/* ===========================================================================
   [Flow 3] THE DONE STEPS ARE SET IN MEDIUM
   ---------------------------------------------------------------------------
   Owner: *"stone / size / engraving text in the bars should be bold after we go
   past them."*

   `font-weight` alone cannot do this here, and both sheets already carried a
   note saying why: main.css registers ONE FoundersGrotesk face (Regular, :44)
   with no `font-weight` descriptor, so every weight resolves to it and anything
   above 400 is a browser-SYNTHESISED fake that double-strikes the glyphs. That
   is why the desktop label was pinned to 400 and the phone's 500 was drawing no
   differently from its neighbours.

   FoundersGrotesk-Medium.otf ships in assets/fonts and is simply never
   declared. sidecart.css:17 already solved exactly this, and its pattern is
   followed rather than a second one invented: a DEDICATED family name, declared
   in the file that uses it, so no existing `font-weight: 500` anywhere else on
   the site silently starts resolving to a different face.

   WARNING, CARRIED FORWARD FROM sidecart.css AND NOT MINE TO CLEAR: that file
   records this as the TRIAL ("Test") cut, to be swapped for the licensed Klim
   .woff2 before production (PR #114). This change puts the same trial cut on a
   second surface. It is the font the repo has; the swap is still owed.
   =========================================================================== */
@font-face {
  font-family: 'FoundersGroteskMedium';
  src: url(../../../assets/fonts/FoundersGrotesk-Medium.otf) format('opentype');
  font-display: swap;
}

/* ---------------------------------------------------------------------------
   STEP-BAR ARROW CHIPS -- HIDDEN BY DEFAULT, AT EVERY WIDTH.
   simple-select-quiz.php now ships a 36x36 prev/next chip on BOTH copies of
   the step bar ([Flow 3] 14514:41123). Only the `.quiz_options` copy at
   <=991px is laid out and re-shown (section 3 below). This rule is
   DELIBERATELY outside the media query that wraps the rest of this sheet:
     * the twin bar inside `.last_slide_info` (the unreached Review slide)
       must never paint them at any width, and
     * no [Flow 3] frame draws this screen at >=992, so desktop keeps exactly
       the bar it had -- "additive only, scoped to max-width:991px" stays true
       for everything the desktop actually renders.
   --------------------------------------------------------------------------- */
#simple-select-quiz .rb_step_arrow { display: none; }

/* =============================================================================
   Ring builder — mobile redesign — STONE screen (step 1.1)

   Figma file Ex10uQ9OY3OuzSPi4g2hPb, section 14463:32244:
     14463:33484  1.1 Stone - Default        390 x 1050   <- the baseline
     14463:33717  1.1 Stone - more details   390 x 1277   (accordion expanded)
     14463:33855  1.1 Stone - See true size  390 x 1015   (hand overlay open)
     14463:34250  1.1 Gemstone selected      390 x  842   (4th row selected)

   Loaded after simple-select.css and after simple-select-redesign.css (which
   defines the --rb-* tokens). Additive only, scoped to max-width:991px, so
   desktop is untouched by construction.

   COORDINATE NOTE. Every y in SPEC.md is measured inside a 390x1050 frame whose
   first 46 px are the iPhone status-bar MOCKUP (`phone-ui`, SF Pro, black bar).
   That is the phone chrome, not our UI, and TOKENS.md excludes it. So every
   SPEC y quoted below has 46 subtracted from it; SPEC's own numbers are given in
   parentheses so they can be checked against the file.

   GUTTER NOTE. The sticky CTA (14463:33709) is 346 wide at x=22 -> a symmetric
   22 px gutter in a 390 frame. The scrolling content column (14463:33485) is
   authored 345 wide at x=22, i.e. a 23 px right gutter -- a 1 px inconsistency
   in the Figma file itself. This sheet uses the symmetric 22 px gutter (346)
   throughout, which is what the brief's target numbers state.
   ============================================================================= */

@media (max-width: 991px) {

  /* ===========================================================================
     0.  SHELL + STACKING ORDER
     ---------------------------------------------------------------------------
     The Figma order is  header / Ring Details / STONE-SIZE-ENGRAVING tabs /
     hero card / carat / handpicked / sticky CTA.  In the DOM the tab strip lives
     inside `.quiz_options` (right Bootstrap column) while the Ring Details bar
     and the hero live in `.quiz-left`, so on a stacked mobile layout the tabs
     land AFTER the hero.  Rather than move a node, the two Bootstrap columns and
     their two layout wrappers are flattened with `display:contents` so every
     real content block becomes a flex item of `.row`, and the sequence is then
     set with `order` alone (brief rule 3).  Nothing is removed from the DOM and
     no element that JS shows/hides is flattened: simple-select.js never calls
     show()/hide() on `.quiz-left`, `.quiz_options` or `.quiz-image-conatiner`
     (it does on `.quiz-image`, `.last_slide_info`, `.desktop-message` and the
     slides -- all of which stay ordinary boxes here).
     =========================================================================== */

  body.ssq-active { background: var(--rb-surface-page); }

  #simple-select-quiz {
    background: var(--rb-surface-page);
    margin-top: 0;
    /* clears the 129-tall fixed CTA block (14463:33707) */
    padding-bottom: 129px;
    position: relative;
  }

  /* Bootstrap gutters off; the 22 px gutter is applied once, per block. */
  #simple-select-quiz > .container,
  #simple-select-quiz .simple-select-heading .container { padding: 0; max-width: none; width: 100%; }
  #simple-select-quiz .simple-select-heading .row { margin: 0; }
  #simple-select-quiz .simple-select-heading .col { padding: 0; }

  #simple-select-quiz > .container > .row {
    display: flex;
    flex-direction: column;
    margin: 0;
  }
  #simple-select-quiz > .container > .row > .quiz-left,
  #simple-select-quiz > .container > .row > .col-12.col-lg-6,
  #simple-select-quiz .quiz_options,
  #simple-select-quiz .quiz-image-conatiner { display: contents; }

  #simple-select-quiz .rb_details_bar        { order: 1; }
  #simple-select-quiz .quiz_options > .rb-progress-bar { order: 2; }
  #simple-select-quiz .quiz-image            { order: 3; }
  #simple-select-quiz .quiz_options > .simple-select-slide,
  #simple-select-quiz .quiz_options > .desktop-message { order: 4; }
  /* Panels JS reveals later in the flow; kept after the slide content. */
  #simple-select-quiz .last_slide_info       { order: 5; }
  #simple-select-quiz .quiz-handpicked-image { order: 6; }
  #simple-select-quiz .ssq-confirmation-info { order: 7; }

  /* ===========================================================================
     1.  HEADER  — 14463:33729 (y 0-80, SPEC 46-126)
     390x80, pad 12/22/6/22, gap 10, SPACE_BETWEEN, counter=CENTER,
     fill #E4DED8 @ 0.60 over the #FAF3ED page ground.
     =========================================================================== */

  /* padTop is 16, not the 12 this was built with. 14463:33730 is an 80-tall band
     that holds ONLY the titles and pads 12; the band the build actually composes
     is 14468:36377's `Frame 1171276558`, [0,46 390x128] with padTop 18, holding
     the titles AND the STONE/SIZE/ENGRAVING strip -- and this rule owns the top
     80 of that 128 while `.rb-progress-bar` owns the bottom 48 (section A below).
     The title stack is centred twice on its way down (the `.col` centres the
     38-tall `.rb_head_titles` in the padded box, which then centres its own
     54-tall overflowing stack), so the stack top resolves to 10 + padTop/2:
     12 gave 16, and the board's 18 needs 16. MEASURED at 390 on 2.4: h2 was
     [97.6,16] against I14468:36377;14468:44609 [97.5,18], and the subtitle 40
     against 42 -- the same 2px, since the -6 gap carries it. Band height and the
     6px bottom pad are unchanged, so 0..80 + 80..128 still sums to the board. */
  #simple-select-quiz .simple-select-heading {
    height: 80px;
    /* THE CHIPS FOLLOW THE CARD, NOT A FLAT 22.
       Owner: *"the back button in the navigation progress bar does not align
       left with the Ring Details left"*, from the lab-diamond-search entry.

       Everything in the body below this band -- the Ring Details bar and the
       ring photo -- is `min(346px, 100% - 44px)` with auto margins, i.e. a 346
       card that CENTRES once the screen is wider than 390 (see the note on
       `.rb_details_bar`; that formula is itself the fix for those two drifting
       apart). This band kept a flat 22, which is the same number only at 390 --
       the artboard. MEASURED, back chip x vs Ring Details x:
         360 -> 22 / 22     390 -> 22 / 22     402 -> 22 / 28
         414 -> 22 / 34     430 -> 22 / 42
       so every phone wider than the artboard showed the chip hanging left of
       the bar, by 6px on the owner's own 402-wide screen. It measured aligned
       every time I checked it at 390, which is why four passes found nothing.

       Stated with the card's own formula rather than a third set of numbers, so
       the band, the bar and the photo cannot drift again. `max()` keeps the 22
       floor below 390, where the card is the one that gives way. */
    padding: 16px max(22px, calc((100% - 346px) / 2)) 6px;
    margin-bottom: 0;
    box-sizing: border-box;
    /* #EDE6E0, STATED OPAQUE. Owner: *"background colour change to #EDE6E0
       (this is originally meant to be pearl-dark at 60% on an opaque pearl-light
       bg). That way [the] background for 'X' pearl dark will be visible."*
       It was authored as the translucent form -- #E4DED8 at 60% -- which is
       that colour only while whatever sits behind it is pearl light, and it
       means anything ON the band that is also pearl-dark blends into it. Flat
       #EDE6E0 is the resolved value, so the close plate takes pearl-dark and
       actually reads. */
    background: #EDE6E0;
  }
  #simple-select-quiz .simple-select-heading .container,
  #simple-select-quiz .simple-select-heading .row,
  #simple-select-quiz .simple-select-heading .col {
    height: 100%;
  }
  #simple-select-quiz .simple-select-heading .col {
    align-items: center;
    gap: 10px;
  }

  /* Back 14463:33730 and close 14463:33736: both 24x24, r4, fill #FAF3ED,
     glyph stroke #3E3C39 w=1.  The exported header icons already carry the
     rounded #FAF3ED plate, so they are used whole as a background.
     The inline <svg> inside each button is the theme's generic right-arrow /
     close glyph -- purely decorative markup (grep: no JS reads either svg; the
     click handlers are bound to `.rb_back` / `.close_ssq` themselves), so it is
     safe to drop it rather than fight its viewBox. */
  #simple-select-quiz .rb_back,
  #simple-select-quiz .close_ssq {
    flex: 0 0 24px;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    background-color: transparent;
    background-repeat: no-repeat;
    background-position: center;
    background-size: 24px 24px;
    border-radius: var(--rb-radius-sm);
    cursor: pointer;
  }
  /* CLOSE IS 28, BACK IS 24. SPEC 8 / 14514:41123: the left slot is a 24x24
     r4 plate drawn at opacity 0.00 (a reserved back button) but the close is
     28x28 r4 #FAF3ED at @340 -- i.e. flush to the same 22px right gutter the
     rest of the quiz uses. At 24 it measured [344,18], 4px small and 4px in. */
  #simple-select-quiz .close_ssq {
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    background-size: 28px 28px;
  }
  #simple-select-quiz .rb_back {
    background-image: url('../../../assets/media/ringbuilder/icon-header-back-chevron.svg');
  }
  /* ---- THE CROSS IS THE ADVANCED SEARCH'S, DRAWN NOT DRAWN-ON -----------
     Same glyph as `#ssq_diamond_search .dsq_close_glyph`: a square box with two
     bars through its centre at +/-45 degrees, each `size x sqrt(2)` long (the
     box diagonal) and 1px thick with round caps. Copied as GEOMETRY rather than
     as an asset, so the two crosses cannot drift apart the way an exported SVG
     and a CSS drawing already had.

     This replaces two different implementations of the same mark -- a
     background-image PNG-style asset at <=991 and an inline <svg> at >=992 --
     with one, applied at every width. */
  /* THE CLOSE IS A PLATE WITH A CROSS ON IT, not a bare cross. Owner: *"the
     cross on phone display is also weird, it's just a plain cross, unlike the
     one on desktop -- exact reconstruction."*

     14557:46136 `Frame 1171276578`: 28 x 28, cornerRadius 4, fill #FAF3ED, with
     a 6 x 6 `Vector` stroked #3E3C39 at weight 1 centred in it (11 + 6 + 11 =
     28). The shared `.rb_back, .close_ssq` rule above sets
     `background-color: transparent`, and switching the glyph from an exported
     asset to a CSS drawing removed the only thing that was painting the plate
     -- so the mark was left floating on the band while desktop kept its 36x36
     #E4DED8 chip. The size and radius were already right; only the fill was
     missing. */
  #simple-select-quiz .close_ssq {
    position: relative;
    background-image: none;
    /* PEARL DARK, now that the band is #EDE6E0 and no longer hides it. */
    background-color: var(--rb-border-subtle);   /* #E4DED8 */
  }
  #simple-select-quiz .close_ssq::before,
  #simple-select-quiz .close_ssq::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    /* 6 x sqrt(2). 14557:46136 draws this glyph at 6 x 6 inside the 28px plate;
       the 8px figure came from the advanced search's own close, which is a
       different control on a different frame. At 11.31 the bars reached within
       2px of the plate's rounded corners and read as an oversized X. */
    width: 8.4853px;
    height: 1px;             /* strokeWeight 1 */
    background: var(--rb-text-secondary);
    border-radius: 0.5px;    /* strokeCap ROUND */
  }
  #simple-select-quiz .close_ssq::before { transform: translate(-50%, -50%) rotate(45deg); }
  #simple-select-quiz .close_ssq::after  { transform: translate(-50%, -50%) rotate(-45deg); }
  #simple-select-quiz .rb_back > svg,
  #simple-select-quiz .close_ssq > svg { display: none; }

  /* Title block 14463:33733 — 195x38, vertical, gap -6, centred. */
  #simple-select-quiz .rb_head_titles {
    height: 38px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    flex: 1 1 auto;
    min-width: 0;
  }
  /* The stack is 30 + 30 - 6 = 54 tall inside a FIXED 38 box, exactly as in
     Figma (14463:33733 is HUG/FIXED and overflows); without this the flex
     items would shrink to fit and the 30px line boxes would collapse. */
  #simple-select-quiz .rb_head_titles > h2,
  #simple-select-quiz .rb_head_titles > .rb_head_setting { flex: 0 0 auto; }
  /* ===========================================================================
     `SMALL_CAPS_FORCED` ON THIS FILE DRAWS PLAIN CAPITALS. MEASURED, SIX TIMES.
     ELEMENTS 1.2 maps `textCase: SMALL_CAPS_FORCED` to
     `font-variant-caps: all-small-caps`. That is the enum's name, not what the
     board renders, and the board's own `absoluteRenderBounds` say so on every
     node that carries it. Small caps only shrink LOWER-case letters, and five of
     the six store their characters already in capitals:

       node                 characters             board rb   caps    small caps
       H.7  13533:33734     'BUILD YOUR RING'       192.04   194.86     137.86
       H.8  13533:33735     'ASHA CLASSIC SOLITAIRE' 128.83   132.39      81.39
       H.15 …44337          'STONE'                  34.86    35.95      23.95
       H.15 …44343          'ENGRAVING'              61.23    62.13      41.13
       C1.16 14514:40415    'Not selected yet'       86.35   116.64      81.64  (none: 87.64)
       C4.6  14514:40466    '14 k White Gold'        81.02   100.86      69.86  (none: 83.86)

     Every board figure lands within 1.5-3.5% of the UNTRANSFORMED string in the
     shipped webfont -- the same systematic offset Figma's metrics carry against
     it everywhere else in this build -- and 5-33% away from the small-caps form.
     The two mixed-case strings prove it in the other direction: they match
     `none`, not `all-small-caps`.
     Confirmed by eye as well, on the 2x render of 14514:41123: BUILD YOUR RING,
     ASHA CLASSIC SOLITAIRE, STONE, SIZE and ENGRAVING are drawn with every
     letter the same height. There is not one small capital in the band.

     So: where the stored string is capitals, build `text-transform: uppercase`
     (the DOM strings here are mixed case); where it is mixed, build neither.
     =========================================================================== */
  /* H.7 / 14463:33734 "BUILD YOUR RING" — Canela 300 24/30, ls -0.21,
     `textCase: SMALL_CAPS_FORCED`, stored characters 'BUILD YOUR RING'.
     Capitals: see the block above. MEASURED both ways here -- uppercase 194.86
     against the board's 192.04 inked box, all-small-caps 137.86. */
  #simple-select-quiz .rb_head_titles h2 {
    margin: 0;
    font-family: var(--rb-font-display);
    font-weight: 300;
    font-size: 24px;
    line-height: 30px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: uppercase;
    font-variant-caps: normal;
    color: var(--rb-text-primary);
    white-space: nowrap;
  }
  /* H.8 / 14463:33735 "ASHA CLASSIC SOLITAIRE" — Founders 400 12/30, ls -0.21,
     SMALL_CAPS_FORCED, stored characters 'ASHA CLASSIC SOLITAIRE', #3E3C39.
     Capitals, same reasoning: 132.39 uppercase against the board's 128.83,
     81.39 small caps. Vertical gap in the Figma frame is -6. This slot prints
     `get_the_title()`, which is mixed case, so the transform is doing real work. */
  #simple-select-quiz .rb_head_setting {
    margin: -6px 0 0 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 12px;
    line-height: 30px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: uppercase;
    font-variant-caps: normal;
    color: var(--rb-text-secondary);
    max-width: 195px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* ===========================================================================
     2.  RING DETAILS BAR  — 14463:33556 (y 88-128, SPEC 134-174)
     346x40, fill #E4DED8 @ 0.60, r4, pad 10/9, inner row SPACE_BETWEEN.
     Renders COLLAPSED: the expanded rows (Setting / Stone / free-engravings
     line) are `visible:false` in the component and have no DOM node at all.
     =========================================================================== */

  #simple-select-quiz .rb_details_bar {
    /* THE SAME BOX THE RING PHOTO USES, SO THE TWO SHARE THEIR EDGES.
       Owner: *"the ring details bar and image are not getting aligned on some
       devices."*

       `.quiz-image` is `min(346px, 100% - 44px)` with auto margins -- a 346
       card that centres once the screen is wider than 390. This bar was a flat
       `margin: 0 22px`, which is the SAME thing at 390 and only at 390: it then
       keeps its 22 and stretches while the photo stays 346 and centres.
       MEASURED, bar left vs photo left: 360 -> 22 / 22, 390 -> 22 / 22,
       414 -> 22 / 34, 430 -> 22 / 42, 768 -> 22 / 211. Every phone wider than
       390 -- which is most of them now -- showed the bar overhanging the photo
       on both sides.

       Stated with the photo's own formula rather than a second set of numbers,
       so the two cannot drift again. */
    width: min(346px, calc(100% - 44px));
    margin: 8px auto 0;        /* gap 8 below the header (Frame 14463:33553) */
    /* Same growth as the stone cards, same reason as the desktop twin: the bar
       had no collapsed height at all here, so it simply appeared. Clamped to the
       toggle's own 40 and grown from there. */
    height: 40px;
    overflow: hidden;
    interpolate-size: allow-keywords;
    transition: height 260ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  #simple-select-quiz .rb_details_bar.is-open {
    height: auto;
    /* HIDDEN, NOT VISIBLE, AND THIS IS THE WHOLE OF THE "text before the
       background" REPORT. `.is-open` used to lift the clip immediately, so from
       the FIRST frame of a 260ms height animation the panel's full-height
       content was painted outside a bar that had barely started growing.
       INSTRUMENTED, sampling every 35ms through an open:

           before  bar 48    overflow hidden    panel bottom 91px BEYOND the bar
           t35     bar 49    overflow VISIBLE   panel bottom 90px beyond
           t70     bar 74.3                     64.8 beyond
           t105    bar 121                      18 beyond
           t140    bar 142.1                    inside at last

       i.e. for well over half the animation the rows floated on the page and
       the background chased them. With the clip kept, the same height animation
       REVEALS the panel instead, which is what it was always meant to do.

       Safe to keep clipped at rest: the open bar is `height: auto`, so it is
       already exactly as tall as its content and clips nothing. */
    overflow: hidden;
  }

  /* ---- THE COLLAPSE HAS TO HAVE SOMETHING TO ANIMATE THROUGH -------------
     The bar grew smoothly but snapped shut. Captured frame by frame:
       t=  0ms  barH=179  panelH=119  open=true
       t= 20ms  barH= 51  panelH=  0            <- panel gone in ONE frame
       t=219ms  barH= 48                        <- transition animated 3px
     The panel ships with the `hidden` attribute and
     simple-select-redesign.js:1999 keeps it in step with `.is-open`, so the UA
     sheet's `[hidden]{display:none}` pulled it out of flow in the same frame the
     class changed. The bar's height then had nothing left to shrink THROUGH --
     it was already at its collapsed content height, and the 260ms ran over the
     3px of padding that remained.

     Kept in flow instead, and clipped by the bar's own `overflow: hidden` --
     which is what the collapsed height is for. `hidden` stays on the node, so
     the attribute still records the state for anything reading it; only its
     `display` is overridden, and `visibility` takes over the actual hiding on a
     delay so the panel is still painted for the length of the collapse. */
  /* `!important` because it is answering one: bootstrap.min.css ships
     `[hidden]{display:none!important}`, which no amount of specificity beats.
     Worth recording -- the note on `.rb_adv_search_row` elsewhere in this build
     says `hidden` is "only enforced by the UA sheet's [hidden]{display:none},
     which ANY author rule outranks". That is not true in this theme. */
  #simple-select-quiz .rb_details_panel[hidden] { display: block !important; }
  #simple-select-quiz .rb_details_bar:not(.is-open) .rb_details_panel {
    visibility: hidden;
    transition: visibility 0s linear 260ms;
  }
  #simple-select-quiz .rb_details_bar.is-open .rb_details_panel {
    visibility: visible;
    transition: visibility 0s;
  }

  #simple-select-quiz .rb_details_toggle {
    display: flex;
    align-items: center;
    width: 100%;
    height: 40px;
    padding: 10px 9px;
    border: 0;
    box-sizing: border-box;
    border-radius: var(--rb-radius-sm);
    background: rgba(228, 222, 216, 0.60);
    text-align: left;
    cursor: pointer;
  }
  /* THE SEAM. Owner: *"I can see the rounded edges and sharp edges from the
     detail part interacting."*

     On a phone the ground is painted TWICE -- once by the toggle, once by the
     panel below it (see the note on `.rb_details_panel`) -- so the two boxes
     meet mid-bar. The toggle carried r4 on all four corners and the panel r4 on
     its bottom two only, which put a rounded edge directly above a square one
     and printed a notch of page ground at each end of the join. Open, the
     toggle is the TOP half of one box, so only its top corners are round.

     Held through the collapse as well (`.rb-details-animating`, set by
     simple-select-redesign.js for the length of the height transition): snapping
     the radius back at the first frame of the close would flash the same notch
     over the panel that is still on its way out.

     The desktop twin does not need this -- there the bar itself paints the
     ground and the radius, and the toggle has neither. */
  #simple-select-quiz .rb_details_bar.is-open .rb_details_toggle,
  #simple-select-quiz .rb_details_bar.rb-details-animating .rb_details_toggle {
    border-radius: var(--rb-radius-sm) var(--rb-radius-sm) 0 0;
  }
  /* Chevron 14463:36330 is 10x5, stroke #3E3C39 w=1, and sits BEFORE the label
     in Figma; in the DOM it is the last child, so it is reordered. */
  #simple-select-quiz .rb_details_chev {
    order: -1;
    flex: 0 0 10px;
    width: 10px;
    height: 5px;
    margin-right: 6px;         /* Figma gap 6 */
    background: url('../../../assets/media/ringbuilder/icon-chevron-down-10.svg') no-repeat center / 10px 5px;
    transition: transform 260ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  /* 14514:40363: "chevron-down ... points DOWN when collapsed" / "chevron now
     points UP" on the expanded variant. The transition above was already here
     with nothing to animate -- the mobile sheet never wrote the open state, so
     the arrow stayed pointing down over an open panel. Same rule the desktop
     twin has had since Flow 2 (_stone-desktop.css:523). */
  #simple-select-quiz .rb_details_bar.is-open .rb_details_chev {
    transform: rotate(180deg);
  }
  #simple-select-quiz .rb_details_label {
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
  }
  /* 14463:36333 is one TEXT node with a styleOverrideTable: "Current Est."
     is Founders 400 #3E3C39, the price run is Founders 500 #0F0E0D. */
  #simple-select-quiz .rb_details_est {
    margin-left: auto;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
    text-align: right;
  }
  #simple-select-quiz .rb_details_price {
    /* Owner: *"in the Ring Details bar, Current Est. $1,900 -- remove the bold
       from the amount."* It was the one word in that row set heavier than its
       own line: MEASURED 500 against the 400 every other node in the bar
       computes. The COLOUR stays -- the amount is still the darker ink, which
       is what separates it from the `Current Est.` label beside it. */
    font-weight: 400;
    color: var(--rb-text-primary);
  }

  /* ---- 2b. THE EXPANDED BODY — 14514:40382 -------------------------------
     The Flow-2 board only ever drew this bar COLLAPSED ("the expanded rows are
     `visible:false` in the component", note above), so the panel had markup and
     typography and no layout at all. [Flow 3] 14514:40363 is the first board in
     either flow that draws it open, and the stone-first journey is the first one
     that gives it something to say on every step.

     MEASURED at 390 before this: the bar's #E4DED8@60 ground stopped at the
     40px header (it is painted by `.rb_details_toggle`, not by the bar) and the
     three rows spilled onto the page ground below it; each row printed
     "Setting 14k White Gold $980" as one run, with the price butted against the
     descriptor instead of right-aligned; and the strap wrapped to two lines
     against the page. The DESKTOP twin has been correct since Flow 2
     (_stone-desktop.css section 2) -- this is the same treatment at the board's
     mobile sizes, which is why the rules read as a near-copy.

     The ground goes on the PANEL, not on `.rb_details_bar`: the toggle already
     paints its own and the two are the same 60% alpha, so grounding the bar as
     well would composite to 84% behind the header and print a darker strip
     across the top. The panel is clipped by the bar's collapsed
     `height: 40px; overflow: hidden`, so nothing of it shows until `.is-open`. */
  #simple-select-quiz .rb_details_panel {
    padding: 0 9px 10px;                  /* 14514:40363 padding 10/9/10/9 */
    box-sizing: border-box;
    background: rgba(228, 222, 216, 0.60);
    border-radius: 0 0 var(--rb-radius-sm) var(--rb-radius-sm);
  }
  /* Body 348x94 (14514:40363 "Ring details Expand"), the full width of the
     panel's content box, holding the rows and nothing else.

     THERE IS NO THUMBNAIL. The previous round added a 95.2x94 r4 image at the
     head of this row off node 14514:40401 -- which carries `visible: false` in
     the file and is not drawn in the 2x render of the component sheet. Flow 3's
     expanded bar is Stone + Setting, 45 + 4 + 45 = 94, across the whole 348.
     With the image in, the rows were squeezed to 220.8 and the stone descriptor
     wrapped to two lines, taking the body to 120 against the board's 94.
     ELEMENTS.md C1.11 / C2; conflict B7 is void with it. */
  #simple-select-quiz .rb_details_body {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 12px;
  }
  #simple-select-quiz .rb_details_rows {
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
    flex-direction: column;
    /* 12, NOT THE BOARD'S 4. Owner, with the panel marked up: *"add space in
       between these two so the setting and metal look like they belong
       together, and stone and stone type look like they belong together."*

       Each row is a PAIR -- `Setting` over `14k Rose Gold` -- stacked with no
       gap of their own, so the only thing separating one pair from the next was
       4px against the ~6px of half-leading inside a pair. The two readings were
       almost identical, which is why the metal read as belonging to the stone
       below it as much as to the setting above.
       This breaks the 45 + 4 + 45 = 94 body the two-row board pins (14514:40363)
       -- deliberately: the grouping is what was asked for, and the panel is
       sized by its content. */
    gap: 12px;
  }
  #simple-select-quiz .rb_details_row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin: 0;
  }
  #simple-select-quiz .rb_details_row_text {
    display: flex;
    flex-direction: column;
    min-width: 0;
  }
  #simple-select-quiz .rb_details_row_label,
  #simple-select-quiz .rb_details_row_value {
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);
  }
  #simple-select-quiz .rb_details_row_value {
    text-align: right;
    white-space: nowrap;
  }
  /* 14514:40363's value line is 14/30 on the secondary ink, textCase LOWER.
     The case is NOT transformed here: "14k White Gold" and "Lab Created
     Diamond" are the metal and the stone's own product name, and the board's
     own lowercase run is a placeholder string, not a rule about proper nouns --
     the same reading _stone-desktop.css records for `font-variant-caps`. */
  #simple-select-quiz .rb_details_row_desc {
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 26px;                    /* 19 + 26 = the board's 45-tall row */
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
  }
  #simple-select-quiz .rb_details_row_desc:empty { display: none; }
  /* Footer 348x23 — FG 400 12/19, centre, secondary ink. */
  #simple-select-quiz .rb_details_strap {
    margin: 8px 0 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 12px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
    text-align: center;
  }

  /* ===========================================================================
     3.  STEP TABS  — bar 14463:33557 (y 144-184, SPEC 190-230)
     342 wide, three 107.33 columns, gap 10.  Each column: a 2 px rule (r10)
     over a 20-tall label, gap 4, the pair centred in a 30-tall box.
     ACTIVE (STONE)   rule #27423B, label Founders 500 #27423B
     INACTIVE         rule #E4DED8, label Founders 400 #3E3C39
     both 12px, ls -0.21, SMALL_CAPS_FORCED.
     =========================================================================== */

  #simple-select-quiz .quiz_options > .rb-progress-bar {
    height: 40px;
    /* was width: 342px -- the design is authored at 390, so a fixed 342 overflowed every narrower phone. min() keeps 342 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    margin: 16px auto 0 auto;   /* gap 16 below the Ring Details bar */
    box-sizing: border-box;
    /* [Flow 3] 14514:41123 / 40624 -- the bar INSTANCE is 346 wide at x22 and
       holds FIVE children, not three: a 36x36 prev wrapper at x22, three 78x30
       step cells at x68 / x156 / x244, and a 36x36 next wrapper at x332. The
       build reserved no arrow gutters, so the three cells spread to 107.33 each
       and started at the frame's own inset. The row is laid out here rather
       than inside `.progress-items` because simple-select.js addresses the
       labels with BOTH `:nth-child` (1401) and jQuery `.index()` (1396): any
       extra element inside that wrapper shifts both. The arrows are siblings of
       it instead, so every existing index is byte-identical. */
    /* !important: simple-select.js `.show()`s this node and jQuery writes
       `style="display: block"` -- a <div>'s default, not this sheet's flex.
       Same defect as the desktop rule; see the note there. */
    display: flex !important;
    flex-direction: row;
    align-items: flex-start;
    /* NOT `gap`. The bar has five children but TWO of them are the legacy
       `.rb-progress` / `.rb-progress-complete` rails, collapsed to zero width;
       a container gap is still spent on each of them, which put the first cell
       at x78 instead of the board's x68. The 10 lives on the arrow chips
       instead, which are the only two children it should separate. */
    gap: 0;
  }

  /* The 4-dot progress rail is not in any 1.x frame, but noUiSlider-adjacent
     code reads it: simple-select.js:1178-1185 calls
     `.progress-circle.completed ... .position().left` to size
     `.rb-progress-complete`.  So it must keep a box and a position -- collapsed
     with visibility + zero height, NEVER display:none (brief rule 1). */
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb-progress,
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb-progress-complete {
    visibility: hidden;
    height: 0;
    min-height: 0;
    overflow: hidden;
    /* The bar is a flex row now (above). These two keep a box and a position --
       simple-select.js:1528 reads `.position().left` off them -- but must not
       take a share of the 346. */
    flex: 0 0 0;
    width: 0;
    padding: 0;
    margin: 0;
  }

  #simple-select-quiz .quiz_options > .rb-progress-bar > .progress-items {
    /* THE CELL ROW HAS TO GIVE WAY BELOW 390. The three step cells are the
       board's rigid 78px and the two chips 36 each; with the 10px chip margins
       that is 22 + 36 + 10 + 234 + 10 + 36 = 348 of content, which fits the
       board's own 346 bar and nothing narrower. MEASURED with the next chip's
       right edge against the viewport: 368 at 390, 375 AND 360 alike -- the row
       simply kept its 390 geometry, so at 360 the chip sat 8px off-screen.
       That is the owner's *"they even drop out of frame slightly"*.
       `flex: 1 1 auto` + `min-width: 0` lets the cell run absorb the difference;
       a flex item will not shrink past its content's intrinsic width without
       the `min-width`, which is why stating the flex alone is not enough. */
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    gap: 0;                     /* per-item margins instead -- see below */
    margin-top: 0;
    font-size: inherit;
    /* 78 + 10 + 78 + 10 + 78 = 254, which is board x68 -> x322. The zero-width
       4th cell (Review) adds nothing, which is why the gap stays on the
       per-item margins below rather than on `gap`. */
    /* 254 IS THE BOARD'S WIDTH, NOT A FLOOR. 78 x 3 + 10 x 2 = 254 is what
       14514:41123 draws at 390, and pinning it with `flex: 0 0` meant the whole
       rail kept its 390 geometry on every narrower phone: MEASURED, the next
       chip's right edge sat at 368 at 390, 375 AND 360 alike, i.e. 8px off a
       360 screen. Owner: *"the navigation left and right ... even drop out of
       frame slightly."*
       `0 1 254px` keeps 254 as the BASIS -- so nothing moves at the board's own
       width -- and lets the run give way below it. `min-width: 0` is required
       or a flex item refuses to shrink past its content's intrinsic width and
       overflows anyway; the cells carry the same, further down. */
    flex: 0 1 254px;
    width: 254px;
    min-width: 0;
    box-sizing: border-box;
  }
  /* ---- CELL AND LABEL --------------------------------------------------
     14514:41123 / 40624 / 40420 draw each cell as a 78x30 box: a 78x2 r10 rule
     at cell-relative y2 over a 78x20 label at y8, and the label is Founders
     Grotesk 12/30, ls -0.21, textCase SMALL_CAPS_FORCED, with NO underline in
     any state -- the rule above the label is what carries the state.

     THIS OVERRIDES the earlier 21px/uppercase/underline treatment, which came
     from annotation 14463:36451 ("21px throughout; ONYX before a step has been
     visited, JADE after; bold once visited; underline ONLY on the step you are
     currently on"). That annotation is outside the [Flow 3] frames and its
     21px cannot fit "ENGRAVING" in the board's 78px cell at all -- the two
     instructions are not reconcilable at this geometry, and the board wins for
     the flow the board describes. Flagged for the owner. */
  /* ...and each cell with it -- see the note on `.progress-items` above. */
  #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label {
    min-width: 0;
    /* 78 IS A BASIS, NOT A LOCK. Owner: *"there should never be any overlap."*
       When the cell RUN was allowed to shrink below 390 these did not follow --
       MEASURED at 360: the run narrowed to 224 while the three cells stayed 78
       each and still ended at x322, so they spilled past the run's right edge
       (292) and straight under the next arrow chip at 302. That is the clipped
       "ENGRAVIN" with the arrow sitting on top of it.
       `0 1 78px` keeps the board's 78 wherever it fits -- 390 is byte-identical
       -- and lets each cell give way in step with the run below it. */
    flex: 0 1 78px;
    width: 78px;
    box-sizing: border-box;
    height: 30px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: 4px;
    padding-top: 2px;           /* rule sits at cell-relative y2 */
    transform: none;            /* base sheet nudges labels 2/3/4 by 9/5/11px */
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 12px;
    /* Board line-height is 30 inside a FIXED 20-tall box. 20 here is the same
       rendered centre with an honest box height, and keeps 2 + 4 + 20 = 26
       inside the 30-tall cell so the rule has room to exist (see below). */
    line-height: 20px;
    letter-spacing: var(--rb-ls-tight);
    /* H.15. Stored characters are 'STONE', ' SIZE', 'ENGRAVING' -- capitals --
       so SMALL_CAPS_FORCED draws them as capitals. This shipped
       `all-small-caps`, which on the DOM's mixed-case "Stone"/"Size"/
       "Engraving" renders 23.95 / 41.13 against the board's 34.86 / 61.23
       inked boxes: a third narrow on every label in the bar. */
    text-transform: uppercase;
    font-variant-caps: normal;
    text-align: center;
    color: var(--rb-text-secondary);     /* pending #3E3C39 */
    text-decoration: none;
    cursor: default;
  }
  /* THE RULE HAD A USED HEIGHT OF 0. The cell was 30 tall, column flex, gap 4,
     line-height 26 -- 26 + 4 + 2 = 32 > 30, so the only shrinkable item, the
     2px rule, flexed away to nothing and the board's bar was never painted.
     `flex: 0 0 2px` makes it unshrinkable; the 20px line-height above also
     puts the content back inside the box. */
  #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label::before {
    content: "";
    display: block;
    flex: 0 0 2px;
    height: 2px;
    min-height: 2px;
    border-radius: var(--rb-radius-lg);
    /* THE SEGMENT FILLS, IT DOES NOT JUST CHANGE COLOUR.
       Owner, after many rounds on the wrong element: *"it's too fast... and I'm
       kinda thinking the animation of fill is not even happening."* Correct, and
       on this screen it never was.

       What is drawn here is a 2px rule per step, and "progress" was the whole
       rule swapping from #E4DED8 to green in one go. There is no width to
       travel, so nothing could animate no matter what duration was set -- and
       every duration I tuned was on `.rb-progress-complete`, which MEASURED 0px
       wide with no inline width ever written on this screen. It is a different,
       unused component.

       The fill is now a background-size animation: the pearl track stays as the
       background COLOUR and the green arrives as a background IMAGE sized from
       0% to 100% of the rule's width. background-size is animatable, so the
       green genuinely sweeps left to right across each segment.

       Timing is measured off the owner's own screen capture (see
       simple-select.css): ~470ms forward, ~200ms back, accelerating from rest
       and decelerating into the stop. */
    background-color: var(--rb-border-subtle);
    background-image: linear-gradient(var(--rb-brand-green), var(--rb-brand-green));
    background-repeat: no-repeat;
    background-position: left center;
    background-size: 0% 100%;
    transition: background-size .45s ease-in-out;
  }
  @media (prefers-reduced-motion: reduce) {
    #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label::before {
      transition: none;
    }
  }
  #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label.completed {
    /* the real Medium face, not a synthesised 500 -- see the @font-face note at
       the top of this file. */
    font-family: 'FoundersGroteskMedium', 'FoundersGrotesk', sans-serif;
    font-weight: 400;   /* the step label is Regular like everything else */                    /* board: done/current is FG Medium */
    color: var(--rb-brand-green);
    text-decoration: none;
  }
  /* ---- STEP STATES -- three, not two ------------------------------------
     Asked for: 21px throughout; ONYX before a step has been visited, JADE
     after; bold once visited; underline ONLY on the step you are currently on.

     `.completed` cannot express that on its own. simple-select.js:1146 stamps
     it on every label from the first up to and INCLUDING the current one, so it
     means "visited or current", and the CURRENT step is simply the last one
     carrying it. That is what the `:has(+ ...)` pair below reads: the completed
     label whose next sibling is not completed -- plus `:last-of-type` for the
     case where every step is done. No JS needed, and nothing to keep in sync
     with the step machinery. */
  /* NO UNDERLINE in any state on 14514:41123 / 40624 / 40420 -- the 78x2 rule
     above the label is the whole state affordance. The `:has()` pair that used
     to draw one is kept only as the hook for "this is the CURRENT step", which
     is what decides whether the cell is tappable (below) and which arrow chip
     is live. */
  #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label.completed:not(:has(+ .progress_label.completed)) {
    text-decoration: none;
  }
  /* A VISITED step that is not the current one is a real back-link. Only those
     get the pointer: simple-select-redesign.js refuses forward moves, so
     advertising a tap on a pending cell is what made the bar look inert. */
  #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label.completed:has(+ .progress_label.completed) {
    cursor: pointer;
  }

  /* Completed = the green has swept the full width of this segment. The shorthand
     `background` is NOT used here: it would reset background-image and
     background-size and take the travel away again. */
  #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label.completed::before {
    background-size: 100% 100%;
  }
  /* Only two gaps, so 342 - 20 = 322 / 3 = 107.33 per column. */
  #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label:nth-of-type(1),
  #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label:nth-of-type(2) {
    margin-right: 10px;
  }
  /* ---- PREV / NEXT ARROW CHIPS ----------------------------------------
     14514:41123 bar children 1 and 5: a 36x36 wrapper holding a 28x28 r4
     #E4DED8 box with an 8-wide, 1px #3E3C39 chevron. On the STONE step the
     prev box is drawn at opacity 0.00 (there is nothing before it) and on the
     ENGRAVING step there is nothing after it, so the next chip goes the same
     way -- `.sss-next` there is ADD TO BAG, and an arrow that adds to the bag
     is not what the board draws. `visibility` rather than `display` so the
     36px gutter survives and the three cells keep landing on x68/156/244. */
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_arrow {
    flex: 0 0 36px;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    /* -30px, ON THE OWNER'S CALL. I measured the arrows as already centred on
       the step labels -- centre 100 against 97 at 390, 134 against 133 at 1416,
       i.e. 3px and 1px out -- and said so. The owner looked at it with the
       offset applied and preferred it, so it goes in: their eye on the rendered
       screen beats my numbers on the box model. It deliberately sits the arrows
       ABOVE the label row's centre line.
       AFTER the shorthand, not before: the first attempt put `margin-top` above
       this block's own `margin: 0`, which reset it, and the boxes did not move
       at any width.

       -17 HERE, NOT THE -30 THE DESKTOP SHEET USES, and this is the one place
       the owner's figure could not be taken literally. At 390 the header band
       is only 80 tall and the close sits inside it: MEASURED with -30, the
       arrow landed at [332,52,36,36] (y 52..88) against `.close_ssq` at
       [340,31,28,28] (y 31..59) -- the two overlap on both axes, i.e. two
       TAPPABLE controls on top of each other, which is a hit-test problem
       rather than a matter of taste. -17 puts the arrow's top at 65, six clear
       of the close, and its centre on 83 -- level with the step cell's own 2px
       rule, which is the relationship the -30 produces at desktop. Same look,
       no collision. */
    margin: -17px 0 0;
    border: 0;
    background: none;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }
  /* AFTER the `margin: 0` above, not before it: the two selectors weigh the
     same (one id + three classes) and the tie is broken on order. Written
     first, these lost and the cells landed at x58 instead of the board's x68. */
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_prev { margin-right: 10px; }
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_next { margin-left: 10px; }
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_arrow > span {
    display: block;
    width: 28px;
    height: 28px;
    border-radius: var(--rb-radius-sm);
    /* 9 x 6, not 8 x 12: 14557:46136's `Vector 437` is 8 x 0 -- a FLAT bbox,
       i.e. the shaft's extent on a stroked ARROW, exactly as the desktop board
       reports 12 x 0. Built literally it became a chevron, which is what reads
       as "weird" beside the desktop pair. With a 1px centred stroke and round
       caps the 8px arrow draws 9 x 6. */
    background: var(--rb-border-subtle) no-repeat center / 9px 6px;
  }
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_prev > span {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='6' viewBox='0 0 9 6' fill='none'%3E%3Cpath d='M8.5 3H0.5M0.5 3L2.83 0.67M0.5 3L2.83 5.33' stroke='%233E3C39' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_next > span {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='6' viewBox='0 0 9 6' fill='none'%3E%3Cpath d='M0.5 3H8.5M8.5 3L6.17 0.67M8.5 3L6.17 5.33' stroke='%233E3C39' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
  /* First step -> no prev; last step -> no next. */
  #simple-select-quiz:has(#ssq_select_stone.active) .quiz_options > .rb-progress-bar > .rb_step_prev,
  #simple-select-quiz:has(#ssq_engraving.active) .quiz_options > .rb-progress-bar > .rb_step_next {
    visibility: hidden;
    pointer-events: none;
  }

  /* The DOM carries a 4th step ("Review") that the 1.x frames do not show.
     simple-select.js:1073 maps a step NAME to a step NUMBER via
     `.progress_label:contains(...)`.index(), so the node must stay in the DOM
     and keep its index -- collapsed to zero width, never display:none. */
  #simple-select-quiz .quiz_options > .rb-progress-bar .progress_label:nth-of-type(4) {
    flex: 0 0 0;
    width: 0;
    margin: 0;
    padding: 0;
    overflow: hidden;
    visibility: hidden;
  }

  /* ===========================================================================
     4.  HERO CARD  — setting section 14463:33486 (y 185-335, SPEC 231-381)
     346x150 #FFFFFF r4, horizontal, gap 8, counter=CENTER:
       image 14463:33487   180x150 r4, IMAGE scale=FILL
       Settings 14463:33488 144x92, vertical gap 20 -> two 144x36 pills r34
     DOM order is pills-then-image, so the image is pulled to order 1.
     =========================================================================== */

  #simple-select-quiz .quiz-image {
        /* simple-select.js writes display:flex inline on .quiz-image in 17 places, and
       .show() writes display:block. Pin it so a return trip cannot change the box type. */
    display: flex !important;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    height: 150px;
    margin: 1px auto 0 auto;   /* SPEC: tabs end 184, content starts 185 */
    padding: 0;
    box-sizing: border-box;
    background: var(--rb-surface-card);
    border-radius: var(--rb-radius-sm);
    overflow: hidden;
    /* 13px is the slack 14557:43973 leaves between the pill column and the
       `setting section`'s right edge (image 180 + gap 8 + Settings 144 = 332
       inside 345). Reserved here so it survives at every width instead of only
       at the board's own 390; border-box keeps the card itself 100vw - 44. */
    box-sizing: border-box;
    /* 8, DOWN FROM 13. Owner: *"in the image preview, there's space left beyond
       the shape and metal buttons['] right -- reduce space by 40%."* The 13 is
       the board's own slack (image 180 + gap 8 + Settings 144 = 332 inside 345)
       and was added here so the pills stopped sitting flat against the card
       edge at widths below 390; 40% off it is 7.8, taken as 8. Still a real
       gap at every width -- MEASURED 13px at 390 / 375 / 360 before, so this
       holds ~8 across the same range. */
    padding-right: 8px;
  }
  #simple-select-quiz .quiz-image > .sss-metal-image {
    order: 1;
    /* SHRINKABLE, not rigid. Owner: *"the shape and metal button touches the
       edge of the image ... give it some padding on the right so that it does
       not touch the edge, adjust image size accordingly."*

       The pill column was already `flex: 0 1 144px` -- it could give way -- but
       the photo beside it was `0 0 180px` and could not, so every pixel the row
       was short came out of the pills alone. With the card at 100vw - 44:
         390 -> card 346, 180 + 8 + 144 = 332, 14px of slack   (the board's 13)
         375 -> card 331, the pills shrink to 143, slack 0
         360 -> card 316, the pills shrink to 128, slack 0
       i.e. from 375 down the pills are pressed flat against the card's right
       edge, which is the report. `min-width: 0` is required for a flex item to
       go below its content's intrinsic width at all.

       Now both sides give way together, and the 13px the board leaves on the
       right is reserved by the card rather than being whatever happens to be
       left over -- see the `padding-right` on `.quiz-image` below. */
    flex: 0 1 180px;
    min-width: 0;
    width: 180px;
    height: 150px;
    margin: 0;
    border-radius: var(--rb-radius-sm);
    overflow: hidden;
  }
  #simple-select-quiz .quiz-image > .sss-metal-image .sss-image-crop { height: 150px; }
  #simple-select-quiz .quiz-image > .sss-metal-image img {
    width: 180px;
    height: 150px;
    /* `contain`, not the `cover` that Figma's scaleMode implies. The mock's
       placeholder is authored to exactly fill this box, so FILL/STRETCH looks
       right there; the real product photographs have a different aspect ratio,
       and `cover` visibly cut the ring off. Showing the whole ring beats
       matching a scaleMode that was only ever true of the mock asset. */
    object-fit: contain;
  }
  /* `.desktop-stone-details` is a desktop-only panel that the base sheet already
     leaves display:none here; JS shows it only on >=992px. Left alone. */

  #simple-select-quiz .quiz-image > .select_metal_shape {
    order: 2;
    /* 144 is the design's column width against its 390 artboard, where the 180px hero
       image plus this column fit the 346 card exactly. On a 320 viewport the card is
       276 and a rigid 144 pushed the pills off the right edge. Cap at 144 and allow
       shrink; min-width:0 is required or the flex item refuses to go below its
       content's intrinsic width and overflows anyway. */
    /* 156, NOT THE BOARD'S 144, AND THE 12 COMES OFF THE PHOTO.
       Owner: *"in the side-by-side of stone plus ring, the metal button cuts off
       the text when the metal is changed -- like 18k Rose Gold."*

       The chevron's double-reserved 22px (see the rule at the end of this file)
       was only half of it. MEASURED with that removed, the longest label still
       does not fit: `14k Yellow Gold` lays out at 130 inside a 119 content box.
       144 is the board's column against its own 390 artboard, where the label it
       was drawn with is shorter than the longest one the catalogue sells -- and
       with 18k now in the metal filter there are three more names at that
       length.

       The column takes the 18 it needs and the hero gives it up: the photo is
       `flex: 0 1 180px`, so it gives the difference up and nothing else on the card
       moves. A slightly narrower ring beats a permanently ellipsised metal name.
       Recorded as a deliberate departure from 14463's 180/144 split. */
    flex: 0 1 162px;
    width: 162px;
    max-width: 162px;
    min-width: 0;
    height: 92px;
    display: flex;
    flex-direction: column;
    gap: 20px;
    margin: 0;
    font-size: 14px;
  }
  /* Pills 14463:33489 / 14463:33495 — 144x36, r34, fill #E4DED8 @ 0.40.
     Figma puts the metal pill first, the shape pill second; the DOM is the
     other way round. */
  #simple-select-quiz .quiz-image .metal_dropdown_ssq { order: 1; }
  #simple-select-quiz .quiz-image .shape_dropdown_ssq { order: 2; }
  #simple-select-quiz .quiz-image .shape_dropdown_ssq,
  #simple-select-quiz .quiz-image .metal_dropdown_ssq {
    position: relative;
    display: flex;
    align-items: center;
    /* 144 is the Figma width; below ~360px the card is narrower than the design's card
       and a rigid 144 pushed the pill past the edge. Fill the (already capped) column
       instead, so the pill is 144 wherever there is room and shrinks with its parent. */
    width: 100%;
    max-width: 162px;   /* follows the column above */
    min-width: 0;
    height: 36px;
    /* left pad 8 (218-210); right pad 13 (354-341) */
    padding: 0 13px 0 8px;
    margin: 0;
    box-sizing: border-box;
    border-radius: 34px;
    background: rgba(228, 222, 216, 0.40);
  }
  /* The "Shape" / "Metal" word is theme markup, not in the Figma pill (the pill
     shows the CURRENT value only). Collapsed rather than removed: it is static
     copy, but zero-width + visibility keeps the node measurable. */
  #simple-select-quiz .quiz-image .shape_dropdown_ssq > span,
  #simple-select-quiz .quiz-image .metal_dropdown_ssq > span {
    width: 0;
    overflow: hidden;
    visibility: hidden;
    font-size: 0;
  }
  #simple-select-quiz .quiz-image .shape_current_option,
  #simple-select-quiz .quiz-image .metal_current_option {
    display: flex;
    align-items: center;
    gap: 6px;                 /* Figma gap 6 between the 20px icon and the label */
    width: auto;
    margin: 0;
    background: none;
    border: 0;
    border-radius: 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 16px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: uppercase;   /* SMALL_CAPS_FORCED on 33493 / 33500 */
    color: var(--rb-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* "Round icon" 14463:33492 / 33498 — 20x20. */
  #simple-select-quiz .quiz-image .shape_current_option svg,
  #simple-select-quiz .quiz-image .metal_current_option svg,
  #simple-select-quiz .quiz-image .shape_current_option img,
  #simple-select-quiz .quiz-image .metal_current_option img {
    width: 20px;
    height: 20px;
    flex: 0 0 20px;
  }
  /* Chevron 14463:33494 / 33501 — 4x8, stroke #0F0E0D w=1, pinned to the right
     edge.  SPEC actually keeps an 11 px gap after the metal label and
     SPACE_BETWEEN on the shape pill; pinning both is the stable rendering for
     variable-length metal names. */
  #simple-select-quiz .quiz-image .shape_dropdown_ssq::after,
  #simple-select-quiz .quiz-image .metal_dropdown_ssq::after {
    content: "";
    margin-left: auto;
    flex: 0 0 4px;
    width: 4px;
    height: 8px;
    background: url('../../../assets/media/ringbuilder/icon-chevron-right-8.svg') no-repeat center / 4px 8px;
  }
  /* The theme also injects a `span.dropdown_icon` into each current-option;
     it duplicates the chevron above. Collapsed, not removed. */
  #simple-select-quiz .quiz-image .select_metal_shape span.dropdown_icon {
    visibility: hidden;
    width: 0;
    height: 0;
    overflow: hidden;
  }
  /* Drop-downs stay absolutely positioned; JS toggles their display. */
  #simple-select-quiz .quiz-image .shape_dropdown_ssq_options,
  #simple-select-quiz .quiz-image .metal_dropdown_ssq_options {
    top: 40px;
    left: 0;
    /* matches the pill above it, and shrinks with it on narrow phones */
    width: 100%;
    max-width: 144px;
    border-radius: var(--rb-radius-sm);
    border-color: var(--rb-border-subtle);
  }

  /* ===========================================================================
     5.  CARAT WEIGHT  — 14463:33502 (y 356-486, SPEC 402-532)
     346x130, fill #FAF3ED @ 0.70, r4, vertical gap 16:
       row A  14x  "CARAT WEIGHT" (Canela 300 18/19) | "See true size on hand"
       row B  100x tiles 70 + gap 4 + "Most Picked" 26
     =========================================================================== */

  #simple-select-quiz .simple-quiz-carat-filter {
        /* Same reason as the stone list above: simple-select.js .show()/.hide()s this block
       (js:660, :1612, :1651, :1917, :1976), and jQuery's .show() writes an inline
       display:block that would flatten this layout on the way back. */
    display: grid !important;
    grid-template-columns: auto auto;
    /* Row A is 14 tall (14463:33503) even though the "See true size" text is 16
       and overhangs it by 2 (SPEC y=400 in a row at 402) -- hence the explicit
       track and align-items:end.  Rows 3/4 are the collapsed slider + read-out,
       pinned to 0 so the block measures 14 + 16 + 100 = 130. */
    grid-template-rows: 14px auto 0 0;
    align-items: end;                 /* Figma counter=MAX on row A */
    row-gap: 0;
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    /* SPEC 130 tall; the slider + read-out rows below are collapsed to 0 so the
       block measures 14 + 16 + 100 = 130. */
    margin: 21px auto 0 auto;         /* Figma vertical gap 21 */
    padding: 0;
    box-sizing: border-box;
    background: rgba(250, 243, 237, 0.70);
    border-radius: var(--rb-radius-sm);
  }

  /* Row A left — "CARAT WEIGHT" 14463:33504, Canela 300 18/19, ls -0.21.
     COPY NOTE: the DOM string is "Change Carat Weight:", SPEC's is
     "CARAT WEIGHT". Uppercased here; the wording itself needs a PHP change. */
  #simple-select-quiz .simple-quiz-carat-filter .filter_heading {
    grid-column: 1;
    grid-row: 1;
    height: 14px;
    margin: 0;
  }
  /* The template writes `style="margin-bottom:5px"` on this <p> inline, so the
     14-tall row cannot be held without !important. */
  #simple-select-quiz .simple-quiz-carat-filter .filter_heading > p { margin: 0 !important; }
  #simple-select-quiz .simple-quiz-carat-filter .filter_heading strong {
    display: block;
    font-family: var(--rb-font-display);
    font-weight: 300;
    font-size: 18px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: uppercase;
    color: var(--rb-text-primary);
    transform: translateY(-3px);   /* SPEC: 19px text in a 14-tall row, y=404 in a row at 402 */
  }
  /* The helper sentence and the "Compare Weights" link are not in the 1.x
     frames. `#carat_video` carries a delegated click handler (simple-select.js)
     and `.filter_heading p` is written to, so both are collapsed rather than
     display:none'd. */
  #simple-select-quiz .simple-quiz-carat-filter .filter_heading > p:nth-of-type(n+2),
  #simple-select-quiz .simple-quiz-carat-filter .filter_heading > #carat_video {
    visibility: hidden;
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
  }

  /* Row A right — "See true size on hand" 14463:33505,
     Founders 400 14/16, ls -0.5, #27423B. */
  #simple-select-quiz .rb_true_size {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    height: 16px;
    margin: 0;
  }
  #simple-select-quiz .rb_true_size_link {
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 16px;
    letter-spacing: var(--rb-ls-wide);
    color: var(--rb-brand-green);
    text-decoration: underline;      /* textDecoration UNDERLINE on 14463:33505 */
  }

  /* Row B — carat size selector 14463:33507, 346x70, SPACE_BETWEEN,
     six 52x70 tiles.  Sits above a 26-tall "Most Picked" row (gap 4). */
  #simple-select-quiz .rb_carat_tiles {
    grid-column: 1 / -1;
    grid-row: 2;
    position: relative;
    display: flex;
    justify-content: space-between;
    width: 100%;
    height: 100px;              /* 70 tiles + 4 gap + 26 tag row */
    margin: 16px 0 0 0;         /* Figma vertical gap 16 under row A */
  }
  #simple-select-quiz .rb_carat_tile {
    position: relative;   /* containing block for the "Most Picked" tag below */
    /* 52px is the design's tile width at its 390px artboard, where six of them plus the
       space-between gaps fit the 346 content column exactly. Below ~360px viewport six
       rigid 52s (312px) no longer fit, and `flex: 0 0` meant they overflowed instead of
       adapting. Cap at 52 and let them shrink: the 30px disc is the real floor, so six
       tiles still fit comfortably down to 320. */
    /* PROPORTIONAL, so the gaps survive. Owner: *"the carat buttons are cramped
       and overlap on each other -- make them spaced and good, fit them all in
       one line."* 14557:45092 draws six 52x70 pills across 345 with ~6.6px
       between them (6 x 52 = 312, and 345 - 312 = 33 over five gaps).

       The tiles were a rigid 52 and only the leftover space gave way, so the
       gaps carried the whole shortfall. MEASURED at 360 (row 316): 6 x 52 = 312
       left 4px for FIVE gaps -- 0.8px each -- and the pill outlines ran
       together, which is the overlap being reported. No box actually
       intersected, which is why a geometry check alone called it clean; the
       1px gaps are what the eye reads.

       52/345 as a share keeps the board exactly at 390 (capped at 52 by
       max-width) and shares the shortfall between tile and gap below it: at 360
       the tile lands on 47.6 and the gaps hold ~6. `aspect-ratio` carries the
       height so the pill keeps its 52:70 shape instead of turning into a
       lozenge; `min-width` stays the disc's own floor. */
    flex: 0 1 15.072463768115942%;   /* 52 / 345 */
    width: 15.072463768115942%;
    min-width: 30px;      /* the disc; below this the tile would clip its own glyph */
    max-width: 52px;
    height: auto;
    aspect-ratio: 52 / 70;
    /* ...and DON'T let the row stretch it. `.rb_carat_tiles` is a 100px-tall
       flex row (it reserves space for the "Most Picked" tag), and the default
       `align-items: stretch` overrode the aspect ratio the moment the explicit
       `height: 70px` was dropped -- MEASURED, the pill came out 52 x 100 and
       read as a lozenge. */
    align-self: flex-start;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    padding: 10px 0;
    box-sizing: border-box;
    background: transparent;
    border: var(--rb-stroke) solid var(--rb-border-subtle);
    border-radius: 200px;
    cursor: pointer;
  }
  /* Disc 14463:36225 — 30x30, r100.  The inner dot grows with the carat:
     10 / 12 / 14 / 18 / 20 / 24 px (36226, 36230, 36234, 36238, 36242, 36246). */
  #simple-select-quiz .rb_carat_disc {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: var(--rb-radius-pill);
  }
  #simple-select-quiz .rb_carat_disc::before {
    content: "";
    display: block;
    border-radius: var(--rb-radius-pill);
    background: var(--rb-grey-disabled);
  }
  #simple-select-quiz .rb_carat_tile[data-carat="0.5"] .rb_carat_disc::before { width: 10px; height: 10px; }
  #simple-select-quiz .rb_carat_tile[data-carat="1.0"] .rb_carat_disc::before { width: 12px; height: 12px; }
  #simple-select-quiz .rb_carat_tile[data-carat="1.5"] .rb_carat_disc::before { width: 14px; height: 14px; }
  #simple-select-quiz .rb_carat_tile[data-carat="2.0"] .rb_carat_disc::before { width: 18px; height: 18px; }
  #simple-select-quiz .rb_carat_tile[data-carat="2.5"] .rb_carat_disc::before { width: 20px; height: 20px; }
  #simple-select-quiz .rb_carat_tile[data-carat="3.0"] .rb_carat_disc::before { width: 24px; height: 24px; }

  #simple-select-quiz .rb_carat_val {
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 16px;
    letter-spacing: var(--rb-ls-wide);
    color: var(--rb-text-secondary);
  }

  /* The 1.5 ct tile carries a #C2CEB2 hairline in SPEC (14463:36232) -- it is
     the tile the "Most Picked" tag points at. */
  /* SPEC strokeDashes [5, 5].  `border-style: dashed` cannot carry a dash
     length -- Chromium picks its own, and on a 1px border that is a ~2px dash
     that reads as a dotted hairline rather than the designed 5/5.

     An SVG background CAN, and it is the only way to get a dashed PILL: the
     four-repeating-linear-gradient trick squares the corners off, and this tile
     is `border-radius: 200px`.  Notes on the shape of it:
       - no viewBox, so the SVG's user units ARE CSS px and the dashes stay 5/5
         at any tile width.  The tile is fluid (flex 0 1 52px down to 30px), and
         a viewBox would have scaled the dash pattern with the box.
       - `stroke-width="2"` with the rect on the box edge: a stroke straddles
         its path, so the outer half falls outside the SVG viewport and is
         clipped, leaving a crisp 1px that sits exactly where the solid 1px
         border sits on the five sibling tiles.
       - `background-origin/clip: border-box` so the SVG viewport is the border
         box, matching the siblings' border rather than the padding box.
     SHAPE: rx AND ry are both given, and both equal HALF THE TILE'S WIDTH.
     `rx='999'` looked like it would clamp to a stadium the way CSS
     `border-radius: 200px` does, but SVG clamps the two axes INDEPENDENTLY --
     rx to width/2 and ry to height/2 -- so a 95x124 tile came out rx 47.5 /
     ry 62.5, a true ellipse, visibly rounder than the five solid tiles beside
     it. CSS instead scales both radii by one factor, which is what makes a
     stadium. Matching that means naming the same number twice. */
  #simple-select-quiz .rb_carat_tile[data-carat="1.5"] {
    border-color: transparent;
    /* A PILL, INSET, AND SCALED WITH THE TILE. Owner: *"the dotted 1.5 carat one
       looks like an oval, can you fix the shape -- it's also cropped on the
       sides."*
       Both come from the same rect. It was drawn at width/height 100% with a
       FIXED `rx`/`ry`, sized for the tile's original box, and `x='0' y='0'` with
       a 2px stroke:
         * SVG clamps `rx` to half the width but leaves `ry` alone, so once the
           tile went fluid the two stopped matching -- at 360 (48 x 66) the
           radii resolved to 38 and 47.5, which is an ELLIPSE, not a pill;
         * a 2px stroke centred on x=0 puts 1px of itself outside the viewport
           on every edge, which the box clips -- the "cropped on sides".
       A viewBox plus `preserveAspectRatio='none'` fixes the shape: the tile
       keeps its authored proportion at every width (MEASURED 48/66 = 0.727
       against the board's 52/70 = 0.743), so rx and ry scale together and
       the stadium holds. The rect is inset by half the stroke so the whole
       stroke stays inside. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 52 70' preserveAspectRatio='none'%3E%3Crect x='1' y='1' width='50' height='68' rx='25' ry='25' fill='none' stroke='%23C2CEB2' stroke-width='2' stroke-dasharray='5 5'/%3E%3C/svg%3E");
    background-origin: border-box;
    background-clip: border-box;
    background-repeat: no-repeat;
    background-size: 100% 100%;
  }


  /* ---- THE CROSSFADE -----------------------------------------------------
     Requested: the tile you leave fades out while the one you pick fades in.
     Figma specifies nothing here -- `carat button` 14463:36224 reports
     `interactions: []`, as does every child -- so this is built to the ask, not
     to a board.

     Every property that differs between the two states is transitioned, so the
     old tile and the new one cross over instead of one snapping: the tile fill
     and its 2px selected outline, the disc slot, the disc itself and the label.
     300ms rather than the builder's usual 260 because the ask was for slower;
     same curve, so it still belongs to the same motion language.

     Colours only. Nothing here touches layout, so the tiles cannot reflow
     mid-transition. */
  #simple-select-quiz .rb_carat_tile {
    transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1),
                border-color 300ms cubic-bezier(0.4, 0, 0.2, 1),
                outline-color 300ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  #simple-select-quiz .rb_carat_disc {
    transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  #simple-select-quiz .rb_carat_disc::before {
    transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  #simple-select-quiz .rb_carat_val {
    transition: color 300ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  @media (prefers-reduced-motion: reduce) {
    #simple-select-quiz .rb_carat_tile,
    #simple-select-quiz .rb_carat_disc,
    #simple-select-quiz .rb_carat_disc::before,
    #simple-select-quiz .rb_carat_val { transition: none; }
  }

  /* Selected tile 14463:36224: fill #D8DDCA, 2px #27423B stroke align=OUTSIDE
     (hence outline, which does not eat the 52px box), disc fill #C2CEB2,
     dot #27423B, label #27423B. */
  #simple-select-quiz .rb_carat_tile.is-selected,
  #simple-select-quiz .rb_carat_tile.active,
  #simple-select-quiz .rb_carat_tile[aria-pressed="true"] {
    background: var(--rb-brand-sage);
    /* stroke align=OUTSIDE on 14463:36224, so it must not eat the content box:
       no border at all, the 2px rule is drawn as an outline.  That also puts
       the disc at y=396 (SPEC) instead of 397 like the 1px-INSIDE tiles. */
    border: 0;
    outline: var(--rb-stroke-thick) solid var(--rb-brand-green);
    outline-offset: 0;
  }
  #simple-select-quiz .rb_carat_tile.is-selected .rb_carat_disc,
  #simple-select-quiz .rb_carat_tile.active .rb_carat_disc,
  #simple-select-quiz .rb_carat_tile[aria-pressed="true"] .rb_carat_disc { background: var(--rb-brand-sage-strong); }
  #simple-select-quiz .rb_carat_tile.is-selected .rb_carat_disc::before,
  #simple-select-quiz .rb_carat_tile.active .rb_carat_disc::before,
  #simple-select-quiz .rb_carat_tile[aria-pressed="true"] .rb_carat_disc::before { background: var(--rb-brand-green); }
  #simple-select-quiz .rb_carat_tile.is-selected .rb_carat_val,
  #simple-select-quiz .rb_carat_tile.active .rb_carat_val,
  #simple-select-quiz .rb_carat_tile[aria-pressed="true"] .rb_carat_val { color: var(--rb-brand-green); }

  /* "Most Picked" 14463:33510 — 81x22 pill, #D8DDCA, r13, pad 4/7, text
     Founders 400 14/12, ls -0.21, #27423B, with a 9x4 caret above it
     (14463:33509).  There is no DOM node for either, so both are drawn on the
     1.5 ct tile.  If markup can change, a real <span> is preferable: CSS
     `content` copy is not selectable and not exposed to assistive tech. */
  #simple-select-quiz .rb_carat_tile[data-carat="1.5"]::before {
    content: "";
    position: absolute;
    top: 74px;                 /* tiles 70 + 4 gap */
    left: 50%;
    transform: translateX(-50%);
    width: 9px;
    height: 4px;
    background: url('../../../assets/media/ringbuilder/icon-caret-up-sage-tooltip.svg') no-repeat center / 9px 4px;
  }
  #simple-select-quiz .rb_carat_tile[data-carat="1.5"]::after {
    content: "Most Picked";
    position: absolute;
    top: 78px;
    left: 50%;
    transform: translateX(-50%);
    width: 81px;
    height: 22px;
    padding: 4px 7px;
    box-sizing: border-box;
    background: var(--rb-brand-sage);
    border-radius: 13px;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 12px;
    letter-spacing: var(--rb-ls-tight);
    text-align: center;
    color: var(--rb-brand-green);
    white-space: nowrap;
  }

  /* noUiSlider: NOT in any 1.x frame, but `#carat-slider-quiz` is the single
     source of truth for the carat value -- simple-select.js reads it in a dozen
     places and sets it programmatically at js:2812, and noUiSlider measures the
     element on init.  So it keeps its box and its width and is hidden with
     visibility, never display:none (brief rule 1).  Same for
     `.active_carat_quiz_container`, whose `#active_carat_quiz` span is written
     to on every slider update. */
  #simple-select-quiz .simple-quiz-carat-filter .filter_row.carat-filters {
    grid-column: 1 / -1;
    grid-row: 3;
    visibility: hidden;
    height: 0;
    margin: 0;
    overflow: hidden;
  }
  #simple-select-quiz .simple-quiz-carat-filter p.active_carat_quiz_container {
    grid-column: 1 / -1;
    grid-row: 4;
    visibility: hidden;
    height: 0;
    margin: 0;
    padding: 0;
    overflow: hidden;
  }

  /* ===========================================================================
     6.  HANDPICKED STONES  — 14463:33512 (y 507-871, SPEC 553-917)
     heading block 38 (19 + 19, gap 0), gap 10, then rows with gap 8.
     =========================================================================== */

  #simple-select-quiz .rb_stones_head {
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    margin: 21px auto 0 auto;   /* Figma vertical gap 21 */
  }
  #simple-select-quiz .rb_stones_title {   /* 14463:33514 */
    margin: 0;
    font-family: var(--rb-font-display);
    font-weight: 300;
    font-size: 18px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: uppercase;
    color: var(--rb-text-primary);
  }
  #simple-select-quiz .rb_stones_sub {     /* 14463:33515 */
    margin: 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);
  }

  /* stone options 14463:33516 — vertical, gap 8. The base sheet lays this out
     as a 2-up grid; on mobile it is a single column of full-width rows. */
  #simple-select-quiz .ssq_all_stone_options {
        /* !important is load-bearing here, not laziness. simple-select.js writes an INLINE
       display on this element -- .css('display','grid') at js:1652/:1918/:1977, plus
       .show()/.hide() at js:660/:1612 which write display:block / display:none. An
       inline style beats any selector, so after the customer picked a stone and came
       back, the list re-rendered with the legacy grid and the rows stopped stacking.
       An author !important is the one thing that outranks an inline declaration. */
    display: flex !important;
    flex-direction: column;
    gap: 8px;
    /* 14463:33516 -- 345 x 316 at x=22.  345, not 346: the row frame
       14463:33518 is 345 wide and the panel inside it is 321 = 345 - 12 - 12
       (MASTER 190/196/204/209).  The left margin is pinned rather than auto so
       the column starts on the design's x=22 exactly, not on 22.5. */
    /* was width: 345px -- the design is authored at 390, so a fixed 345 overflowed every narrower phone. min() keeps 345 at 390 and shrinks below. */
    width: min(345px, calc(100vw - 44px));
    margin: 10px auto 0 22px;
  }

  /* Row 14463:33518 (Natural) — 346x56, pad 8/12, r8,
     fill #FFFFFF @ 0.60, stroke #E4DED8 w=1 INSIDE. */
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection {
    /* was width: 345px -- the design is authored at 390, so a fixed 345 overflowed every narrower phone. min() keeps 345 at 390 and shrinks below. */
    width: min(345px, calc(100vw - 44px));
    /* Height is pinned because Chromium snaps the 2.5px INSIDE stroke of the
       selected variant down to 2 device pixels at DPR 1; without it the two
       states measure 56 and 55.  SPEC row = 345x56 (14463:33518). */
    height: 56px;
    box-sizing: border-box;
    padding: 7px 11px;   /* 8/12 minus the 1px INSIDE stroke -- see note */
    background: rgba(255, 255, 255, 0.60);
    border: var(--rb-stroke) solid var(--rb-border-subtle);
    border-radius: var(--rb-radius-md);
    cursor: pointer;
  }
  /* Selected 14463:33517 — stroke #27423B w=2.5 INSIDE, fill #FFFFFF @ 0.70.
     The 2.5px border is absorbed by border-box so the row stays 56 tall. */
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active {
    padding: 5.5px 9.5px;   /* 8/12 minus the 2.5px INSIDE stroke */
    background: rgba(255, 255, 255, 0.70);
    border: 2.5px solid var(--rb-brand-green);
  }

  #simple-select-quiz .ssq_all_stone_options .ssq_stone_options { padding: 0; }
  #simple-select-quiz .ssq_all_stone_options .stone_option {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;                 /* Figma gap 10 between icon and text */
    padding: 0;
    text-align: left;
    font-size: 14px;
  }
  /* icon 14463:33520 — 40x40, r4, stroke #E4DED8 w=0.5 */
  #simple-select-quiz .ssq_all_stone_options .ssq_stone_image {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border: 0.5px solid var(--rb-border-subtle);
    border-radius: var(--rb-radius-sm);
    overflow: hidden;
  }

  /* NORMALISE THE CATALOGUE THUMB INTO THE BOX.
     These images are WooCommerce product images, so their framing is whatever
     the catalogue happens to hold, not something the design controls. Measured
     on dev-0: the three diamonds are 300x300 stones sitting inset on white, but
     the gemstone's `Round-Lab-Emerald-300x300.jpg` is cropped tight to the
     stone, so under `object-fit: cover` it filled its frame edge to edge and
     read as a flat green disc beside three inset diamonds.

     `contain` plus a white ground and a small inset gives every image the SAME
     treatment whatever its crop: a tightly cropped stone is brought down to the
     inset the diamonds already have, and an image that already carries white
     margin is unchanged in character. This is a rendering fix -- the real
     remedy is a gemstone product image shot like the other three. */
  #simple-select-quiz .ssq_all_stone_options .ssq_stone_image img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #FFFFFF;
    padding: 3px;
    box-sizing: border-box;
    transform: none;           /* base sheet scales unselected thumbs to 0.90 */
  }
  /* Text block: name + subline stacked left (gap 2), price right-aligned on the
     first line.  The DOM prints price BETWEEN the two, so grid placement moves
     it to column 2 without touching the markup. */
  #simple-select-quiz .ssq_all_stone_options .ssq_stone_text {
    flex: 1 1 auto;
    min-width: 0;
    display: grid;
    grid-template-columns: 1fr auto;
    row-gap: 2px;
    align-items: start;
  }
  #simple-select-quiz .ssq_all_stone_options p.ssq_type {           /* 14463:33524 */
    grid-column: 1;
    grid-row: 1;
    margin: 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);
  }
  /* p.ssq_simple_size is the LEGACY sub-line and it is no longer the visible
     one: simple-select.js:2478 rewrites EVERY .ssq_simple_size on the page to
     "<n> carats" on each carat-slider 'update', by class and unscoped, so it can
     never hold the Figma string "0.50 Carat • F Color • VS2 ". p.rb_stone_subline
     (below) carries that; this one collapses.
     Collapsed, NOT display:none -- js:2478 writes into it and the base sheet
     toggles its height on .active, so it must stay a real, measurable box. It
     shares grid cell 2/1 with the subline; at height 0 it adds nothing. */
  #simple-select-quiz .ssq_all_stone_options p.ssq_simple_size {    /* 14463:33525 */
    grid-column: 1;
    grid-row: 2;
    height: 0;
    margin: 0;
    overflow: hidden;
    visibility: hidden;
  }
  /* 14463:33756 — the real sub-line. FG 400 14/19, ls -0.21, #3E3C39 @ 0.95.
     Same cell as the collapsed legacy node above. */
  #simple-select-quiz .ssq_all_stone_options p.rb_stone_subline {
    grid-column: 1;
    grid-row: 2;
    margin: 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: rgba(62, 60, 57, 0.95);   /* #3E3C39 @ 0.95 */
  }
  #simple-select-quiz .ssq_all_stone_options p.details_display_price { /* 14463:33527 */
    grid-column: 2;
    grid-row: 1;
    margin: 0;
    text-align: right;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);
  }
  /* 14463:33763 — "$1,660 total", the second line of the `pricing` stack.
     FG 400 14/19, ls -0.21, #3E3C39 @ 0.95, right-aligned, 2px under the delta
     price (`pricing` itemSpacing 2, which the 2px row-gap already supplies). */
  #simple-select-quiz .ssq_all_stone_options p.rb_stone_total_price {
    grid-column: 2;
    grid-row: 2;
    margin: 0;
    text-align: right;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: rgba(62, 60, 57, 0.95);
    white-space: nowrap;
  }
  /* PHP ships it empty (the total needs the setting price out of localStorage,
     which the server cannot see); collapse rather than reserve a blank 19px line
     for the pre-JS frame. Safe to display:none: additive node, no JS reads it by
     selector -- simple-select-redesign.js writes it via the row it already has. */
  #simple-select-quiz .ssq_all_stone_options p.rb_stone_total_price:empty { display: none; }
  /* base sheet turns every <p> in a selected row jade */
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active p.ssq_type,
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active p.details_display_price { color: var(--rb-text-primary); }
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active p.rb_stone_subline,
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active p.rb_stone_total_price {
    color: rgba(62, 60, 57, 0.95);
  }
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active p.ssq_simple_size {
    height: 0;
    visibility: hidden;
  }
  /* The gemstone row prints `.stone_option` without the `.ssq_stone_options`
     wrapper -- same geometry either way. */
  #simple-select-quiz .ssq_all_stone_options > #simple_gemstone > .stone_option { padding: 0; }

  /* ===========================================================================
     6b. THE SELECTED ROW: COLLAPSED 124 / EXPANDED 354
     Figma 14463:33517 (collapsed, in 14463:33484) and 14463:33750 (expanded, in
     14463:33717); component set 14463:37318 holds both as variants of ONE card.

     The panel is a CHILD of the card, inset by the card's own 12px padding, and
     the card grows.  Figma's own arithmetic, reproduced exactly:

       collapsed  8 (padTop) + 80 (main info) + 30 (disclosure) + [228 clipped] + 8
                  = 126 of content in a frame PINNED to 124 with clipsContent:true
       expanded   8 + 80 + 30 + 228 + 8 = 354, clipsContent:false, height HUG

     So the collapsed card really is 2px shorter than its own content -- that is
     not a rounding slip, it is `clipsContent` trimming the bottom padding, and
     it is reproduced here as an explicit height + overflow:hidden rather than
     silently rounded away.  +230 is the growth to animate (CHECKLIST 97).

     Markup contract (simple-select-quiz-stones.php, appended per row AFTER the
     existing .ssq_stone_options subtree so nothing simple-select.js reads moves):

       .ssq-simple-selection[.active][.rb_details_open]
         .ssq_stone_options ...            <- `main info`      14463:33751
         .rb_stone_details[.is-open]
           button.rb_stone_disclosure[aria-expanded]            14463:33764
             .rb_stone_disclosure_label  "Stone details"        14463:33765
             .rb_stone_chevron > svg 12x6                       14463:33768
           .rb_stone_panel[aria-hidden]    <- Frame 1171276141  14463:33769
             .rb_stone_specs > .rb_stone_spec[data-rb-spec]
                 .rb_stone_spec_label + .rb_stone_spec_value
             p.rb_stone_caveat                                  14463:33803

     GUTTER: this sheet uses the symmetric 346 card (see the header note), so the
     content column is 322 where Figma's 345-wide card gives 321.  Every other
     number below is the Figma value untouched.
     =========================================================================== */

  /* The card must be able to hug when open, and must clip when shut.  Height is
     pinned only on the SELECTED row -- the other three are 56 and own no panel. */
  /* A SELECTED ROW HAS TWO SHAPES, and the difference is the badge.
       14463:33517 `lab diamond` selected     345 x 124  (main info 80)
       14463:34323 `Gemstone`   selected      345 x  93  (`line 1` 45, card gap 2)
     Only the Lab Diamond row carries "Popular Choice" (SEARCH.md §5 row 17: no
     badge exists for natural, moissanite or gemstone in any frame). On mobile
     that badge stacks UNDER the subline, so it alone grows the info column from
     40 to 68 and the card from 93 to 124. The 93 shape is therefore the default
     for a selected row and the 124 shape is the Lab Diamond override -- not the
     other way round, which would size three rows off the one row that is
     different. (Desktop needs no such split: there the badge sits beside an
     83-tall image that already sets the row height either way.)
     Figma draws no selected Natural or Moissanite row; 14463:34250's Gemstone is
     the only badge-less selected artboard, so it is the one generalised from. */
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active {
    height: 93px;         /* 14463:34323 -- 8 + 45 + 2 + 30 + 8 */
    overflow: hidden;     /* clipsContent -- what hides the panel */
    transition: height 260ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  #simple-select-quiz .ssq_all_stone_options > .simple_diamond:first-child.active {
    height: 124px;        /* 14463:33517 -- FIXED, content is 126, clips 2 */
  }
  /* height:auto is only interpolable where interpolate-size is honoured; where it
     is not the geometry is still exact and the change is simply instant. */
  #simple-select-quiz .ssq_all_stone_options {
    interpolate-size: allow-keywords;
  }
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active.rb_details_open,
  #simple-select-quiz .ssq_all_stone_options > .simple_diamond:first-child.active.rb_details_open {
    height: auto;         /* 14463:33750 -- HUG, 354 on the lab row */
    overflow: visible;    /* clipsContent:false */
  }

  /* `main info` 14463:33751 -- 321 x 80: a 68-tall content row, 12px of bottom
     padding, and a 1px #E4DED8 @ 0.40 rule drawn INSIDE the bottom edge (so the
     visible gap under the content is 11, and 68 + 11 + 1 = 80). */
  /* `line 1` 14463:34324 -- 321 x 45: a 40-tall content row, 4px of bottom
     padding and the 1px #E4DED8 @ 0.40 rule INSIDE the bottom edge. The card's
     own itemSpacing is 2 here (0 on the lab card), carried as a margin.
     The row that carries the box differs by stone: .simple_diamond and
     .simple_moissanite wrap their .stone_option in .ssq_stone_options, while
     #simple_gemstone prints .stone_option as a direct child (see the note above
     section 6b). Both are addressed so the hairline and the 2px itemSpacing land
     on the gemstone row too. */
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active > .ssq_stone_options,
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active > .stone_option {
    box-sizing: border-box;
    height: 45px;
    margin-bottom: 2px;
    padding: 0 0 3px 0;
    border-bottom: var(--rb-stroke) solid rgba(228, 222, 216, 0.40);
    align-items: flex-start;
  }
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active .stone_option {
    align-items: flex-start;
  }
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active .ssq_stone_text {
    align-content: start;
    height: 40px;
  }
  /* `main info` 14463:33751 -- 321 x 80 on the badge row: a 68-tall content row,
     12px of bottom padding, the same 1px rule INSIDE the bottom edge (so the
     visible gap is 11, and 68 + 11 + 1 = 80), and no itemSpacing under it. */
  #simple-select-quiz .ssq_all_stone_options > .simple_diamond:first-child.active > .ssq_stone_options {
    height: 80px;
    margin-bottom: 0;
    padding: 0 0 11px 0;
  }
  /* `Details` 14463:33752 -- icon 40x40 top-aligned beside a 68-tall info column:
     the 40-tall title/subline pair (19 + 2 + 19), gap 6, then the 22-tall badge. */
  #simple-select-quiz .ssq_all_stone_options > .simple_diamond:first-child.active .stone_option,
  #simple-select-quiz .ssq_all_stone_options > .simple_diamond:first-child.active .ssq_stone_text {
    height: 68px;
  }
  /* Gemstone is a wrapper short, so its 40-tall content row is the padded box
     itself: 45 - 3 - 1 leaves 41, and the 40-tall icon sits at its top. */
  #simple-select-quiz .ssq_all_stone_options > #simple_gemstone.active > .stone_option .ssq_stone_text {
    height: 40px;
  }
  /* "Popular Choice" 14463:33760 -- 104 x 22, r12, #142037, pad 4/9, label
     FG 400 14/19 #FAF3ED.  There is no markup node for it and the string is
     static in the design, so it is generated rather than invented in PHP.  It is
     bound to the FIRST row (Lab Diamond, which PHP always prints first) and not
     to .active: in Figma it is a property of that stone, not of the selection.
     The 22px box is Figma's pin -- 4 + 19 + 4 would be 27 -- so the label is
     centred in 22 instead of padded to it. */
  #simple-select-quiz .ssq_all_stone_options > .simple_diamond:first-child.active .ssq_stone_text::after {
    content: "Popular Choice";
    grid-column: 1;
    grid-row: 3;
    justify-self: start;
    box-sizing: border-box;
    margin-top: 6px;              /* `info` itemSpacing */
    height: 22px;
    padding: 0 9px;
    display: inline-flex;
    align-items: center;
    border-radius: 12px;
    background: var(--rb-ink-navy);
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-surface-page);
  }
  /* NOT REACHABLE: the second price line "$1,660 total" (14463:33763, FG 400
     14/19 #3E3C39 @ 0.95, right-aligned under "+ $980").  The row has exactly one
     price node, p.details_display_price, whose text simple-select.js re-parses
     into a number (js:480, js:2718) -- so it can be neither split nor duplicated
     from CSS, and generated content cannot know the running total.  Needs a
     second node in the markup. */

  /* --- the disclosure row -------------------------------------------------
     `main info` 14463:33764 -- 321 x 30, SPACE_BETWEEN, centred.  Only the
     selected row has one (CHECKLIST 72); on the other three the wrapper is
     collapsed to zero height rather than display:none, because
     simple-select-redesign.js renders into .rb_stone_specs on every row. */
  #simple-select-quiz .ssq_all_stone_options .rb_stone_details {
    height: 0;
    overflow: hidden;
    /* GROW, DO NOT SNAP. Measured frame-by-frame on dev-0: clicking a row took
       it from 118 to 169 in a SINGLE frame and then eased back down to 158 over
       ~250ms -- a hard jump followed by a slow shrink, which is what reads as
       the card "suddenly becoming big" and then jittering.

       The jump was this wrapper: `height: 0 -> auto` with no transition on it,
       while the panel INSIDE it carries one. `interpolate-size: allow-keywords`
       is already on `.ssq_all_stone_options`, so the keyword interpolates and
       the same 260ms curve the panel and the chevron use applies here too. */
    transition: height 260ms cubic-bezier(0.4, 0, 0.2, 1);
    visibility: hidden;
  }
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active .rb_stone_details {
    height: auto;
    overflow: visible;
    visibility: visible;
  }
  #simple-select-quiz .ssq_all_stone_options .rb_stone_disclosure {
    display: flex;
    align-items: center;
    justify-content: space-between;
    box-sizing: border-box;
    width: 100%;
    height: 30px;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    text-align: left;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }
  /* `Details` 14463:33765 -- 70 x 19, FG 400 14/19, ls -0.21, #3E3C39. */
  #simple-select-quiz .ssq_all_stone_options .rb_stone_disclosure_label {
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
    text-transform: none;      /* textCase ORIGINAL */
  }
  /* Frame 1171276137 -- a 30 x 30 hit target flush to the card's 12px padding,
     holding a 12 x 6 vector stroked #3E3C39 at 1.5.  Figma nets 0deg collapsed
     and 180deg expanded (the parent frame's -pi and the vector's own rotation
     cancel); the box is identical in both states, so this rotates about the
     glyph centre and never translates (CHECKLIST 96). */
  #simple-select-quiz .ssq_all_stone_options .rb_stone_chevron {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 30px;
    box-sizing: border-box;
    width: 30px;
    height: 30px;
    /* CENTRED, both axes.  Frame 1171276137 (I14463:33517;14463:37336) is
       AL:VERTICAL primary=CENTER counter=CENTER at (325,689) 30x30 and its
       12x6 vector (…;14463:37337) sits at x=334 -- exactly (30-12)/2 = 9 in
       from the target's left edge.  Card x is 22, so the target is card-rel
       303..333 and the glyph card-rel 312..324.  MASTER 201/227 record the
       glyph as 306..318; that contradicts both the raw Figma node and MASTER's
       own "centred in 303..333" wording, so the node wins.  A 3px left inset
       used to stand here and put the glyph at 307.5..319.5. */
    color: var(--rb-text-secondary);
  }
  /* 14 x 8, DRAWING A 12 x 6 CHEVRON. Owner: *"the down arrows on the lab
     diamond / natural diamond / moissanite / gemstone bars are chopped -- cut
     down at the bottom."* They were: the path ran corner to corner of a
     `0 0 12 6` viewBox, and an SVG clips to its viewBox, so a 1.5 stroke with
     ROUND caps lost 0.75 off every edge -- most visibly the bottom vertex,
     which came out sliced flat instead of pointed. The glyph is unchanged at
     12 x 6; the box around it now has the 1px the stroke needs. */
  #simple-select-quiz .ssq_all_stone_options .rb_stone_chevron svg {
    display: block;
    width: 14px;
    height: 8px;
    transform: rotate(0deg);
    transform-origin: 50% 50%;
    transition: transform 260ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  #simple-select-quiz .ssq_all_stone_options .rb_stone_details.is-open .rb_stone_chevron svg {
    transform: rotate(180deg);
  }

  /* --- the spec panel -----------------------------------------------------
     Frame 1171276141 14463:33769 -- 321 x 228 at card-relative (12, 118),
     VERTICAL gap 6: a 190-tall rows group and a 32-tall caveat.
     Collapsed with height, never display:none -- the growth IS the gesture. */
  #simple-select-quiz .ssq_all_stone_options .rb_stone_panel {
    display: flex;
    flex-direction: column;
    gap: 6px;
    height: 0;
    overflow: hidden;
    transition: height 260ms cubic-bezier(0.4, 0, 0.2, 1);
  }

  /* ...and the rest of the selection gesture, on the same curve.
     The wrapper transition above fixed the 51px snap, but a 16px jump survived
     it -- measured at t=12ms, before the wrapper had moved at all. That one is
     NOT the details panel: on `.active` the row's own padding goes 18/15 -> 15.5,
     its border 1px -> 2px, and `.ssq_stone_options` gains `padding-bottom: 15px`.
     All three are concrete lengths, so unlike a content-driven `height: auto`
     they interpolate directly -- no `interpolate-size` needed and no layout
     thrash. Transitioning them is what turns "snap, then grow" into one motion. */
  #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection {
    transition: padding 260ms cubic-bezier(0.4, 0, 0.2, 1),
                border-width 260ms cubic-bezier(0.4, 0, 0.2, 1),
                border-color 260ms cubic-bezier(0.4, 0, 0.2, 1),
                background-color 260ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  #simple-select-quiz .ssq_all_stone_options .ssq_stone_options {
    transition: padding 260ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  #simple-select-quiz .ssq_all_stone_options .rb_stone_details.is-open .rb_stone_panel {
    height: auto;
    overflow: visible;
  }
  /* Frame 1171276146 -- 321 x 190, VERTICAL gap 4. */
  #simple-select-quiz .ssq_all_stone_options .rb_stone_specs {
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  /* One uniform row: a fixed 120 label box, an 8px gutter, then the value.
     Row height 24 everywhere EXCEPT Certificate, which Figma draws at 22
     (CHECKLIST 83) -- addressed by its data key, not by :nth-child, so the
     height does not migrate when a stone type ships a different row set.
     24*6 + 22 + 4*6 = 190. */
  #simple-select-quiz .ssq_all_stone_options .rb_stone_spec {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    min-height: 24px;
  }
  #simple-select-quiz .ssq_all_stone_options .rb_stone_spec[data-rb-spec="Certificate"] {
    min-height: 22px;
    padding-right: 8px;        /* 14463:33783 -- the one row with a right inset */
  }
  #simple-select-quiz .ssq_all_stone_options .rb_stone_spec_label {
    flex: 0 0 120px;
    width: 120px;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
    text-transform: none;
  }
  #simple-select-quiz .ssq_all_stone_options .rb_stone_spec_value {
    flex: 1 1 auto;
    min-width: 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 22px;         /* values run 22, labels 19 -- CHECKLIST 89/90 */
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);
    text-transform: none;
  }
  /* 14463:33803 -- 321 x 32, FG 400 14/16, ls -0.21, #3E3C39, wraps to 2 lines.
     Moissanite and gemstone carry no caveat in data-details, so the node renders
     empty; :empty removes it AND its 6px gap instead of leaving a 32px hole. */
  #simple-select-quiz .ssq_all_stone_options .rb_stone_caveat {
    margin: 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 16px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
    text-align: left;
  }
  /* The one display:none in this block, and the one case the "never hide what JS
     reads" rule allows: :empty matches only while the node has NO text, and
     simple-select-redesign.js reaches it with .text(), a setter that works on a
     hidden node and re-shows it the moment it writes a caveat. */
  #simple-select-quiz .ssq_all_stone_options .rb_stone_caveat:empty { display: none; }

  /* Respect a reduced-motion preference: the two states stay exact, the
     260ms interpolation between them is dropped. */
  @media (prefers-reduced-motion: reduce) {
    #simple-select-quiz .ssq_all_stone_options > .ssq-simple-selection.active,
    #simple-select-quiz .ssq_all_stone_options .rb_stone_panel,
    #simple-select-quiz .ssq_all_stone_options .rb_stone_chevron svg { transition: none; }
  }

  /* ===========================================================================
     7.  STONE DETAILS ACCORDION  — 14463:33750 expanded body (SPEC 719-947)
     Rows are label 120 + value, 14/19 vs 14/22, row gap 4, then a 32-tall
     caveat line at 14/16.  In the DOM this is one shared block after the list,
     not a per-row accordion.
     =========================================================================== */

  /* RETIRED VISUALLY, KEPT IN THE DOM.  Figma has no shared accordion -- the
     details now live inside the tapped row (section 6b).  This block must NOT be
     display:none'd: simple-select.js writes .simple_details_info on every row
     click (js:2290/2307) and reads it back as the source of truth for the
     desktop panel (js:1470) and the confirmation summary (js:1751), and it also
     slideToggles the inner div (js:2366), which display:none on the ancestor
     would fight.  So it is taken out of the flow with zero height + hidden
     visibility + an off-screen clip, which leaves .html() and .text() intact.
     .rb_legacy_shared_details is the hook the markup added for exactly this. */
  #simple-select-quiz .stone_details_accordion.rb_legacy_shared_details {
    position: absolute;
    left: -9999px;
    /* was width: 345px -- the design is authored at 390, so a fixed 345 overflowed every narrower phone. min() keeps 345 at 390 and shrinks below. */
    width: min(345px, calc(100vw - 44px));
    height: 0;
    /* The generic .stone_details_accordion rule below sets border-box padding
       8/12 and a 1px hairline.  With height:0 those still paint, so the box
       measured 345 x 18 (8+8 padding + 1+1 border) and left an 18px dead band
       in flow under the stone list.  Zero them here -- MASTER 189 asks for
       visibility:hidden + ZERO height, never display:none. */
    padding: 0;
    border: 0;
    margin: 0;
    height: 0;
    min-height: 0;
    overflow: hidden;
    visibility: hidden;
    pointer-events: none;
  }

  #simple-select-quiz .stone_details_accordion {
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    margin: 8px auto 0 auto;
    padding: 8px 12px;
    box-sizing: border-box;
    background: rgba(255, 255, 255, 0.70);
    border: var(--rb-stroke) solid var(--rb-border-subtle);
    border-radius: var(--rb-radius-md);
  }
  #simple-select-quiz .stone_details_accordion p.simple_details {   /* 14463:37335 */
    display: flex;
    align-items: center;
    height: 30px;
    margin: 0;
    line-height: 19px;
  }
  #simple-select-quiz .stone_details_accordion p.simple_details a {
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
    text-decoration: none;
  }
  #simple-select-quiz .stone_details_accordion p.simple_details svg { display: none; }
  /* chevron 14463:37337 — 12x6, stroke #3E3C39 w=1.5, in a 30x30 box right */
  #simple-select-quiz .stone_details_accordion p.simple_details::after {
    background-image: url('../../../assets/media/ringbuilder/icon-chevron-down-10.svg');
    background-size: 12px 6px;
    background-repeat: no-repeat;
    background-position: center;
    width: 30px;
    height: 30px;
    margin: 0 0 0 auto;
    float: none;
  }
  #simple-select-quiz .stone_details_accordion .simple_details_info {
    padding: 6px 0 0 0;   /* Figma gap 6 under the toggle row; no side inset */
    margin: 0;
  }
  /* Rows are built by simple-select.js:2307 as
     <p><span style="font-weight:bold">Key:</span> value</p>.  The bold is an
     inline style, so the SPEC weight (400, #3E3C39) needs !important -- the one
     place in this sheet where specificity cannot win. */
  #simple-select-quiz .stone_details_accordion .simple_details_info p {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    min-height: 24px;
    margin: 0 0 4px 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 22px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);
  }
  #simple-select-quiz .stone_details_accordion .simple_details_info p > span {
    flex: 0 0 120px;
    width: 120px;
    font-weight: 400 !important;
    line-height: 19px;
    color: var(--rb-text-secondary);
  }

  /* ===========================================================================
     8.  STICKY CTA  — 14463:33707 (390x129, pinned to the bottom)
     pad 12/10/10/10 + the CTA's own x=22 -> a 22 px gutter; 44-tall primary,
     gap 8, 28-tall text link inside a 40-tall wrapper (12 px of slack, folded
     into the bottom padding: 12 + 44 + 8 + 28 + 37 = 129).
     =========================================================================== */

  #simple-select-quiz .ssq_all_stone_confirmations {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 100;
    /* IT HUGS WHAT IT HOLDS. Owner: *"on the stone screen in the BYR flow,
       adjust the sticky width at the bottom -- when there's no advanced search,
       like for moissanites and gemstones, the section holding Continue to Ring
       Size must resize, while admitting decent padding around it."*

       The 129 was the height WITH the advanced-search link in it. MEASURED at
       390 on a moissanite, where that link is not rendered: the CTA ends at
       y771 and the bar still ran to 844 -- 73px of empty cream under the
       button, because the height was pinned regardless of contents.

       `height: auto` with a `min-height` floor instead, so the bar is the sum of
       what it actually contains: 12 top + the 44 CTA + (8 + 28 for the advanced
       row, when there is one) + the bottom inset. With the link it still
       resolves to the designed 129; without it, to about 90.

       The bottom inset STAYS at the board's 37. A first pass cut it to 24 and
       MEASURED the lab bar at 116 instead of 129 -- shrinking a state the owner
       did not ask about. `max()` keeps the 37 everywhere and only grows it where
       a notch actually needs more room. The min-height keeps a short bar from
       looking cramped against the viewport edge.

       --rb-nav-reserve, which the quiz's own bottom padding is derived from, is
       measured off this element by simple-select-redesign.js -- so the content
       above re-reserves the right amount on its own when this shrinks. */
    height: auto;
    min-height: 88px;
    padding: 12px 22px max(37px, calc(24px + env(safe-area-inset-bottom, 0px))) 22px;
    margin: 0;
    box-sizing: border-box;
    background: var(--rb-surface-page);
  }
  /* The <p> wrappers are show()/hide()n by simple-select.js:1595-1596, so no
     `display` is set on them here -- only box metrics. */
  #simple-select-quiz .ssq_all_stone_confirmations > p { margin: 0; }
  #simple-select-quiz .ssq_all_stone_confirmations > p + p { margin-top: 8px; }

  #simple-select-quiz .ssq_all_stone_confirmations .ssq_finalize_button {  /* 14463:33709 */
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    height: 44px;
    padding: 0;
    box-sizing: border-box;
    background: var(--rb-brand-green);
    border: 0;
    border-radius: var(--rb-radius-sm);
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: uppercase;
    text-align: center;
    color: var(--rb-surface-page);
    text-decoration: none;
  }
  /* arrow 14463:33712 — 12 wide, stroke #FAF3ED w=1.25 */
  #simple-select-quiz .ssq_all_stone_confirmations .ssq_finalize_button::after {
    content: "";
    width: 12px;
    height: 10px;
    background: url('../../../assets/media/ringbuilder/icon-arrow-right-on-cta.svg') no-repeat center / 12px auto;
  }
  /* 14463:33714 — 346x28, r4, no fill, Founders 400 16/19 #27423B.
     .browse_more NO LONGER FILLS THIS SLOT: .rb_adv_search_row does (below).
     The box metrics are kept anyway because the node stays laid out off-screen
     and simple-select-redesign.js:616 proxies the visible link's click onto it,
     so every real handler (diamond-search.js:2530 in-quiz search;
     simple-select.js:1616 "Change of Heart?" modal) still runs on a sized,
     hit-testable element.
     COPY NOTE: SPEC reads "Advanced lab diamond search" and per annotation
     14463:36452 re-labels per selected category; the DOM string here is
     "Browse More Lab Diamonds" (set by simple-select.js:1601) — which is why
     the label had to move to a node simple-select.js does not rewrite. */
  #simple-select-quiz .ssq_all_stone_confirmations .browse_more {
    display: flex;
    align-items: center;
    justify-content: center;
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    height: 28px;
    padding: 0;
    box-sizing: border-box;
    background: none;
    border: 0;
    border-radius: var(--rb-radius-sm);
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-align: center;
    color: var(--rb-brand-green);
    text-decoration: underline;      /* textDecoration UNDERLINE on 14463:33716 */
  }

  /* Take .browse_more's <p> OUT OF FLOW so it contributes neither the 28px row
     nor the 8px list gap, leaving exactly one secondary slot in the 129px bar
     (12 + 44 + 8 + 28 + 37 = 129).
     Off-screen, NOT display:none: simple-select.js:1595-1596 calls
     .show()/.hide() on these <p> wrappers, and the inline `display:block` that
     .show() writes would beat any display we set here and resurrect the old
     link. `position` and `left` are untouched by show()/hide(), so this holds in
     both states. The node stays laid out and hit-testable for the click proxy.
     Negative `left` does not extend scrollWidth in LTR, so no overflow. */
  #simple-select-quiz .ssq_all_stone_confirmations > p:has(.browse_more) {
    position: absolute;
    left: -9999px;
    top: 0;
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    height: 28px;
    margin: 0;
  }

  /* 14463:33716 — Frame 1171276227, the secondary-CTA tap target: 346 x 28,
     padding 0 14, radius 4, no fill, label centred. The <p> IS the tap target;
     flex centring overrides the theme's 16/17.6 strut so the 19px line box sits
     inside the 28px height instead of setting it. */
  #simple-select-quiz .ssq_all_stone_confirmations p.rb_adv_search_row {
    display: flex;
    align-items: center;
    justify-content: center;
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    height: 28px;
    padding: 0 14px;
    box-sizing: border-box;
    background: none;
    border: 0;
    border-radius: var(--rb-radius-sm);
  }
  /* The Gemstone suppression — CHECKLIST [SEARCH] 28. The `hidden` attribute is
     set by simple-select-redesign.js:601; the UA sheet's display:none loses to
     the display:flex above, so it has to be restated. display:none is safe on
     THIS node only: it is additive markup that no legacy JS reads. */
  #simple-select-quiz .ssq_all_stone_confirmations p.rb_adv_search_row[hidden] {
    display: none;
  }
  /* 14463:33716 text — Founders Grotesk 400 16/19, ls -0.21, #27423B,
     textDecoration UNDERLINE, textCase ORIGINAL. The colour is stated on the
     link states too: bare <a> in this bar otherwise inherits the theme link
     colour (#0F0E0D). */
  #simple-select-quiz .ssq_all_stone_confirmations .rb_adv_search_link,
  #simple-select-quiz .ssq_all_stone_confirmations .rb_adv_search_link:hover,
  #simple-select-quiz .ssq_all_stone_confirmations .rb_adv_search_link:focus,
  #simple-select-quiz .ssq_all_stone_confirmations .rb_adv_search_link:visited {
    display: block;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-align: center;
    text-transform: none;
    text-decoration: underline;
    color: var(--rb-brand-green);
  }

  /* The shared Back / Your Setting / Next bar is not part of any 1.x stone
     frame -- the back affordance is the header chevron and "Next" is the CTA
     above.  Collapsed ONLY while the stone slide is active (`:has()` keeps this
     off the size / engraving / review steps), and with visibility rather than
     display:none because simple-select.js:1245-1246 calls .show()/.hide() on
     `.sss-next`, `.setting_total` and `.full_total`. */
  /* `:not(.rb-stone-panel)` is load-bearing. 2.2 (14468:36206) and 2.4
     (14468:36310) BOTH draw a 390x129 footer with the primary CTA in it, and
     both render inside `#ssq_select_stone.active` -- so without this exclusion
     the new screens inherited the collapse and measured
     `.ssq_bottom_nav` = [0,900,390,0] visibility:hidden, with ADD TO RING and
     CONTINUE TO RING SIZE hidden inside it. On 2.4 that was a dead end in the
     strict sense: `.rb-stone-held` hides the four `.ssq-simple-selection`
     cards, whose own `Choose This Stone` button used to be the only way off
     the stone step on mobile. */
  #simple-select-quiz:has(#ssq_select_stone.active):not(.rb-stone-panel) .ssq_bottom_nav,
  #simple-select-quiz:has(#ssq_engraving.active) .ssq_bottom_nav {
    visibility: hidden;
    height: 0;
    padding: 0;
    border: 0;
    overflow: hidden;
  }

  /* ---------------------------------------------------------------------------
     8b.  THE STICKY BLOCK ON RING SIZE AND ENGRAVING
     Frame 1171276552 14463:34704 -- 390 x 129 at y 719 (real y 673, the frames
     carry a 46px status-bar mockup), AL:VERTICAL gap=10 pad=12,10,10,10,
     fill #FAF3ED and NO stroke.  Its one child 14463:34705 is a 370-wide
     stack of a 346 x 44 CTA (14463:34706) at (22,731) over a 346 x 28
     reassurance slot (14463:34711) at (22,783), itemSpacing 8.  primary=MIN,
     so the 27px of slack (129 - 12 - 80 - 10) falls BELOW the copy.

     ENGRAVING NO LONGER SHARES THIS BLOCK.  14463:35118 has no sticky frame at
     all: its 346 x 44 CTA 14463:35169 is the last child of the Engraving block,
     in flow.  That in-flow node now ships (`button.rb_eng_addbag`, styled in
     _engraving.css §4b) and proxies its click to this bar's own `.sss-next`, so
     the bar is collapsed on that step with the same visibility/height-0 shape
     the stone step uses -- `.sss-next` stays in the DOM and stays clickable.
     MASTER 364/366/367 were written against the stopgap mapping and now resolve
     against `.rb_eng_addbag` instead of `.ssq_bottom_nav .sss-next`.

     `:has()` scopes this to the size slide.  Slide 1 is stone (collapsed
     above), 2 size, 3 engraving (collapsed above), 4 review --
     simple-select.js:1088 moves `.active` across
     `.simple-select-slide[slide=N]`, and #ssq_metal_shapes / #ssq_select_stone
     share slide 1, so the selectors never overlap.
     ------------------------------------------------------------------------ */
  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav {
    box-sizing: border-box;
    padding: 12px 10px 10px;
    border: 0;                    /* 14463:34704 carries a fill, no stroke */
    background: var(--rb-surface-page);
  }
  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav {
    /* HEIGHT BY CONTENT, NOT THE BOARD'S 129.
       Owner, three times and finally: *"in the sticky section there's a gap
       between the last line and the bottom of the screen -- a lot of space
       wasted on the sticky ones, everywhere in the BYR flow on phone"*, and
       *"on the back-to-stone page there's a hell of a lot of space between the
       last content and the sticky bottom bar top."*

       MEASURED at 390 on the stone panel: the band 129 tall holding ONE child
       80 tall inside 12/10 of padding -- 102 of content in a 129 box, so 27px
       of the band is nothing at all, and it sits between the shopper's last
       line and the bottom of the screen. The earlier pass took 40% off the
       CLEARANCE above the band (24 -> 14, and 8 -> 5 here), which is why the
       gap above it now measures 5px and the complaint did not go away: the
       waste was never above the band, it was inside it.

       `height: auto` is safe precisely because nothing downstream hard-codes
       129 either: simple-select-redesign.js publishes `--rb-nav-reserve` from
       this band's RENDERED height, so the page's own bottom padding follows it
       down on its own. 14463:34704's 129 was an AL:VERTICAL frame with
       pad 12/10 and gap 10 -- a hug, drawn at the height its contents happened
       to need on that artboard, not a fixed rail. */
    height: auto;
  }

  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav .sss-nav {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;   /* primary=MIN -- slack falls below */
    gap: 8px;                      /* 14463:34705 itemSpacing */
    width: 100%;
  }

  /* Back and the two running totals are not on either frame.  Parked, never
     display:none'd: simple-select.js:1245-1246 calls .show()/.hide() on
     `.setting_total` and `.full_total` and an inline `display` beats a
     stylesheet rule, so they are taken out of flow instead -- which an inline
     display cannot undo.  `.sss-prev` keeps its click target in the DOM for
     the header chevron's `.rb_back` proxy, whose handler falls back to
     $('.sss-prev').first() once :visible finds nothing (offsetWidth 0). */
  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav .sss-prev {
    order: 1;
    visibility: hidden;
    width: 0;
    height: 0;
    padding: 0;
    /* A zero-sized flex item still eats its share of the column's 8px gap and
       pushed the CTA to y=693 instead of the design's 685 (731 - 46). */
    margin: 0 0 -8px;
    overflow: hidden;
  }
  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav p.setting_total,
  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav p.full_total {
    position: absolute;
    left: -9999px;
    top: 0;
    width: 0;
    height: 0;
    margin: 0;
    padding: 0;
    overflow: hidden;
    visibility: hidden;
  }

  /* CTA 14463:34706 -- 346 x 44, #27423B, r4, pad 14/0, gap 5, label Founders
     Grotesk 400 16/19 ls -0.21 #FAF3ED, `textCase: UPPER`.  Centring the
     179 + 5 + 12 content in 346 puts the label on x=97 and the arrow on x=281,
     which is what SPEC records. */
  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav .sss-next {
    order: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    box-sizing: border-box;
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    height: 44px;
    padding: 14px 0;
    margin: 0;
    border-radius: var(--rb-radius-sm);
    background: var(--rb-brand-green);
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: uppercase;
    text-decoration: none;
    color: var(--rb-surface-page);
  }
  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav .sss-next svg {
    display: block;
    width: 12px;
    height: auto;
    margin: 0;
    flex: 0 0 12px;
  }
  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav .sss-next svg path {
    stroke: var(--rb-surface-page);
    stroke-width: 1.25;           /* Vector 138 14463:34709 */
  }
  /* Reassurance slot 14463:34711 -- 346 x 28, Founders Grotesk 400 14/21,
     #3E3C39 at 90%, centred, 8px under the CTA.  SIZE only.

     A REAL NODE NOW CARRIES IT.  `p.rb_nav_note` ships empty from
     simple-select-quiz.php and simple-select-redesign.js writes the string on
     step 2 only, so the line is selectable and exposed instead of being drawn
     with `content` -- the ::after that used to stand here is gone, or the copy
     would render twice.

     ORDER IS LOAD-BEARING.  The <p> is the FIRST child of `.sss-nav` in source
     order, so at its default `order: 0` it took the top of the column and
     pushed the CTA from the designed 12px below the bar's top edge to 37.6.
     `order: 3` puts it back under the CTA, on the 8px column gap the design's
     itemSpacing draws. */
  #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav .rb_nav_note {
    order: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    /* was width: 346px -- the design is authored at 390, so a fixed 346 overflowed every narrower phone. min() keeps 346 at 390 and shrinks below. */
    width: min(346px, calc(100vw - 44px));
    height: 28px;
    margin: 0;
    padding: 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 21px;
    letter-spacing: var(--rb-ls-tight);
    text-align: center;
    color: rgba(62, 60, 57, 0.90);
  }
  /* Every other step leaves the slot empty (RB_NAV_NOTES has one entry).  An
     empty flex item is still an item: it kept its own 0-height box AND its
     share of the column's 8px gap, which is what inflated the engraving bar
     past the 12 + 44 + 10 the frame draws.  `:empty` is not used -- the JS
     writes an empty TEXT NODE rather than removing it, and that is not
     `:empty` in every engine.  Keyed off the step instead, which is exact. */
  #simple-select-quiz:not(:has(#ssq_size.active)) .ssq_bottom_nav .rb_nav_note {
    display: none;
  }

  /* ===========================================================================
     9.  "SEE TRUE SIZE ON HAND" OVERLAY  — 14463:33993 / 14463:33994
     Scrim #000000 @ 0.50 over the whole page, panel 348x734 at (21,140-46=94),
     r4, pad 10, close 24x24 top-right (10x10 glyph, stroke #0F0E0D w=0.75),
     photo-hand-see-true-size.png STRETCHed.
     There is NO DOM for this: `.rb_true_size_link` is a bare <a href="#"> with
     no panel and no scrim node, and nothing in simple-select.js opens one.  The
     panel below is therefore authored against a hook that does not exist yet
     (`body.rb-true-size-open` + a `.rb_true_size_panel` node) so that landing
     the markup is a one-line change and no numbers have to be re-derived.
     =========================================================================== */

  #simple-select-quiz .rb_true_size_panel {
    position: fixed;
    top: 94px;
    left: 21px;
    width: 348px;
    height: 734px;
    padding: 10px;
    box-sizing: border-box;
    z-index: 200;
    border-radius: var(--rb-radius-sm);
    background: url('../../../assets/media/ringbuilder/photo-hand-see-true-size.png') no-repeat center / 100% 100%;
  }
  #simple-select-quiz .rb_true_size_panel .rb_true_size_close {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 24px;
    height: 24px;
    border: 0;
    border-radius: var(--rb-radius-sm);
    background: url('../../../assets/media/ringbuilder/icon-close-x-12.svg') no-repeat center / 10px 10px;
  }
  #simple-select-quiz .rb_true_size_scrim {
    position: fixed;
    inset: 0;
    z-index: 199;
    background: rgba(0, 0, 0, 0.50);
  }

}

/* =============================================================================
   ADDENDUM — MOBILE (<=991px), added against DEFECTS.md D4 and SPACING2.md §C.

   Everything below was written from numbers measured on dev-0 at 390 through
   adv3/lib.js, then diffed against:
     `2.2 Stone details` MOBILE  14468:36206  (SPACING2 §C)
     `Settings` pill MOBILE      14468:36314 / 36315 / 36977  (DEFECTSPEC D4)

   Nothing here deletes or reorders a rule above; every block is a later,
   equal-or-higher-specificity override in the same cascade.
   ============================================================================= */

@media (max-width: 991px) {

  /* ===========================================================================
     D4.  THE METAL / SHAPE PILLS — 14468:36315 (metal) and 14468:36986 (shape)

     MEASURED at 390 before this block:
       metal label starts x=251, shape label starts x=266   -> 15px ragged
       span.icon 35 wide (simple-select.css:663 `.select_metal_shape span
         { width: 35px }`) holding a 20px svg -> 15px of dead space
       .select_metal_option / .select_shape_option: padding 8px 5px / 5px,
         gap 8px  -> glyph starts at 223, board says 218
       shape glyph painted INK 13.4px; board frame is 20 and its vector fills it
       metal label "14K WHITE GOLD" 98.06px wide -> overruns the 123px inner box

     BOARD: pill 144x36 r34 #E4DED8@0.40; inner 123x20 at left inset 8;
       glyph 20x20, gap 6, label 14/16 ls -0.21 SMALL_CAPS_FORCED;
       BOTH labels start at x=244 = 218 + 20 + 6.
     =========================================================================== */

  /* The generated option row is the real flex line — the 6px gap pinned on
     .*_current_option above never reached it because the generated
     .select_metal_option / .select_shape_option sits between them. */
  #simple-select-quiz .quiz-image .metal_dropdown_ssq > .metal_current_option > .select_metal_option,
  #simple-select-quiz .quiz-image .shape_dropdown_ssq > .shape_current_option > .select_shape_option {
    /* NORMAL CASE. These two pills rendered "14K WHITE GOLD" and "ROUND"; the
       metal and the shape are names, and the board writes them as names. The
       uppercase is inherited: simple-select.js CLONES the chosen option out of
       the dropdown LIST -- classes and all -- into the pill, bringing the list's
       own casing with it. Reset on the pill only, so the list is untouched. */
    text-transform: none;
    font-variant-caps: normal;
    display: flex;
    align-items: center;            /* counterAxisAlignItems: CENTER, as drawn */
    gap: 6px;                       /* itemSpacing 6 on 14468:36979 / 36985 */
    padding: 0;                     /* was 8px 5px — pushed the glyph to 223 */
    border-bottom: 0;               /* the dropdown-list divider, not the pill */
    /* ROUND2: `.select_shape_option.disabled` (simple-select.css:709) paints
       `background: #a3a3a3; border-color: #a3a3a3` -- a grading colour for a
       shape the current setting cannot take, written for the DROPDOWN LIST.
       simple-select.js clones the chosen option into `.shape_current_option`
       WITH its classes, so a disabled shape put a solid grey 142 x 20 bar
       behind the label inside the 220 x 44 pill (measured at 1728 on 2.4 and
       2.2; the sibling `.select_metal_option` was rgba(0,0,0,0)). 14468:41896
       draws the pill interior on the pill's own fill with no inner block.
       Nulled HERE rather than at the source, which the list still needs. */
    background: transparent;
    border-color: transparent;
    width: 100%;
    min-width: 0;                   /* or the flex line refuses to shrink */
    overflow: hidden;
    cursor: pointer;
  }

  /* ONE 20px glyph slot on BOTH pills, so the two labels land on the same x.
     simple-select.css:663 gives every span in .select_metal_shape width:35px;
     this is the same declaration at higher specificity, not a removal. */
  #simple-select-quiz .quiz-image .metal_dropdown_ssq > .metal_current_option > .select_metal_option > span.metal_icon,
  #simple-select-quiz .quiz-image .shape_dropdown_ssq > .shape_current_option > .select_shape_option > span.icon {
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: visible;              /* the svg below is deliberately larger */
    line-height: 0;
  }

  /* 14468:36980 — the metal swatch is a 20x20 circle. Its FILL is written
     inline by simple-select.js:2062 (`style="background: <metal colour>"`)
     and is the metal signal, so it is left alone; only the box is corrected
     (simple-select.css:747 draws a 9px radius on a 20px box). */
  #simple-select-quiz .quiz-image .metal_dropdown_ssq > .metal_current_option > .select_metal_option > span.metal_icon {
    border-radius: 50%;
  }

  /* 14468:36986 — glyph frame 20x20 with a vector that FILLS it (19.71 of 20).
     The shipped svg is viewBox "0 0 50 50" with the artwork bounded at
     8.25,8.25 33.5x33.5, i.e. 33.5/50 = 0.67 of the box is ink. Painting 20px
     of INK therefore needs a 20 / 0.67 = 29.85px box. The box is centred in
     the 20px slot above, so the overflow is the svg's own transparent padding
     (4.93px per side) and the INK still starts at x=218, flush with the metal
     swatch on the pill above it. Measured ink before: 13.4px. */
  #simple-select-quiz .quiz-image .shape_dropdown_ssq > .shape_current_option > .select_shape_option > span.icon > svg {
    width: 29.85px;
    height: 29.85px;
    flex: 0 0 auto;
  }

  /* Label. 14/16 ls -0.21 weight 400 is already pinned; the case is
     SMALL_CAPS_FORCED on 14468:36981 / 36988, which `text-transform:
     uppercase` defeats (capitals render full height and "14K WHITE GOLD"
     then measures 98px inside a 123px box, next to a 20px glyph and a
     4px chevron). all-small-caps is the CSS spelling of SMALL_CAPS_FORCED. */
  #simple-select-quiz .quiz-image .metal_dropdown_ssq > .metal_current_option > .select_metal_option,
  #simple-select-quiz .quiz-image .shape_dropdown_ssq > .shape_current_option > .select_shape_option {
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 16px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);
    text-transform: none;
    font-variant-caps: normal;   /* was all-small-caps -- the pill shows a NAME */
    font-feature-settings: "c2sc" 1, "smcp" 1;
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  /* ===========================================================================
     2.2 STONE DETAILS, MOBILE — board C `14468:36206` (SPACING2 §C)

     This is `.ssq_picked_selection.preview_stone`, the block drawn once a stone
     has been picked (the advanced-search result tap lands here). Before this
     addendum it carried NO redesign rule at all. MEASURED at 390:

       content column      x=11  w=368          board x=12 w=366
       title -> price gap  0.6                  board 6
       title block -> img  5                    board 10
       main image          368 x 290            board 366 x 330
       thumbs              100 x 79.2, gap 10,  board 52 x 52, gap 8,
                           centred                    left-aligned at x=12/72
       spec rows           46.4 tall, pitch 46.4, board 32 tall, gap 16,
                           gap 0                      pitch 48
       spec values         x = 54 / 42 / 53 /   board x = 140 on EVERY row
                           59 / 82 (inline flow)      (120 label column + 8)
       spec label weight   700                  board 400

     The footer is a pinned bar that overlaps the body (SPACING2 §C.2); the
     129px of clearance it needs is already on #simple-select-quiz above.
     =========================================================================== */

  #simple-select-quiz .ssq_picked_selection {
    display: flex;
    flex-direction: column;
    /* `Frame 1171276486` padding 10 / 12 / 0 / 12. The block carries a 1px
       border on all four sides from the base sheet; with it live the content
       column measured x=13 w=364 against the board's x=12 w=366, so the two
       side edges are zeroed and the bottom rule is left alone.
       The board's gaps are 6 / 10 / 4-plus-padding, not one number, so they
       are expressed per block below rather than as a single `gap`. */
    gap: 0;
    padding: 10px 12px 0;
    border-left: 0;
    border-right: 0;
    /* MEASURED at 390: with the base sheet's `border: 1px solid var(--pearl-dark)`
       (simple-select.css:951) still live on the TOP edge, every child of the panel
       painted ONE pixel below its board position -- 2.2 `.rb_ys_line` at 71 for a
       board 70, and on 2.4 the whole column (YOUR STONE 363/362, the headline row
       386/385, the hero 415/414, the thumbs 769/768, the spec block 838/837). The
       two side borders were already zeroed for the same reason; the top one was
       missed, and it is a single origin error, not six. Neither board draws a rule
       here (14468:36207 and 14468:36311 carry no stroke), so it goes. The BOTTOM
       border is deliberately left alone -- see the note above. */
    border-top: 0;
    box-sizing: border-box;
  }
  /* CHECK 60: the two mobile boards do NOT share a content width. 2.2's rows
     (14468:36249) are 366 wide at board x=12 -- the padding above. 2.4's body
     (14468:36311) is 345.5 wide at board x=22, and its spec rows
     (14468:36333) inherit that. MEASURED before this rule: the 2.4 rows were
     [12,*,366] on both states, 10px left of and 20.5 wider than the board.
     390 - 22 - 22.5 = 345.5. */
  /* ...AND ABOVE 390 IT HAS TO CENTRE LIKE EVERYTHING ELSE ON THE SCREEN.
     Owner, on a 430pt phone in the stone flow: *"alignment is still off"* --
     YOUR STONE, the stone photo and the stone's spec rows all starting a score
     of pixels LEFT of the Ring Details bar and the ring card above them.

     Every other block on this screen is `min(346px, 100vw - 44px)` with auto
     margins: a 346 column that CENTRES once the viewport is wider than 390, the
     width the boards are drawn at. This one was a flat 22/22.5 gutter instead,
     so it alone kept growing. MEASURED in the stone flow on the stone step:

                      390                       430
       details bar    x 22  w 346               x 42  w 346
       ring card      x 22  w 346               x 42  w 346
       continue CTA   x 22  w 346               x 42  w 346
       YOUR STONE     x 22  w 345.5             x 22  w 385.5   <-- 20 adrift

     At 390 the two idioms agree to within the board's own half pixel, which is
     why this never showed on the 390 frame it was measured against.

     Same cap, written as padding so the block's own border and background still
     run full-bleed: `max(gutter, (100% - 346px) / 2)`. The 390 numbers are the
     floor of each max, so that frame is unchanged to the pixel -- 22 and 22.5
     are still what it gets -- and from 390 up the content column centres on 346
     with the card. The idiom is already in this sheet (2.1's `padding: 16px
     max(22px, calc((100% - 346px) / 2)) 6px`). */
  #simple-select-quiz.rb-stone-held .ssq_picked_selection {
    padding-left: max(22px, calc((100% - 346px) / 2));
    padding-right: max(22.5px, calc((100% - 346px) / 2));
  }

  /* `Frame 38795` title row: name 14468:36213, price 14468:36214, gap 6 */
  #simple-select-quiz .ssq_picked_selection #preview_confirm_type {
    order: 1;
    margin: 0;
    font-family: var(--rb-font-display);
    font-weight: 300;
    font-size: 18px;
    line-height: 24px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);
  }
  /* simple-select-quiz.php:416 writes `style="font-weight: 900"` INLINE on this
     span, so !important is the only thing that reaches it. 14468:36213 is
     Canela 300. */
  #simple-select-quiz .ssq_picked_selection #preview_confirm_type > span {
    font-weight: 300 !important;
  }
  /* simple-select-quiz.php:417 writes `margin-top:2px; margin-bottom:5px`
     INLINE on this node; the 6px gap below cannot be measured until those two
     are cleared, and an inline declaration can only be beaten by !important.
     Nothing else in this sheet uses it. */
  #simple-select-quiz .ssq_picked_selection #preview_confirm_price {
    order: 2;
    margin: 6px 0 0 !important;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 16px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);
  }

  /* `Frame 38796` 14468:36217 — image then thumbs, itemSpacing 10 */
  #simple-select-quiz .ssq_picked_selection .quiz-handpicked-image {
    order: 3;
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* 14468:36210 (title row) -> 14468:36217, itemSpacing 10.
       Below: `Frame 1171276485` pads 10 at the bottom and the body frame then
       adds its own itemSpacing 4 before the next block = 14. */
    margin-top: 10px;
    margin-bottom: 14px;
  }
  /* 14468:36218 — 366 x 330, IMAGE scaleMode FILL, radius 4, clips */
  #simple-select-quiz .ssq_picked_selection .quiz-handpicked-image > img {
    display: block;
    width: 100%;
    height: 330px;
    object-fit: cover;
    border-radius: var(--rb-radius-sm);
    background: var(--rb-surface-card);
  }
  /* 14468:36221 — thumbs 52x52 at x=12 and x=72, itemSpacing 8, LEFT aligned.
     Fluid guard (HARNESS trap 6): a fixed 52 next to a fixed 8 is safe here
     because 2 x 52 + 8 = 112 fits the 276px column a 320 viewport leaves. */
  #simple-select-quiz .ssq_picked_selection .quiz-image-video-thumbs {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    gap: 8px;
    margin: 0;
  }
  #simple-select-quiz .ssq_picked_selection .quiz-image-video-thumbs > .quiz_image_thumb,
  #simple-select-quiz .ssq_picked_selection .quiz-image-video-thumbs > .quiz_video_thumb,
  #simple-select-quiz .ssq_picked_selection .quiz-image-video-thumbs > .quiz_video_thumb > img {
    flex: 0 0 52px;
    width: 52px;
    height: 52px;
    box-sizing: border-box;
    object-fit: cover;
    border-radius: var(--rb-radius-sm);
  }
  /* 14468:36222 — selected thumb, 1px #27423B INSIDE (desktop uses 1.5) */
  #simple-select-quiz .ssq_picked_selection .quiz-image-video-thumbs > .quiz_image_thumb.active {
    border: var(--rb-stroke) solid var(--rb-brand-green);
  }
  /* [Flow 3] 14514:41542 — the INACTIVE thumb carries a VISIBLE 1.5px #FAF3ED
     inside stroke. 3.2's equivalent hides the same stroke and 3.5 and the
     setting PDP (14514:39692-39697) both draw it, so two screens against one --
     and it is what keeps two tiles 8px apart from reading as one strip.
     MEASURED before: no border on `.quiz_video_thumb` at all.
     Scoped to the stone-first root: the Flow-2 stone panel is a different
     board and this pass does not own its answer. */
  section#simple-select-quiz.rb-stone-first .ssq_picked_selection .quiz-image-video-thumbs > .quiz_video_thumb,
  section#simple-select-quiz.rb-stone-first .ssq_picked_selection .quiz-image-video-thumbs > .quiz_image_thumb:not(.active) {
    border: 1.5px solid var(--rb-surface-page);
  }
  /* ...and 1.5 is not something a BORDER can draw. MEASURED: Chrome floors
     `border-width` to whole device pixels, so at DPR 1 `border: 1.5px` computes
     to `1px` -- a probe div set to 1.5px and to 1.51px both reported
     `borderTopWidth: "1px"` -- which is why this stroke has been shipping a
     pixel thin on every non-retina screen while reading correct in the source.
     `box-shadow` spread is NOT snapped (the same probe kept `1.5px`), so the
     ring is painted with one.

     It goes on a pseudo-element rather than on the tile itself because the
     tile's 52x52 <img> would cover an inset shadow painted in the tile's own
     background layer; a positioned ::after paints after the image. The border
     above is kept as the LAYOUT box -- it is what insets the image by 1.5 so
     the stroke reads as INSIDE -- and the shadow is drawn over the border's
     snapped 1px, in the same colour, so the two cannot disagree.

     `.quiz_image_thumb` is an <img>, a replaced element with no pseudo-element
     box, so it keeps the border alone: 1.5 on retina, 1 below. Said rather
     than hidden. */
  section#simple-select-quiz.rb-stone-first .ssq_picked_selection .quiz-image-video-thumbs > .quiz_video_thumb {
    position: relative;
    /* the ring is the ::after below; a border here would inset the image and
       double the stroke. An INSIDE stroke overlays the photo, it does not
       shrink it. */
    border: 0;
  }
  section#simple-select-quiz.rb-stone-first .ssq_picked_selection .quiz-image-video-thumbs > .quiz_video_thumb::after {
    content: "";
    position: absolute;
    /* no border on the tile, so the padding box IS the 52x52 border box and
       `inset: 0` puts the ring exactly on the board's stroke line. */
    inset: 0;
    border-radius: inherit;
    box-shadow: inset 0 0 0 1.5px var(--rb-surface-page);
    pointer-events: none;
  }

  /* Spec list 14468:36249 — VERTICAL, itemSpacing 16, padding 21 / 0 / 21 / 0 */
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion {
    order: 4;
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 21px 0;
  }
  /* Row 14468:36250 — h 32 = 24 of content + padding-bottom 8, 1px bottom
     rule #E4DED8 INSIDE (the rule is already on .accordion-row in the base
     sheet; only the padding and the row's own height are corrected here). */
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .accordion-row {
    padding: 0 0 8px;
  }
  /* CHECK 21: on BOTH mobile boards the pitch is 48, 48, 48, then 46, because
     the Certificate row (14468:36268 / 14468:36352) is 30 tall, not 32 -- it
     drops the `Frame 1171276145` wrapper and its label column is a direct
     child. MEASURED before this rule: a flat 48 on both states, so the 46 was
     never produced. The 2px comes off the row's padding-bottom rather than its
     height, so an OPENED row still grows with its body. `.rb_row_cert` is a
     hook on the markup, not `:nth-child`, so the pitch survives a row being
     added or reordered. */
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .accordion-row.rb_row_cert {
    padding-bottom: 6px;
  }
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .accordion-row > button.accordion-title {
    display: flex;
    align-items: center;
    gap: 8px;                  /* mobile itemSpacing 8 (desktop uses 16) */
    width: 100%;
    /* Row 14468:36250 is 32 tall with padding-bottom 8 and a 1px INSIDE bottom
       stroke, so the content box is 32 - 8 - 1 = 23 and the pitch is 48. */
    min-height: 23px;
    padding: 0 18px 0 0;       /* clears the 10px chevron + 8px of air */
    margin: 0;
    text-align: left;
    font-family: var(--rb-font-body);
    letter-spacing: var(--rb-ls-tight);
  }
  /* Label column is 120 on EVERY board and every breakpoint (SPACING2 §E),
     which is what puts the value at x = 12 + 120 + 8 = 140 on all five rows.
     Expressed as a fixed basis that may shrink, so 320 does not wrap it. */
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .accordion-row > button.accordion-title > span.att_label {
    flex: 0 0 auto;
    width: auto;
    min-width: 120px;          /* a FLOOR, not a cap: every real label is far
                                  under 120 so the value still starts at x=140
                                  on all five rows, while the value-less
                                  "Details and Dimensions" row (132px of label)
                                  stays on one line instead of wrapping */
    font-weight: 400;          /* product-single.css:1307 bolds it */
    font-size: 14px;
    line-height: 19px;
    color: var(--rb-text-secondary);
  }
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .accordion-row > button.accordion-title > span:not(.att_label) {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 400;
    font-size: 14px;
    line-height: 22px;         /* mobile value line-height is 22, label 19 */
    color: var(--rb-text-primary);
  }
  /* Chevron 14468:36255 — 10 x 5, flush to the column's right edge (x=368 in
     a column that ends at 378). accordion.css:23 draws it absolutely at
     24x24 / right:10 / top:18, which no longer suits a 24-tall row. */
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .accordion-row > button.accordion-title::after {
    top: 50%;
    right: 0;
    width: 11px;
    height: 6px;
    margin-top: -3px;
    /* accordion.css:23 points this at a 24x24 SQUARE glyph; squashing that to
       10x5 renders as a dash. icon-chevron-down-10.svg is an 11x6 box whose
       painted path is exactly the board's 10 x 5. */
    background-image: url('../../../assets/media/ringbuilder/icon-chevron-down-10.svg');
    background-size: 11px 6px;
    background-position: center;
    background-repeat: no-repeat;
    /* ...AND IT TURNS OVER WHEN THE ROW OPENS.
       Owner, about this slide: *"arrows are not rotating 180 degrees on
       expanding the section -- fix this wherever this is happening."*

       There was no open-state rule at all here: the row swapped its panel in
       and the chevron went on pointing down, so nothing on the header said the
       section was open. The page-builder accordion this markup borrows from
       answers the same question by swapping the glyph for a MINUS -- correct
       where the closed glyph is a PLUS (the Product Details / Shipping rows,
       MEASURED as `plus-icon.svg`), and wrong here, where it is a chevron.
       A first pass that rotated every `.accordion-row` made those plus/minus
       rows identical in both states; this is scoped to the chevron ones.
       260ms matches the stone-card disclosure chevron a few hundred lines up,
       so the two read as the same control. */
    transform-origin: 50% 50%;
    transition: transform 260ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .accordion-row.opened > button.accordion-title::after {
    transform: rotate(180deg);
  }
  @media (prefers-reduced-motion: reduce) {
    #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .accordion-row > button.accordion-title::after {
      transition: none;
    }
  }

}

/* =============================================================================
   ADDENDUM 2 — MOBILE, round 2. Two nodes the round-1 rules reached but did not
   actually change, both re-measured on dev-0 at 390 before being touched.
   Additive: nothing above is deleted or reordered, and nothing here sets
   `display` on a node simple-select.js shows/hides.
   ============================================================================= */

@media (max-width: 991px) {

  /* ---------------------------------------------------------------------------
     `Frame 38796` 14468:36217 — VERTICAL, itemSpacing 10, 366 x 392
     = main image 330 (14468:36218) + 10 + thumb strip 52 (14468:36221).
     Re-read from the REST API today: itemSpacing 10, height 392.

     MEASURED at 390 BEFORE this rule:
       .quiz-handpicked-image   12,938  366 x 382   display: BLOCK, gap 10px
       > img                    12,938  366 x 330
       > .quiz-image-video-thumbs 12,1268 366 x 52  -> gap 0, not 10

     Why the round-1 `display: flex; gap: 10px` never fired: the node is
     `<div class="quiz-handpicked-image d-block d-lg-none">`
     (simple-select-quiz.php:419) and bootstrap's `.d-block { display: block
     !important }` wins, so the flex `gap` is inert. On top of that
     simple-select.js calls `$('.quiz-handpicked-image').show()/.hide()` in ten
     places (js:1242, 1531, 1573, 1658, 1924, 1983, 1991, 2000, 2384 ...), which
     writes an INLINE display. Forcing `display: flex !important` from here would
     therefore beat jQuery's `.hide()` and pin the block permanently visible —
     exactly the trap that made both drawer glyphs paint at once. So the gap is
     re-expressed as a margin on the second child, which is honoured in block
     flow AND in flex, and the now-redundant flex `gap` is zeroed so the two can
     never add up to 20 on whichever path leaves the box as a flex container. */
  #simple-select-quiz .ssq_picked_selection .quiz-handpicked-image {
    gap: 0;
  }
  #simple-select-quiz .ssq_picked_selection .quiz-image-video-thumbs {
    /* itemSpacing 10 on 14468:36217. The strip's sibling above is the 330px
       image, whose margins are 0, so nothing collapses into this. */
    margin-top: 10px;
  }

  /* ---------------------------------------------------------------------------
     `Round icon` 14468:36980 — the metal swatch on the summary pill.
     REST-verified today: 20 x 20, cornerRadius 20, fill `visible: false`
     (NOT painted), stroke 3px #d0d0d0 with `strokeAlign: INSIDE`. It is a
     RING with a hollow centre, not a disc. Note the board's stroke colour
     #d0d0d0 is exactly the live 14k-white-gold swatch colour, so the ring is
     the metal signal itself, not a neutral outline.

     MEASURED at 390 BEFORE this rule:
       .metal_icon  218,222  20 x 20  background rgb(208,208,208)
                    border-radius 50%, border "0px none", box-shadow none
       inline style: `background: rgb(208,208,208) ...` — written by
       simple-select.js:2062, which copies the source swatch's computed
       background so the colour tracks the chosen metal.

     That inline colour must stay (it is the only place the metal colour comes
     from) and an inline declaration cannot be overridden without !important, so
     the centre is removed with a mask instead of by repainting: the element
     still carries the metal colour edge to edge, and the mask keeps only the
     outer 3px of it. Inner radius 7 = 10 - 3, i.e. `strokeAlign: INSIDE` — the
     20px box and the pill's 6px glyph/label gap do not move. Where `mask` is
     unsupported the swatch simply stays the filled disc it is today. */
  #simple-select-quiz .quiz-image .metal_dropdown_ssq > .metal_current_option > .select_metal_option > span.metal_icon {
    /* THE RING IS 21% OF THE BOX -- 14684:49640.
       Owner, twice: *"the ring must be thicker, the icon looks like you chickened
       out on that one"*, then *"the metal icon is too thick now"* with that node.

       Both reports were right, and a FIXED pixel ring is why. The board draws a
       19 circle with a 4 INSIDE stroke, so the ring is 4/19 of the diameter --
       but this icon MEASURED 17, not 19. At the original flat `7px` hole that
       came out 1.5px (too thin); at a flat 4px it came out 4 on a 17 box, which
       is a FATTER ring than the board's because the box is smaller (a 9px hole
       against the board's 11).

       Stated as the board's RATIO instead, so the swatch is the frame's shape at
       whatever size it renders: 4/19 of the DIAMETER, i.e. 3.6 at 17 and 4.2 at 20.

       `closest-side` IS LOAD-BEARING. Without a size keyword a radial gradient
       sizes to `farthest-corner`, and its colour stops are then percentages of
       THAT -- 12.02px on a 17 box, not the 8.5 radius. MEASURED, `calc(50% - 4px)`
       against 12.02 left a 2px hole and painted a ring half again as thick as the
       board's. `closest-side` makes 100% the radius, so 58% is the hole and the
       remaining 42% of the radius is the board's 21% of the diameter. */
    -webkit-mask-image: radial-gradient(circle closest-side at 50% 50%, transparent 0 58%, #000 58%);
            mask-image: radial-gradient(circle closest-side at 50% 50%, transparent 0 58%, #000 58%);
  }

}

/* =============================================================================
   ADDENDUM 3 — MOBILE, round 3. The two blocks the mobile 2.2 board carries
   that the build has NO NODE for: the trust row `14468:36224` and the wishlist
   heart `14468:36215`.

   MEASURED on dev-0 at 390, after advanced search -> first card -> ADD TO RING
   (the state the boards call `2.2 Stone details`), BEFORE this addendum:

     .ssq_picked_selection        0,871    390 x 788   display flex, position relative
     > .close_picked_selection  361,877     24 x 20.5  position ABSOLUTE, top 5 right 5
     > #preview_confirm_type     12,882    366 x 24
     > #preview_confirm_price    12,912    366 x 16    (gap 6   — board 6   OK)
     > .quiz-handpicked-image    12,938    366 x 392   (gap 10  — board 10  OK)
     > .diamond_atts_accordion   12,1344   366 x 314   (gap 14  — board 14  OK)

   i.e. the rhythm of every block that EXISTS is already on the board; what is
   missing is two blocks. `.pdp-trust-row` IS in the document — it is the PDP's
   own row (da-general.php:824), it lives in `.single_variation_wrap` and it
   measures 18px tall on the product page — but it is in a different subtree
   from `.ssq_picked_selection` and CSS cannot move a node between subtrees.
   Nothing inside the quiz contains the string "Insured Shipping", and there is
   no heart anywhere in `.ssq_picked_selection`.

   So the two nodes below need MARKUP in simple-select-quiz.php, which this
   agent does not own. The rules that follow are written against the exact
   markup named in the report, are inert until that markup lands, and were
   deployed and re-measured with it absent to prove they change nothing today.

   REST-verified geometry (file Ex10uQ9OY3OuzSPi4g2hPb, board origin 31053 /
   -21284):
     trust row  `14468:36224`  x 12 y 569  351 x 25, SPACE_BETWEEN
       item 1   `14468:36227`  x 12  w 109   icon 17x17 at y 573, label x 31 w 90
       item 2   `14468:36235`  x 142 w 96    label x 161 w 77
       item 3   `14468:36242`  x 259 w 104   label x 278 w 85
       resolved gaps 21 / 21, icon->label 2, all ink #3e3c39
     heart      `14468:36215`  x 342 y 116  36 x 36 frame, fill #ffffff
                `visible: false` (so: transparent hit area)
       vector   `14468:36216`  x 356 y 116  22 x 20, stroke #3e3c39 1px, NO fill
                -> the glyph is flush to the TOP-RIGHT of its 36x36 hit area,
                   right edge 378 = the content column's right edge.
   ============================================================================= */

@media (max-width: 991px) {

  /* ---------------------------------------------------------------------------
     3.1 The title column is 318, not 366 — `14468:36211` is 318 wide with
     `layoutGrow: 1` and the 36-wide heart sits at x=342, i.e. 12 of air then
     36 of heart. Reserving that slot is correct with or without the heart node,
     so it is NOT guarded on `:has()`.

     Fluid (HARNESS trap 6): the 48 is fixed (36 heart + 12 gap) and the column
     is the percentage, so it is written as `100% - 48px`, never as a fixed 318.
     At 390 that resolves to the board's 318; at 320 it is 248, and the longest
     live headline ("Lab Created Diamond", Canela 300 18px) is ~165 wide, so it
     does not wrap at either end. */
  #simple-select-quiz .ssq_picked_selection #preview_confirm_type,
  #simple-select-quiz .ssq_picked_selection #preview_confirm_price {
    width: calc(100% - 48px);
  }

  /* ---------------------------------------------------------------------------
     3.2 Trust row `14468:36224` — 351 x 25 between the image frame and the
     spec list, 4 below the one and 4 above the other.

     `.ssq_picked_selection` is a flex column whose children carry explicit
     `order` (1 type, 2 price, 3 image, 4 accordion), so a node dropped into
     the markup between the image and the accordion would default to `order: 0`
     and jump to the TOP of the panel. `order: 3` puts it level with the image
     frame, and equal-order items keep document order — image, then trust row,
     then the order-4 accordion. This is why the markup must sit AFTER
     `.quiz-handpicked-image` in the source.

     The 14px below the image frame is already on `.quiz-handpicked-image`
     (10 of `14468:36208` bottom padding + the body frame's itemSpacing 4), so
     only the 4 below this row is set here.

     Width 351 is the board's FIXED width inside the 366 column — a real 15px
     shortfall, not a rounding artefact (CHECKLIST2 #80). `min()` keeps it from
     overflowing a narrower column. `flex-wrap: wrap` is the 320 guard: the
     three items are `nowrap` text and measure ~340 together at 14px, which
     does not fit the 296px column a 320 viewport leaves, so the third item
     drops to a second line there instead of being squeezed or clipped. At 390
     they fit on one line and `space-between` resolves the board's 21px gaps. */
  #simple-select-quiz .ssq_picked_selection .rb_stone_trust {
    order: 3;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    column-gap: 6px;
    row-gap: 4px;
    width: min(351px, 100%);
    min-height: 25px;
    margin: 0 0 4px;
    padding: 0;
  }
  /* item `14468:36227` — icon 17x17, itemSpacing 2, label 14/25 #3e3c39.
     (The PDP's own `.pdp-trust-item` is 13px with an 18px icon and a 5px gap;
     this is the mobile board's 14/17/2, scoped to the quiz.) */
  #simple-select-quiz .ssq_picked_selection .rb_stone_trust .pdp-trust-item {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    margin: 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 25px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
    white-space: nowrap;
  }
  #simple-select-quiz .ssq_picked_selection .rb_stone_trust .pdp-trust-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 17px;
    width: 17px;
    height: 17px;
    color: var(--rb-text-secondary);
  }
  #simple-select-quiz .ssq_picked_selection .rb_stone_trust .pdp-trust-icon > svg {
    display: block;
    width: 17px;
    height: 17px;
  }

  /* ---------------------------------------------------------------------------
     3.3 Wishlist heart `14468:36215`.

     The board puts the 22x20 glyph flush to the top-right of the content
     column (right edge 378 = 390 - 12) and level with the top of the title
     row, inside a 36x36 transparent hit area. `.ssq_picked_selection` is
     already `position: relative` in the live build, so the hit area is placed
     against it: an absolute child is offset from the PADDING box, so the
     panel's own `padding-top: 10` is the whole offset — `top: 10px` measured
     the glyph's top edge onto the headline's top edge (both 882 at 390), and
     `right: 12px` puts its right edge on the column's right edge (378).

     COLLISION, and it is real — REPORTED, NOT DECIDED HERE: the build has a
     mobile-only close control, `.close_picked_selection`, `position: absolute;
     top: 5; right: 5`, measured 361,877 24 x 20.5. It lands on top of the
     glyph the board puts at 356..378 x 882..902. The 2.2 board has NO close
     control at all (its header is the `Setting details` bar `14468:36297` and
     its footer already carries `Continue browsing` `14468:36309`), so the
     design never had to resolve this.

     Both of the CSS-only ways out were built and MEASURED with the markup
     injected at 390, and both are worse than the board: moving the close to
     `left: 5px` puts the X on the first letter of the headline (headline box
     12..330 x 882..906, close 5..29 x 877..897.5), and moving the heart left
     of the close puts the glyph at 333..355 instead of the board's 356..378.
     So the heart is placed exactly where `14468:36215` puts it and the close
     control is left exactly as it is; which of the two moves — or retiring the
     close control, which is this sheet's recommendation — is a design call for
     whoever lands the markup. `display` is not touched either way
     (HARNESS trap 7). */
  #simple-select-quiz .ssq_picked_selection .rb_stone_heart {
    position: absolute;
    top: 10px;
    right: 12px;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: flex-start;
    justify-content: flex-end;
    padding: 0;
    margin: 0;
    border: 0;
    background: none;          /* frame fill #ffffff is `visible: false` */
    cursor: pointer;
    z-index: 2;
    color: var(--rb-text-secondary);
  }
  #simple-select-quiz .ssq_picked_selection .rb_stone_heart > svg {
    display: block;
    width: 22px;
    height: 20px;
    fill: none;
    stroke: currentColor;      /* `14468:36216` stroke #3e3c39, 1px, no fill */
    stroke-width: 1;
  }
}

/* =============================================================================
   2.2 / 2.4 STONE PANEL STATES — MOBILE (<=991px)
   2.2 STONE DETAILS      14468:36206  (spec block 14468:36249)
   2.4 BACK TO STONE STEP 14468:36310  (stone stack 14468:36321, spec 14468:36333)

   WHAT WAS WRONG, MEASURED ON DEV-0 AT 390x844
   --------------------------------------------
   After Add to Ring the column still carried the four `.ssq-simple-selection`
   cards at x=22, y 555 / 687 / 751 / 815 and `.rb_stones_head` at (22,507),
   with `.ssq_picked_selection.preview_stone` pushed to [0,871,390,788] below
   them. Board 2.4 puts `14468:36321` — "YOUR STONE", the descriptor + "+ $500"
   row, the stone image and the spec block — there instead, and draws none of
   the four stone-type cards.

   Same mechanism as desktop: `.ssq_all_stone_options` is pinned
   `display: flex !important` above so jQuery's `.hide()` cannot reach it. The
   override is scoped to `#simple-select-quiz.rb-stone-panel`, two classes on
   the id element against the base rule's one, and the class is written only by
   the stone-flow block at the foot of diamond-search.js.

   The existing mobile `.ssq_picked_selection` rules (ADDENDUM 1 above) already
   build 2.2 to board C. This section adds the STATE split — what 2.4 shows that
   2.2 does not and vice versa — and leaves every measurement that was already
   correct alone.
   ============================================================================= */

@media (max-width: 991px) {

  #simple-select-quiz.rb-stone-panel .ssq_all_stone_options,
  #simple-select-quiz.rb-stone-panel .simple-quiz-carat-filter,
  #simple-select-quiz.rb-stone-panel .rb_stones_head,
  #simple-select-quiz.rb-stone-panel .ssq_all_stone_confirmations {
    display: none !important;
  }

  #simple-select-quiz.rb-stone-panel .ssq_picked_selection {
    display: flex !important;
  }

  /* --- 4.2.2 title block 14468:36322 — 345.5 x 42, gap 4 ------------------
     "YOUR STONE" 14468:36323 is Canela 300 18/19, UPPER, CENTRE/CENTRE — NOT a
     scaled copy of the desktop node (CHECK 76, which is 24/19 and LEFT). */
  #simple-select-quiz .ssq_picked_selection > .rb_ys_title {
    order: 0;
    margin: 0;
    font-family: var(--rb-font-display);
    font-weight: 300;
    font-size: 18px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: uppercase;
    text-align: center;
    color: var(--rb-text-primary);
  }
  /* 2.2 names the stone in 14468:36213 instead; that board has no heading. */
  #simple-select-quiz:not(.rb-stone-held) .ssq_picked_selection > .rb_ys_title { display: none; }

  /* 14468:36324 — SPACE_BETWEEN. R33: declared 0, RESOLVED 143.5 (the price
     lands at local x 303.5), so this is space-between and never a gap. */
  #simple-select-quiz .ssq_picked_selection > .rb_ys_line {
    order: 1;
    display: flex;
    flex-direction: column;          /* 2.2: name over price, itemSpacing 6 */
    margin: 0;
  }
  #simple-select-quiz.rb-stone-held .ssq_picked_selection > .rb_ys_line {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    margin-top: 4px;                 /* 14468:36322 itemSpacing 4 */
  }
  /* 14468:36325 / 36326 — FG 400 14/19, ls -0.21, case ORIGINAL, label ink for
     both halves (COPY3 3.3: build the string already cased, no transform). */
  #simple-select-quiz.rb-stone-held .ssq_picked_selection #preview_confirm_type,
  #simple-select-quiz.rb-stone-held .ssq_picked_selection #preview_confirm_type > span,
  #simple-select-quiz.rb-stone-held .ssq_picked_selection #preview_confirm_price {
    font-family: var(--rb-font-body) !important;
    font-weight: 400 !important;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: none;
    color: var(--rb-text-primary);
  }
  /* 14468:36325 is the LEFT half of a SPACE_BETWEEN pair and 36326 ("+ $500 ")
     is 42 wide at x325.5 -- the descriptor gets the rest of the 345.5 row, not
     half of it. MEASURED after the descriptor grew to carry the carat and the
     shape: `#preview_confirm_type span` 166.1x35, i.e. "0.50 Carat Round Lab
     Created Diamond" wrapped onto two lines inside a 172.8 flex share. */
  #simple-select-quiz.rb-stone-held .ssq_picked_selection #preview_confirm_type {
    flex: 1 1 auto;
    min-width: 0;
  }
  #simple-select-quiz.rb-stone-held .ssq_picked_selection #preview_confirm_price {
    /* `width: auto` is load-bearing: the node computes a 297.5px width from the
       base sheet, and `flex: 0 0 auto` resolves its basis FROM that width -- so
       pinning the flex alone squeezed the descriptor to its 48px min-content
       ("Created") and made it four lines. It has to hug its own "+ $700". */
    flex: 0 0 auto;
    width: auto;
    white-space: nowrap;
    margin: 0 !important;
    /* R33: 14468:36326 "+ $500 " resolves to local x 303.5 in a 345.5 row --
       it is the RIGHT half of a SPACE_BETWEEN pair. Both halves are flex
       children that split the row 172.8/172.8, so without this the price
       painted left-aligned at x=194.8 instead of ending flush at 367.5. */
    text-align: right;
  }

  /* --- 4.2.2 spec block 14468:36333 vs 3.2.3 14468:36249 ------------------
     CHECK 20 calls this "the single largest structural difference between the
     two mobile spec blocks": 2.2 pads 21 top and 21 bottom, 2.4 pads ZERO, so
     the 2.4 block starts flush under the image strip. The 21/21 is already set
     by ADDENDUM 1 for 2.2; only the 2.4 override is added here. */
  #simple-select-quiz.rb-stone-held .ssq_picked_selection .diamond_atts_accordion {
    padding: 0;
  }

  /* The Details & Dimensions body. Both mobile boards draw this row COLLAPSED
     and neither ships a body (COPY3 2: "Absent from both mobile boards"), but
     the row is a real disclosure in the build and throwing its content away
     would lose Polish / Symmetry / Fluorescence / Depth / Table / Ratio /
     Measurement on mobile entirely. It keeps the same 120 + 8 columns as the
     rows above it, so an opened body reads as part of the same table. */
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion #details-and-dimensions {
    padding: 12px 0;
  }
  #simple-select-quiz .ssq_picked_selection .rb_dd_row {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 0 0 16px;
    font-family: var(--rb-font-body);
    font-size: 14px;
    line-height: 22px;
    letter-spacing: var(--rb-ls-tight);
  }
  #simple-select-quiz .ssq_picked_selection .rb_dd_row:last-child { margin-bottom: 0; }
  #simple-select-quiz .ssq_picked_selection .rb_dd_row > .att_label {
    flex: 0 0 120px;
    width: 120px;
    font-weight: 400;
    color: var(--rb-text-secondary);
  }
  #simple-select-quiz .ssq_picked_selection .rb_dd_row > span:not(.att_label) {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--rb-text-primary);
  }
  /* The expander's own label carries no value node, so its 120 column has to be
     allowed to grow — otherwise "Details & Dimensions" wraps inside 120px. */
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .rb_dd_expander > button.accordion-title > span.att_label {
    flex: 0 0 auto;
    width: auto;
    min-width: 0;
  }

  /* --- 3.2.2 trust strip 14468:36224 — 351 x 25, SPACE_BETWEEN at local x
     0 / 130 / 247. R31: the DECLARED 30 is LARGER than the resolved 21, because
     3 items + 2 x 30 overflow 351 — so space-between, never a gap. 2.4 draws no
     trust strip. Labels are FG 400 14/25. ---------------------------------- */
  /* MEASURED: on mobile `.ssq_picked_selection` is NOT hidden on the bare STONE
     step -- it sits at [0,959.8,390,827] with its spec rows already painted --
     so the strip is shown ONLY in the 2.2 state rather than "hidden on 2.4",
     otherwise it appears on a screen no board draws it on. */
  #simple-select-quiz .ssq_picked_selection > .rb_trust_strip { display: none; }
  #simple-select-quiz.rb-stone-pdp .ssq_picked_selection > .rb_trust_strip {
    order: 3;
    display: flex;
    justify-content: space-between;
    align-items: center;
    list-style: none;
    margin: 14px 0 0;                /* 14468:36208 padBottom 10 + body gap 4 */
    padding: 0 15px 0 0;             /* 366 -> the board's 351 row */
    height: 25px;
  }
  #simple-select-quiz .ssq_picked_selection > .rb_trust_strip > li {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    color: var(--rb-text-secondary);
  }
  #simple-select-quiz .ssq_picked_selection .rb_trust_icon {
    display: block;
    width: 21px;
    height: 21px;
    flex: 0 0 21px;
  }
  #simple-select-quiz .ssq_picked_selection .rb_trust_icon svg { display: block; }
  #simple-select-quiz .ssq_picked_selection .rb_trust_label {
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;
    line-height: 25px;
    letter-spacing: var(--rb-ls-tight);
  }
  /* The spec block follows the trust strip on 2.2 (board order: stone block,
     trust strip, spec block) and sits directly under the image on 2.4. */
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion { order: 4; }

  /* --- the footer's link row 14468:36305 / 14468:36370 --------------------
     Both mobile boards put it in the footer stack DIRECTLY UNDER the primary
     CTA, 346 x 28, centred, no fill and no stroke, label underlined #27423B
     (CHECK 66). The nav is a row, so the slot is given the full width and
     forced onto its own line. */
  /* THE FOOTER ITSELF -- 14468:36298 (2.2) and 14468:36361 (2.4). Identical
     shells: 390 x 129 flush to the board bottom, AL VERTICAL gap 10, counter
     CENTER, pad 12/10/10/10, fill #FAF3ED, top stroke declared but
     `visible:false` (CHECK 72 -- mobile has NO footer rule). Inside,
     14468:36299 / 36362 is a 370x80 stack, gap 8: the 44-tall primary CTA over
     a 28-tall link row. 12 + 80 + 10 + 10 = 112 of 129, so 17px of safe-area
     slack falls at the bottom (CHECK 29).

     Mirrors the SIZE step's bar (section 8b) because it is the same frame
     family; it is written out rather than shared because the two selectors
     resolve on different states and the CTA width differs (2.2's 14468:36300
     is 370 FILL, 2.4's 14468:36363 is 346 FIXED). */
  #simple-select-quiz.rb-stone-panel:has(#ssq_select_stone.active) .ssq_bottom_nav {
    box-sizing: border-box;
    /* HEIGHT BY CONTENT, NOT THE BOARD'S 129.
       Owner, three times and finally: *"in the sticky section there's a gap
       between the last line and the bottom of the screen -- a lot of space
       wasted on the sticky ones, everywhere in the BYR flow on phone"*, and
       *"on the back-to-stone page there's a hell of a lot of space between the
       last content and the sticky bottom bar top."*

       MEASURED at 390 on the stone panel: the band 129 tall holding ONE child
       80 tall inside 12/10 of padding -- 102 of content in a 129 box, so 27px
       of the band is nothing at all, and it sits between the shopper's last
       line and the bottom of the screen. The earlier pass took 40% off the
       CLEARANCE above the band (24 -> 14, and 8 -> 5 here), which is why the
       gap above it now measures 5px and the complaint did not go away: the
       waste was never above the band, it was inside it.

       `height: auto` is safe precisely because nothing downstream hard-codes
       129 either: simple-select-redesign.js publishes `--rb-nav-reserve` from
       this band's RENDERED height, so the page's own bottom padding follows it
       down on its own. 14463:34704's 129 was an AL:VERTICAL frame with
       pad 12/10 and gap 10 -- a hug, drawn at the height its contents happened
       to need on that artboard, not a fixed rail. */
    height: auto;

    padding: 12px 10px 10px;
    border: 0;
    background: var(--rb-surface-page);
    visibility: visible;
    overflow: visible;
  }
  #simple-select-quiz.rb-stone-panel:has(#ssq_select_stone.active) .ssq_bottom_nav .sss-nav {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;     /* primary MIN -- the 17px falls below */
    gap: 8px;                        /* 14468:36299 itemSpacing */
    width: 100%;
    flex-wrap: nowrap;
  }
  /* Back and the two running totals are on neither board. Parked, never
     display:none'd -- simple-select.js:1245-1246 writes an INLINE display on
     `.setting_total` / `.full_total` / `.sss-next`, which a stylesheet rule
     cannot undo; taking them out of flow can. */
  #simple-select-quiz.rb-stone-panel:has(#ssq_select_stone.active) .ssq_bottom_nav .sss-prev {
    order: 1;
    visibility: hidden;
    width: 0;
    height: 0;
    padding: 0;
    margin: 0 0 -8px;                /* a zero-sized flex item still eats a gap */
    overflow: hidden;
  }
  #simple-select-quiz.rb-stone-panel:has(#ssq_select_stone.active) .ssq_bottom_nav p.setting_total,
  #simple-select-quiz.rb-stone-panel:has(#ssq_select_stone.active) .ssq_bottom_nav p.full_total {
    position: absolute;
    left: -9999px;
    top: 0;
    width: 0;
    height: 0;
    margin: 0;
    padding: 0;
    overflow: hidden;
    visibility: hidden;
  }
  /* 14468:36300 "ADD TO RING" 370x44 FILL / 14468:36363 "CONTINUE TO RING SIZE"
     346x44 FIXED. Same #27423B, same r=4, same 16/19 label -- CHECK 95, the
     relabelling is the whole visual signal that the stone is now held. */
  #simple-select-quiz.rb-stone-panel:has(#ssq_select_stone.active) .ssq_bottom_nav .sss-next {
    order: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    box-sizing: border-box;
    width: min(370px, calc(100vw - 20px));
    height: 44px;
    padding: 14px 0;
    margin: 0;
    border-radius: var(--rb-radius-sm);
    background: var(--rb-brand-green);
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-transform: uppercase;
    text-decoration: none;
    color: var(--rb-surface-page);
    visibility: visible;
  }
  #simple-select-quiz.rb-stone-held:has(#ssq_select_stone.active) .ssq_bottom_nav .sss-next {
    width: min(346px, calc(100vw - 44px));
  }
  #simple-select-quiz.rb-stone-panel:has(#ssq_select_stone.active) .ssq_bottom_nav .sss-next svg {
    display: block;
    width: 12px;
    height: auto;
    margin: 0;
    flex: 0 0 12px;
  }
  #simple-select-quiz.rb-stone-panel:has(#ssq_select_stone.active) .ssq_bottom_nav .sss-next svg path {
    stroke: var(--rb-surface-page);
    stroke-width: 1.25;              /* 14468:36303 / 36368 */
  }

  #simple-select-quiz .rb_stone_link_slot {
    display: none;
    order: 3;                        /* directly under the CTA, on the 8px gap */
    box-sizing: border-box;
    width: min(346px, calc(100vw - 44px));
    height: 28px;                    /* 14468:36305 / 36370 */
    margin: 0;
    padding: 0;
    text-align: center;
  }
  #simple-select-quiz.rb-stone-held:has(#ssq_select_stone.active) .rb_stone_link_slot,
  #simple-select-quiz.rb-stone-pdp  .rb_stone_link_slot { display: block; }
  #simple-select-quiz .rb_stone_link_slot > a {
    display: none;
    align-items: center;
    justify-content: center;
    gap: 3px;                        /* 14468:36305 itemSpacing 3 */
    height: 28px;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    text-decoration: underline;
    text-transform: none;
    color: var(--rb-brand-green);
    background: none;
    border: 0;
  }
  #simple-select-quiz.rb-stone-pdp .simple-select-heading .rb_stone_back_link { display: inline-flex; align-items: center; gap: 5px; }
  #simple-select-quiz:not(.rb-stone-pdp) .simple-select-heading .rb_stone_back_link { display: none; }
  #simple-select-quiz.rb-stone-held .rb_stone_link_slot > .rb_pick_other_link { display: inline-flex; }
  /* 14468:36307 — a bare 12.17px rule, 1px #27423B, left of the label. 2.4's
     "Pick a different stone" (14468:36372) has no rule at all. */
  /* AN ARROW, NOT A HYPHEN. The API reports `Vector 138` (14468:44493) as
     12 x 0 -- a flat bounding box -- and this was built literally, as a 12px
     rule with a border-top. Rendering the node at 4x shows what it actually is:
     a left arrow, "<- Continue browsing". A zero-height bbox on a stroked path
     is the shaft's extent, not the glyph. Drawn as an SVG background so the
     head and shaft stay one piece at any zoom. */
  #simple-select-quiz .rb_link_rule {
    display: block;
    width: 12px;
    height: 10px;
    border: 0;
    background: 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='M11.5 5H1M1 5L5 1M1 5L5 9' stroke='%2327423B' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / 12px 10px;
  }
  #simple-select-quiz.rb-stone-held .rb_stone_link_slot .rb_link_rule { display: none; }

  /* CHECK 94 on the mobile side. 14468:36206's direct children are
     36207 / 36277 / 36278 / 36281 / 36282 / 36298 -- there is NO progress bar
     on 2.2, exactly as on desktop 2.2. MEASURED before this rule: the bar
     painted at [24,144,342,40] with STONE / SIZE / ENGRAVING over the
     stone-details panel. 2.4 (14468:36310) keeps its bar (14468:44613), so
     this is scoped to `.rb-stone-pdp` only. */
  /* OWNER OVERRULES THE BOARD HERE. Owner, with a screenshot of this screen
     reached through advanced search: *"the progress bar goes missing"* / *"the
     progress bar is missing when gone through advanced natural diamond search,
     might be for lab diamonds too -- fix it."*

     The note above is still an accurate reading of 14468:36206 and 2.2 desktop:
     neither board draws a bar here. But this screen is reached mid-flow -- the
     shopper has a setting and has just chosen a stone, and the next thing they
     do is CONTINUE TO RING SIZE -- so losing the STONE / SIZE / ENGRAVING
     marker costs them their place. Shown again, and the board conflict is
     recorded rather than quietly resolved, so the designer can overrule back. */
  /* was: #simple-select-quiz.rb-stone-pdp .rb-progress-bar { display: none; } */

  /* The mobile-only close glyph is on NEITHER board, and it is destructive in
     a way no board sanctions: MEASURED, clicking it left the hash on
     `#slide3pdp` but made `#simple-select-quiz` itself invisible and tore the
     search down (visible `.result_grid_item_container` 100 -> 0,
     `#ssq_diamond_search.scrollTop` 1200 -> 0), landing the shopper on the
     plain product page. With the footer restored above, "Continue browsing"
     (14468:36309) is the board's escape from 2.2 and "Pick a different stone"
     (14468:36372) is 2.4's, so the glyph is removed from both states only. */
  /* `!important` because the node ships with bootstrap's `.d-block`, whose own
     `display: block !important` an author rule cannot outrank. MEASURED with
     the plain rule in place: the glyph still painted at [361,341,24,20.5]. */
  #simple-select-quiz.rb-stone-panel .ssq_picked_selection > .close_picked_selection {
    display: none !important;
  }

  /* ===========================================================================
     ROUND 3 -- 2.2 / 2.4 BOARD ALIGNMENT AT 390
     Boards: 2.2 = 14468:36206 (390x976), 2.4 = 14468:36310 (390x1122).
     BOTH boards draw the 46px iOS status-bar mock (14468:36285 /
     I14468:36377;14468:44591) that the build does not reproduce, so every
     board coordinate quoted below is converted: PAGE y = BOARD y - 46. That
     offset is what reconciles the chip (board 56 -> page 10), the 2.2 headline
     (board 116 -> page 70), the 2.4 back chip (board 64 -> page 18) and the
     2.4 tab rail (board 128 -> page 82) with the numbers measured on dev-0.
     =========================================================================== */

  /* --- 2.2 HAS NO "BUILD YOUR RING" BAND AND NO SETTING CARD --------------
     14468:36206's direct children are 36207 / 36277 / 36278 / 36281 / 36282 /
     36298. Its WHOLE header is 14468:36282 -- phone chrome plus the Ring
     Details chip, 106 board / 60 page tall. There is no 14463:33729 header
     band on it and no setting card anywhere on it.
     MEASURED BEFORE at 390: `.simple-select-heading` [0,0 390x80] and
     `.quiz-image.horizontal` [22,136 346x150] both painted, which started
     `.simple-select-slide.active` at 286 and put `.rb_ys_line` at 307 against
     the board's 70 -- 237px of header the board does not specify. The tab rail
     was already suppressed here (rule further down), so the suppression was
     exactly half applied. */
  #simple-select-quiz.rb-stone-pdp .simple-select-heading { display: none; }
  /* `!important`: simple-select.js writes an INLINE `display` on `.quiz-image`
     (it calls .show()/.hide() on it in the stone branch), and an inline style
     outranks any plain author rule. */
  #simple-select-quiz.rb-stone-pdp .quiz-image { display: none !important; }

  /* 14468:36297 sits at board [12,56 366x40] inside 14468:36282, whose L/R pad
     is 12 -- so page y=10 and flush with the SAME 12px gutter the 2.2 panel
     content below uses, not the 22 the 1.x header band uses.
     MEASURED BEFORE: [22,88 346x40] -- internally inconsistent too, since
     `.rb_ys_line`, the hero and the trust strip under it were all inset 12. */
  /* `width: auto` restores the full-bleed box this variant has always had --
     the rule above now sets a width, and without this the 12px inset would be
     measured against a 346 card instead of the column. */
  #simple-select-quiz.rb-stone-pdp .rb_details_bar { width: auto; margin: 10px 12px 0; }

  /* --- 2.4 HEADER CHIPS TOP-ALIGN AT PAGE y=18 ----------------------------
     I14468:36377;14468:44603 pads 18 at the top, and I...44604 puts BOTH chips
     at board y=64 = page 18, at the TOP of the 54-tall title row.
     MEASURED BEFORE: both at y=31, because `.simple-select-heading .col`
     centres them against the two-line title block in a [22,12 346x62] row.
     Only the two chips move; the title block stays centred, which is where the
     board's own -6 itemSpacing stack resolves to anyway.
     The fill is stated because the computed `background-color` read
     rgba(0,0,0,0) while I...44605 / I...44611 both fill #FAF3ED -- the exported
     glyph SVGs draw their own plate, but nothing guaranteed it. */
  #simple-select-quiz.rb-stone-held .rb_back,
  /* 2px, not 6. The comment below this used to read "header padTop 12 + 6 = the
     board's 18" -- but the container's top measures 16, not 12, so 6 put both
     chips at y22 against the board's 18. The H2 in the same row paints 22..39
     against Figma's 22..39 exactly, so the chips were the only things out of
     line with the title they sit level with. 16 + 2 = 18. */
  #simple-select-quiz.rb-stone-held .close_ssq,
  #simple-select-quiz.rb-stone-pdp .close_ssq,
  #simple-select-quiz.rb-stone-held .rb_back,
  #simple-select-quiz.rb-stone-pdp .rb_back {
    align-self: flex-start;
    margin-top: 2px;
  }
  #simple-select-quiz.rb-stone-held .close_ssq,
  #simple-select-quiz.rb-stone-pdp .close_ssq {
    background-color: var(--rb-surface-page);
  }
  /* ...AND ON EVERY STEP, SO THE CHIP DOES NOT JUMP BETWEEN THEM.
     Owner: *"the back button flies off on mobile when I click back to stone
     using the back button in the nav -- the back nav arrow flies up and
     disappears."*

     Nothing animates it; it is laid out twice. TRACED frame by frame through
     that tap: the chip sits at y33 on the step being left and y18 on the step
     being entered, and moves between them in one frame with no transition --
     which on a handset reads as the thing flinging itself upward.

     The 18 comes from the rule above, and the 33 is the default: the chip is a
     flex item in a row whose other child is the title BLOCK, so without
     `align-self` it centres against however many lines that block has, and the
     block is taller on some steps than others. The rule above only names
     `rb-stone-held` and `rb-stone-pdp`, so exactly the steps outside those two
     states kept the centred position.

     Top-aligned everywhere instead: 18 is the board's own number for this chip
     and it is the one position that does not depend on what the title happens
     to say. */
  #simple-select-quiz .simple-select-heading .rb_back,
  #simple-select-quiz .simple-select-heading .close_ssq {
    align-self: flex-start;
    margin-top: 2px;
  }
  /* THE 2.4 BACK CHIP IS GONE, AND WITH IT THE THING THAT "FLIES".
     Owner, twice: a screen-recording of the step change with *"the back button
     flies off on mobile -- it's like the back nav arrow flies up and
     disappears"*, and then the same chip circled on the first slide --
     *"this is not supposed to be there, that's obsolete, it came in during the
     advanced lab diamond search's stone addition and back-to-stone step"*.

     It used to be un-hidden here because board 14468:36310, "2.4 Back to stone
     step", paints it (I14468:36377;14468:44605, 24x24, r4, #FAF3ED) while the
     generic "step 1 has no back" rule hides every step-1 chip. Its destination
     was diamond-search.js's rbShowGrid() -- back to the advanced search with
     the held stone and every filter, sort and row intact.

     That destination has a control of its own on this screen now:
     `.rb_pick_other_link`, "Pick a different stone", is in the footer slot of
     both of the owner's screenshots and routes to the same search. Two controls
     for one move is what made the chip read as leftover.

     REMOVING IT ALSO REMOVES THE FLASH, which is the same defect seen from the
     other end. TRACED frame by frame at 45fps through a SIZE -> STONE tap: the
     chip is absent on size, paints for one frame as the stone slide lands, then
     goes -- because the hide is keyed on `.rb_at_first`, which
     simple-select-redesign.js writes on the `ssqChange` event, i.e. one beat
     AFTER the slide's own `.active` has already moved. A class that arrives late
     cannot hide something that is already painted.

     So the hide is keyed on the SLIDE instead. `:has(#ssq_select_stone.active)`
     re-evaluates with the slide's own class, so there is no window in which the
     chip is visible, on any journey -- no JS, no event, nothing to be late.
     `!important` because the base `.rb_at_first` rule it supersedes carries one.
     The behaviour in diamond-search.js is left bound: the element stays in the
     DOM (the header is a three-column row and collapsing the slot would slide
     the title off centre), it simply never shows on this step. */
  #simple-select-quiz:has(#ssq_select_stone.active) .rb_back {
    visibility: hidden !important;
    pointer-events: none !important;
  }

  /* ...AND ITS POSITION MUST NOT DEPEND ON A CLASS THAT FLICKERS.
     Owner: *"on phone, when I go forward and back to the stone slide, the back
     button kind of flies off -- it goes off."*

     The chip's placement is stated three rules up under `.rb-stone-held` /
     `.rb-stone-pdp`: `align-self: flex-start; margin-top: 2px`, which puts it at
     y18. Without those classes `.simple-select-heading .col` CENTRES it against
     the two-line title instead -- the rule's own note records the measurement,
     "MEASURED BEFORE: both at y=31". So the chip sits 13px apart in the two
     states.

     Those mode classes are re-stamped around every slide change: syncQuizChrome
     and rbApplyStoneFirstOpen both call rbStoneMode('held') / rbStoneMode(null)
     on the open and back transitions. Lose `rb-stone-held` for a single frame
     and the chip recentres 13px and snaps back -- which is the fly.

     Restating the placement on `.rb_at_first` alone makes the geometry identical
     whether or not the mode class is present at that instant, so a flicker in
     the class can no longer move the control. Deliberately NOT applied to
     `.close_ssq`: that one is visible on the setting-first journey too, where
     centring is correct and moving it would be a change nobody asked for. The
     back chip is hidden on that journey's step 1, so this is invisible there.

     NOT VERIFIED IN-BROWSER. Frame-by-frame at 390 the control never moved in
     the rig -- it stayed [22,33,24,24] and hidden through a forward/back cycle,
     and `rb_at_first` never cleared when the slide was driven directly, so the
     transition the owner sees does not occur headlessly. This is the mechanism
     the CSS makes possible, not a reproduction. */
  section#simple-select-quiz.rb_at_first .rb_back {
    align-self: flex-start;
    margin-top: 2px;
  }

  /* --- 2.4 TAB RAIL INSETS 22, NOT 24 -------------------------------------
     I14468:36377;14468:44613 is board [22,128 342x40] = page x=22, y=82, tabs
     at board x 22 / 139.3 / 256.7.
     MEASURED BEFORE: [24,82 342x30] with labels at 24 / 141 / 259 -- the rail
     sat 2px right of every other block on the screen, all of which inset 22,
     because `.rb-progress-bar` pads `2px 24px 6px`. Width 342 and y=82 were
     already right, so the 2 is moved from the left pad to the right one and
     the rail does not grow.

     Section A below re-pads this bar `2px 24px 6px` at the SAME specificity as
     an unqualified `#simple-select-quiz.rb-stone-held .rb-progress-bar` (both
     one id + two classes), and it is written LATER in this file, so it won the
     tie on order -- MEASURED, the rail stayed at x=24 with the shorter selector.
     Matching its `.quiz_options >` step makes this (1,3,0) and the win is on
     specificity, not on where either rule happens to sit. */
  #simple-select-quiz.rb-stone-held .quiz_options > .rb-progress-bar {
    padding-left: 22px;
    /* was 26 to hold a 342 content box. [Flow 3] 14514:41123's bar is 346 at
       x22 (36 + 10 + 78 + 10 + 78 + 10 + 78 + 10 + 36), so both insets are 22. */
    padding-right: 22px;
  }

  /* --- 2.4's HERO IS 344 TALL; 2.2's IS 330 -------------------------------
     This is NOT a board inconsistency to be averaged away: 14468:36329 (2.4)
     is [22,460 345.5x344] and 14468:36218 (2.2) is [12,163 366x330]. Two
     boards, two heights, both unambiguous. 330 stays the shared default above
     and 2.4 overrides it.
     The strip below follows from the same frame: 14468:36328 gaps 3 into
     14468:36330, a 66-tall frame whose 52-tall tiles (14468:36331) are centred
     in it, so the tile bottom lands at page 820; 14468:36321's itemSpacing 10
     then starts the spec block at 837. That is a 17px tile-bottom-to-first-row
     gap on 2.4 against 2.2's 14 (36221 bottom 509 -> 36224 top 523).
     MEASURED BEFORE: hero 330 and a 14px gap, which is exactly what put
     `.diamond_atts_accordion` at 821 instead of 837. */
  #simple-select-quiz.rb-stone-held .ssq_picked_selection .quiz-handpicked-image > img {
    height: 344px;
  }
  #simple-select-quiz.rb-stone-held .ssq_picked_selection .quiz-handpicked-image {
    margin-bottom: 17px;
  }

  /* --- 2.2 FAVOURITE CONTROL -- 14468:36215 ------------------------------
     36215 is a 36x36 frame right-aligned in the headline row 14468:36210
     (itemSpacing 12), page [342,70]. Its box ends at x=378, the 12px gutter's
     right edge -- hence `right: 0`. It does not exist on 2.4 (14468:36324 has
     no heart child), so it is held to `.rb-stone-pdp`.

     There is ONE heart on 2.2, not two. 14468:36219, the 44x44 overlay on the
     hero, carries `visible: false` in the file and is absent from the 1:1
     export; the markup that drew it has been removed (see the note in
     simple-select-quiz.php), so `.rb_fav_hero` no longer exists to style.

     Absolutely positioned rather than added as flex children: `.rb_ys_line` is
     a COLUMN on 2.2 (name over price, 14468:36212) and `.ssq_picked_selection`
     orders its children explicitly, so a new in-flow node would either stack
     under the price or default to order 0 and jump to the top of the panel.
     The 48px the title column already gives up (section 3.1 above, the
     `calc(100% - 48px)` that reserves 36 of heart + 12 of gap) is this slot,
     so nothing reflows to make room. */
  #simple-select-quiz.rb-stone-pdp .ssq_picked_selection > .rb_ys_line,
  #simple-select-quiz.rb-stone-pdp .ssq_picked_selection > .quiz-handpicked-image {
    position: relative;
  }
  #simple-select-quiz .rb_fav {
    display: none;                   /* 2.4 and every 1.x screen draw no heart */
    position: absolute;
    top: 0;
    right: 0;
    align-items: center;
    justify-content: center;
    padding: 0;
    margin: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  #simple-select-quiz.rb-stone-pdp .rb_fav { display: flex; }
  /* 14468:36215 -- the 36x36 tap target. The glyph 14468:36216 is NOT centred
     in it: the board puts the 22x20 vector at [356,116], i.e. flush with the
     frame's TOP edge and flush with its RIGHT edge (356 + 22 = 378 = the frame's
     right edge at 342 + 36). The build centred it, which measured [349,79] --
     7px left and 9px low of the board. A 36x36 target is kept for the tap area
     (the vector alone is under the 44px minimum), and the glyph is pinned into
     its corner instead. */
  #simple-select-quiz .rb_fav_line {
    width: 36px;
    height: 36px;
    align-items: flex-start;
    justify-content: flex-end;
  }
  /* 14468:36216 -- a 22x20 vector, stroke #3E3C39 w=1, no fill. */
  #simple-select-quiz .rb_fav > svg {
    display: block;
    width: 22px;
    height: 20px;
  }
  #simple-select-quiz .rb_fav > svg > path {
    fill: none;
    stroke: var(--rb-text-secondary);
    stroke-width: 1;
  }
  #simple-select-quiz .rb_fav[aria-pressed="true"] > svg > path {
    fill: var(--rb-text-secondary);
  }
}

/* =============================================================================
   FAVOURITE CONTROLS ARE A MOBILE-2.2 NODE ONLY
   The `.rb_fav` styling above lives inside the <=991 block, so at >=992 the two
   new buttons fell back to UA defaults and rendered as real in-flow controls.
   MEASURED at 1728 on desktop 2.2 after the markup landed: `.rb_fav_line`
   painted at [894,147 754x676.9] -- a block-level button filling the right
   column. The desktop boards (2.2 = 14468:44399, 2.4 = 14468:41822) draw no
   heart at all, and desktop is finished work that must not regress, so the
   default is `display: none` at EVERY width and only mobile 2.2 turns it on.
   The mobile show rule is (1,2,0) against this (1,1,0), so it still wins --
   media queries carry no specificity of their own.
   ============================================================================= */
#simple-select-quiz .rb_fav { display: none; }

/* =============================================================================
   LIST-VIEW ROW -- AN EXPANDED ROW MUST FLOW, NOT OVERLAP
   NOT in a media query: the same shape was measured at 390 AND at 1728.

   MEASURED at 390: `.result_item_row` is `height: 48px` with
   `overflow: visible`, and bootstrap's own `.row { flex-wrap: wrap }` puts the
   row's two col-12 children (`.results_header` and `.result_item_details`) on
   two flex lines. The moment the accordion opens, the 596-tall details body
   paints OUTSIDE the 48px box and straight over rows 2..n, which still begin at
   213 / 265 / 317. So the row's own CTA was covered: its box read
   [40,809 310x45] with `visibility: visible`, which is why it had been reported
   as usable, but `document.elementFromPoint` at its centre returned the NEXT
   row's `<p>` and a real `locator.click()` failed actionability with
   "<p>Signature Ideal</p> ... intercepts pointer events".

   That is the whole reason the list path never reached 2.2. The delegated
   handler in diamond-search.js is wired correctly and its selector matches --
   verified live, `a.matches('#ssq_diamond_search .result_item_row
   .search_selectors a')` === true and `typeof window.rbStoneMode` === 'function'
   -- it simply never received a click, so `#simple-select-quiz` kept
   `rb_at_first` alone and the 2.2 sheet had nothing to key off.

   Letting the OPEN row size to its content is the entire fix; a closed row
   keeps its 48 exactly, so the 48 + 4 pitch assertion is untouched.
   Specificity has to beat `#ssq_diamond_search .search_results
   .result_item_row` (1,2,0), because _advanced-search.css is enqueued AFTER
   this partial. `:has()` takes the specificity of its most specific argument,
   so this selector is (1,4,0) and wins on specificity, not on order.
   ============================================================================= */
#ssq_diamond_search .search_results .result_item_row:has(> .result_item_details.opened) {
  height: auto;
}

/* THE GEMSTONE THUMB carries NO margin of its own.
   `Round-Lab-Emerald-300x300.jpg` is cropped tight to the stone, while the
   three diamond images are stones sitting inset on white. Measured in the 40px
   frame: the diamonds read about 58% of the box, the emerald about 86% even
   under `contain`, so it stood out as a flat green disc beside three inset
   stones. The extra inset brings it to the same visual weight.

   This compensates for ONE catalogue asset and is tuned to it. The durable fix
   is a gemstone product image framed like the diamond ones; if that lands, drop
   this rule rather than re-tuning it. */
#simple-select-quiz .ssq_all_stone_options #simple_gemstone .ssq_stone_image img,
#simple-select-quiz .ssq_all_stone_options .simple_gemstone .ssq_stone_image img {
    padding: 8px;
}

/* =============================================================================
   ADDENDUM 4 — MOBILE 2.2 / 2.4 ALIGNMENT PASS
   Boards: 14468:36206 "2.2 Stone details" 390x976
           14468:36310 "2.4 Back to stone step" 390x1122
   Pulled from the REST API at depth 8 and diffed against dev-0 rendered at 390.
   Nothing here is a rebuild: every node already existed, and every rule below
   is a position/size correction with the board's own number in the comment.

   MEASURED ON DEV-0 AT 390 BEFORE THIS ADDENDUM (absolute page y):
     2.4  heading band   0-80      board band 46-174  (128 tall, covers the tabs)
          Ring Details  88-128     board 182-222      <- ABOVE the tabs, wrong order
          step tabs    144-184     board 128-168
          hero card    185-335     board 230-380
          YOUR STONE   346         board 408          gap from card 11, board 28
          YOUR STONE   text-align CENTER              board hugs LEFT at x=22
     2.2  headline     290  "0.52 Carat Round Lab Diamond"   board is UPPER
          price        318  gap 25 from the headline glyph box, board 19
          trust strip  766  gap 28 from the thumbs,           board 14
          spec row 1   812  gap 21 from the trust strip,      board 25
          trust icon   21x21, icon->label 6                   board 17x17, gap 2
   ============================================================================= */

@media (max-width: 991px) {

  /* --- A. BOARD ORDER, 14468:36310 --------------------------------------
     `BYR Header` is ONE #E4DED8 band [0,46 390x128] holding the titles AND the
     STONE/SIZE/ENGRAVING strip [22,128 342x40]; the Ring Details chip
     [23,182 345x40] sits BELOW it on the page ground. The build had the chip
     first and the tabs after, on bare #FAF3ED. Only `order` moves -- the two
     wrappers are already `display:contents` (section 0), so no node moves. */
  #simple-select-quiz .quiz_options > .rb-progress-bar { order: 1; }
  #simple-select-quiz .rb_details_bar                  { order: 2; }

  /* The header block is 80 of the band's 128, so the tab strip carries the
     remaining 48 of wash and must be FULL-BLEED. The content box is held at the
     board's 342 with 24px of side padding -- which is the same 24 the old
     `margin: 0 auto` resolved to at 390, so `.progress-circle.completed`'s
     offset is byte-identical and simple-select.js:1178 (`.position().left`,
     used to size `.rb-progress-complete`) reads exactly what it read before. */
  #simple-select-quiz .quiz_options > .rb-progress-bar {
    width: 100%;
    height: 48px;
    /* 22, not 24: [Flow 3] 14514:41123 insets the 346-wide bar at x22, the same
       gutter every other block inside the BYR quiz uses.

       ...AND ABOVE 390 THAT GUTTER HAS TO CENTRE, like every other block on the
       screen. Owner: *"despite multiple times, this button does not align with
       the rest, and it's not only in engraving -- in all steps, same story"*,
       and then *"neither does the other arrow with its right end."*

       Both arrows, both ends, because the whole rail was still laid out on the
       390 board's coordinates while the Ring Details bar and the ring card had
       already moved to a centred 346 column. MEASURED at 412 in the builder:

         bar / card            x 33  ..  379
         back arrow            x 22  ..   58     <- 11 short on the left
         step cells            68 / 156 / 244
         forward arrow         x 332 ..  368     <- 11 short on the right

       Same `max(gutter, (100% - 346px) / 2)` the stone block and the engraving
       column now use, whose floor is the board's own 22, so 390 and every
       narrower phone are unchanged to the pixel and from 390 up the rail's two
       ends track the bar's. The bar stays `width: 100%` with border-box sizing
       -- the fix above, which kept the chips inside the frame, is untouched;
       only where the content box starts and ends moves. */
    padding: 2px max(22px, calc((100% - 346px) / 2)) 6px;
    /* ...AND THE PADDING HAS TO COME OUT OF THE 100%, NOT BE ADDED TO IT.
       Owner: *"the navigation left and right on either side of stone / size /
       engraving look weird and huge on phone, they even drop out of frame
       slightly."*

       `width: 100%` with content-box sizing makes this bar 100vw + 44, so the
       two 36px chips are laid out against a box wider than the screen.
       MEASURED with an 18k Rose Gold ring, next chip right edge vs viewport:
         390 -> 368 in 390   (8px is the board's own inset -- fine)
         375 -> 368 in 375   (7px left, should be 22)
         360 -> 368 in 360   OUT OF FRAME by 8px
       Nothing was wrong at the board's own 390, which is why it only shows on a
       narrower phone. This rule overrides the fluid
       `width: min(346px, calc(100vw - 44px))` above it, so border-box is what
       puts the two back in agreement: the bar is the viewport, the 22px gutters
       are inside it, and the chips land on 22 and (100vw - 58) at every width. */
    box-sizing: border-box;
    margin: 0;
    background: rgba(228, 222, 216, 0.60);   /* --rb-border-subtle @ 0.60 */
  }
  /* Chip: board band bottom 174 -> chip 182 = 8, which is the author margin
     already on `.rb_details_bar`; it now measures from the band instead of
     from the header. Board card 230 - chip bottom 222 = 8 (build had 1). */
  /* 20, up from 8 -- the mobile half of the "give the Ring Details bar some air
     above the photo" change. The desktop side went 12 -> 24 in
     _stone-desktop.css, and this rule is why mobile did not move with it: the
     gap there is not on `.quiz-image-conatiner` (which is `display: contents`
     at <=991 and has no box at all) but on `.quiz-image.horizontal` itself.
     Measured before: bar bottom 328, image top 336 -- 8px, which is what reading
     as stuck. Same +12 as desktop rather than matching 24, because the phone
     column has far less height to spend. */
  /* 9, down from 32. [Flow 3] 14514:41123 and 14514:40420 both end the
     Ring-details bar at header-relative 176 and start the setting card at 185.
     The 32 came from a "give the bar some air" pass on the Flow-2 boards; it
     pushed RING SIZE, the wheel, the helper row, the engraving heading, its
     paragraph, the text box and the symbol row all 23px down together, which
     is why seven blocks were off by one number. */
  /* 16, UP FROM THE BOARD'S 9. Owner: *"there is no gap between collapsed Ring
     Details and the image below it in phone mode -- fix it, and also fix for
     [the] expanded view."*
     The 9 IS the board's own figure (14514:41123 / 14514:40420 end the bar at
     header-relative 176 and start the card at 185), and it is what shipped --
     MEASURED at 390, the gap is exactly 9px in BOTH states, collapsed (bar 40
     tall) and expanded (bar 171 tall), because it is a margin on the card
     rather than anything the bar's own height feeds. So nothing was broken;
     9px simply does not read as separation between two filled blocks on a
     phone. Raised to 16 on the owner's call -- a deliberate deviation, stated
     rather than quietly matching the board. It moves only this card, so the
     blocks below it keep their own spacing. */
  #simple-select-quiz .quiz-image.horizontal { margin-top: 16px; }

  /* --- A2. 2.4 SETTING CARD CARRIES ONE CHIP, NOT TWO, 14468:36314 -------
     The card 14468:36312 is 150 tall and holds exactly one 144x36 pill,
     14468:36314 at board [210,287] = page [210,241], vertically centred in it
     (241 + 18 = 259 = 184 + 75). The build stacks TWO -- `.metal_dropdown_ssq`
     and `.shape_dropdown_ssq`, a 92-tall column from 14463:33489/33495, which is
     a DIFFERENT board -- so the pair centres at 213 and the metal pill sits 28px
     high of its node. MEASURED at 390 on 2.4: [210,213 144x36] plus a second
     [210,269 144x36] with no counterpart in 14468:36310.

     The shape pill is hidden rather than deleted, and ONLY on 2.4: by this point
     the customer has chosen a real stone, so its shape is decided -- which is
     why the board drops the control and draws the shape as a plain 20x20 icon
     inside the metal pill instead. Everywhere the shape is still a CHOICE the
     pill stays.

     Scoped with `:has()` and not on `.rb-stone-held` alone: MEASURED, that class
     is set by diamond-search.js:3147 on 2.4 and is STILL on the root on the SIZE
     step (`#ssq_size.active`, card [22,184 346x150] with both pills painted), so
     gating on it would silently take the shape control off a screen no board in
     this task covers. The stone slide being active is what makes it 2.4. */
  /* [Flow 3] EXTENDS THIS TO THE SIZE AND ENGRAVING STEPS. The note above
     deliberately held the shape pill on those two because "no board in this
     task covers" them -- 14514:41123 (3.4) and 14514:40420 (3.6) now do, and
     both draw the same single 144x36 metal chip as 3.5, with no shape control
     anywhere on the screen. MEASURED before: `.select_metal_shape` 144x92 at
     [210,237] on both, stacking a second "Round" pill at y293. */
  #simple-select-quiz.rb-stone-held:has(#ssq_select_stone.active) .quiz-image > .select_metal_shape,
  #simple-select-quiz.rb-stone-held:has(#ssq_size.active) .quiz-image > .select_metal_shape,
  #simple-select-quiz.rb-stone-held:has(#ssq_engraving.active) .quiz-image > .select_metal_shape {
    height: 36px;
    gap: 0;
  }
  #simple-select-quiz.rb-stone-held:has(#ssq_select_stone.active) .quiz-image > .select_metal_shape > .shape_dropdown_ssq,
  #simple-select-quiz.rb-stone-held:has(#ssq_size.active) .quiz-image > .select_metal_shape > .shape_dropdown_ssq,
  #simple-select-quiz.rb-stone-held:has(#ssq_engraving.active) .quiz-image > .select_metal_shape > .shape_dropdown_ssq {
    display: none;
  }

  /* --- A2b. THE ENGRAVING STEP HAS TO PAINT ITS OWN FLOOR ----------------
     14514:40420 is a 390x848 frame filled #FAF3ED edge to edge. 3.4 and 3.5
     keep their ground for free because a FIXED 390x129 `.ssq_bottom_nav` in
     #FAF3ED covers the foot of the viewport; 3.6 correctly has no bottom nav
     (the board puts ADD TO BAG in the content flow at y599, not in a sticky
     bar), so below the quiz's own 750px there was nothing painting anything.
     MEASURED: `document.elementFromPoint(195, 780)` and `(195, 860)` both
     returned HTML.da-no-applepay at rgba(0,0,0,0) with body also transparent,
     i.e. the bottom ~150px of a 900-tall viewport rendered white.
     `min-height` on the quiz rather than a background on <body>: the quiz is
     the flow's own surface and the original product page underneath it must
     not gain a ground it did not have. */
  #simple-select-quiz:has(#ssq_engraving.active) {
    min-height: 100vh;
    background-color: var(--rb-surface-page);
  }

  /* --- A3. THE STONE STEP DRAWS THE SETTING CARD AFTER ALL ----------------
     REVERSED. The previous round read 3.5 off 14514:40624 and hid the card,
     because 40624 parks `setting section` at @22,61 -- inside the BYR header's
     fixed 0..222 band, where it is occluded. 41618 does the same at @22,62.
     But 14514:41519 puts the identical component at @22,**231**, clear of the
     header, and that is where 14514:41123 (3.4) and 14514:40420 (3.6) put it
     too. Three frames against two, and the two that disagree are the ones whose
     own 2x renders show no card at all -- i.e. they are MIS-LAID-OUT, not a
     different design. 41519 is canonical for 3.5; the card is drawn.

     MEASURED with the card suppressed: `.quiz-image.horizontal` absent, YOUR
     STONE [22,194], stone row [22,217], stone image [22,246], thumbs [22,600],
     accordion [22,669] -- every one of them 170px high of 41519, which puts the
     card at page 185 (board 231 - 46) and YOUR STONE at page 364 (board 410).
     Restoring the card and spending the board's own 29px under it lands all
     five on the board. See ELEMENTS.md 0.3. */

  /* --- B. HERO CARD -> STONE BLOCK --------------------------------------
     2.4: `setting section` bottom 380 -> `YOUR STONE` 408 = 28.
     2.2: `Frame 1171276486` padTop 10 + `Frame 1171276485` padTop 10 = 20
     above 14468:36213. Each board is honoured literally rather than averaged. */
  #simple-select-quiz.rb-stone-held .ssq_picked_selection { padding-top: 28px; }
  /* [Flow 3] 29, not 28: 14514:41519 ends the card at 381 and starts the
     content column at 410. One px, and it is the only number that differs
     between the two boards for this gap -- so it is spent only where Flow 3
     owns the screen. */
  section#simple-select-quiz.rb-stone-first.rb-stone-held:has(#ssq_select_stone.active) .ssq_picked_selection {
    padding-top: 29px;
  }
  #simple-select-quiz.rb-stone-pdp  .ssq_picked_selection { padding-top: 20px; }

  /* --- C. "YOUR STONE" 14468:36321 --------------------------------------
     The node is [22,408 109x19] -- 109 wide, HUGGING its text, pinned to the
     column's left edge. Its textAlignHorizontal:CENTER is centring inside that
     109px hug, NOT inside the 346 column, so in CSS terms the block is LEFT.
     The build read the CENTER off the node and centred it in 346. */
  #simple-select-quiz.rb-stone-held .ssq_picked_selection > .rb_ys_title {
    text-align: left;
  }

  /* [Flow 3] 14514:41535 carries `case=LOWER` -- "0.60 carat round lab diamond"
     -- and so does the Ring-details expanded stone value it mirrors
     (14514:40407). Two of the three 3.5 frames have it; only 41618, the modal
     variant, drops it, which is why B10 settles on LOWER. Flow 2's 14468:36331
     is ORIGINAL, so this is scoped to the stone-first root rather than folded
     into the `.rb-stone-held` rule above. */
  section#simple-select-quiz.rb-stone-first .ssq_picked_selection #preview_confirm_type,
  section#simple-select-quiz.rb-stone-first .ssq_picked_selection #preview_confirm_type > span {
    text-transform: lowercase;
  }

  /* --- D. 2.2 HEADLINE CASE, 14468:36213 --------------------------------
     style.textCase = UPPER ("0.60 CARAT ROUND LAB DIAMOND"). 2.4's
     14468:36331 is ORIGINAL, and the `.rb-stone-held` rule above already sets
     `text-transform:none` at higher specificity, so the two states stay split
     off one string. */
  #simple-select-quiz.rb-stone-pdp .ssq_picked_selection #preview_confirm_type {
    text-transform: uppercase;
  }

  /* --- E. 2.2 HEADLINE ROW, 14468:36210 = 366 x 37 ----------------------
     The row is three numbers, and it has to be all three or none: the board's
     boxes are name 14468:36213 h=13, gap 6, price 14468:36214 h=18, summing to
     the frame's 37. The build ran the CSS line boxes instead (24 + 0 + 16 = 40)
     and zeroed the 6 to compensate, which left the price 6px low at page 95 for
     a board 89 AND made the row 3px too tall -- and since `.rb_ys_line` is the
     first block in the column, that 3 pushed the hero, the thumb strip, the
     trust row and the spec block down with it.

     So the leading is taken OUT of the two line boxes and the board's 6 is put
     back between them. The name is UPPER here (rule D above), so a 13px line box
     on 18px Canela clips nothing -- there are no descenders in the rendered
     string, and 13 is exactly the cap height Figma reports for it. The price's
     18px box over a 16px face lands its ink at 89.2, i.e. on the board's 89.
       13 + 6 + 18 = 37, price top 70 + 13 + 6 = 89.
     `!important` on the price because simple-select-quiz.php writes
     `margin-top:2px; margin-bottom:5px` inline on that node. */
  /* 24px, the board's own leading (14468:36213 fontSize 18 / lineHeightPx 24),
     not 13. A 13px line box on an 18px face overflows UPWARD by half the
     leading, so the glyphs painted at 67..80 against the board's 69..83 and the
     gap to the price came out 3px wide. The 13 was chosen as Figma's reported
     cap height, which sets the BOX correctly and the INK wrong.
     The negative margin puts the block back where the 13px box had it, so the
     6px gap to the price below is unchanged. Cross-check: .rb_ys_title on 2.4
     (14468:36323) is the same 18px Canela upper and carries normal leading,
     painting 362..375 against Figma's 362..376. */
  #simple-select-quiz.rb-stone-pdp .ssq_picked_selection #preview_confirm_type {
    line-height: 24px;
    margin-top: -6px;
  }
  /* 1px, not 6. The title above now carries the board's real 24px leading
     instead of a 13px box, so its border box is 11px taller and a 6px margin
     pushed the price from the board's 89 down to 94. The GAP the board draws is
     between the two INK bands, not the boxes: title ink ends ~82.5, price ink
     starts ~89. 1px of margin restores that. */
  #simple-select-quiz.rb-stone-pdp .ssq_picked_selection #preview_confirm_price {
    margin: 1px 0 0 !important;
    line-height: 18px;
  }

  /* --- F. 2.2 THUMBS -> TRUST ROW, 14468:36224 --------------------------
     Board: thumb strip bottom 555 -> trust row 569 = 14. That 14 (padBottom 10
     + body itemSpacing 4) is ALREADY on `.quiz-handpicked-image` as
     margin-bottom; the strip was adding a second copy of the same number, so
     the rendered gap was 28. */
  #simple-select-quiz.rb-stone-pdp .ssq_picked_selection > .rb_trust_strip {
    margin-top: 0;
  }

  /* --- G. 2.2 TRUST ROW -> SPEC LIST ------------------------------------
     Board: trust bottom 594 -> `Frame 1171276146` 598 (body itemSpacing 4)
     -> padTop 21 -> first row 619, i.e. 25 from the strip. The 21 padding was
     already right; the 4 was missing. */
  #simple-select-quiz.rb-stone-pdp .ssq_picked_selection .diamond_atts_accordion {
    margin-top: 4px;
  }

  /* --- H. TRUST ICONS, 14468:36228 / 36236 / 36243 ----------------------
     17x17, and the icon->label gap resolves to 2 (label x=31 against an icon
     at x=12 w=17). The build drew 21x21 with a 6 gap, which pushed every label
     8px right and broke the 12 / 142 / 259 item origins.

     The three are THREE DIFFERENT glyphs, not one repeated: 14468:36229 is a
     parcel with a check, 14468:36237 a gem over a circle, 14468:36244 a circular
     return arrow. All three share the node NAME "streamline-sharp:shipment-check"
     -- which is how one of them came to be pasted three times -- but their child
     vectors differ, and the 1:1 export shows three distinct marks. The artwork now
     comes from the file's own SVG export of each node (see simple-select-quiz.php);
     the sizing below is what makes those 17x17 viewBoxes land on the board's cells,
     and `currentColor` is what keeps them on the li's --rb-text-secondary. */
  #simple-select-quiz .ssq_picked_selection .rb_trust_icon {
    width: 17px;
    height: 17px;
    flex: 0 0 17px;
  }
  #simple-select-quiz .ssq_picked_selection .rb_trust_icon svg {
    width: 17px;
    height: 17px;
  }
  #simple-select-quiz .ssq_picked_selection > .rb_trust_strip > li { gap: 2px; }

  /* PILL LABELS IN NORMAL CASE -- applied to the pill AND its descendants.
     The metal and shape pills rendered "14K WHITE GOLD" and "ROUND". A reset on
     `.select_metal_option` alone did not reach them: simple-select.js clones the
     chosen option out of the dropdown LIST, classes and all, and the casing sits
     on a nested span inside that clone rather than on the node the pill rule
     targets. The descendant selector is blunt on purpose -- it changes nothing
     but letter case, and the list itself is left alone. */
  #simple-select-quiz .quiz-image .metal_current_option,
  #simple-select-quiz .quiz-image .metal_current_option *,
  #simple-select-quiz .quiz-image .shape_current_option,
  #simple-select-quiz .quiz-image .shape_current_option * {
    text-transform: none;
    font-variant-caps: normal;
  }

}

/* =============================================================================
   [Flow 3] 3.5 -- "PICK A DIFFERENT STONE": CONFIRM + CHOOSER
   Figma 14514:41689 ("Change of heart?" popup, 300x279)
         14514:40692 ("Browse more popup" bottom sheet, 390x392)

   DELIBERATELY OUTSIDE THIS FILE'S max-width:991px WRAPPER, which is the one
   exception in the sheet. Everything above is a mobile redesign of a screen that
   already had a desktop form; these two panels are NEW controls that exist at
   every width, because the link that opens them does. Splitting them across
   _stone.css and _stone-desktop.css would mean maintaining one design twice, and
   scoping them to mobile would leave the destructive action unconfirmed on a
   laptop -- the exact failure the confirm is here to prevent.

   Literal hex rather than the --rb-* tokens for the same reason: every token in
   this build is declared inside a width media query, so a token reference here
   would resolve on a phone and fall back to nothing on a desktop.
   ============================================================================= */

/* `black mask` -- #000000 @ 70%, FIXED, full frame. Its own element; see the
   note at rbSfScrim() for why this does not reuse .rb_drawer_scrim. */
#simple-select-quiz .rb_sf_scrim {
  position: fixed;
  inset: 0;
  z-index: 1200;
  background: rgba(0, 0, 0, 0.699999988079071);
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms cubic-bezier(0.42, 0, 0.58, 1);
}
#simple-select-quiz .rb_sf_scrim.rb_sf_scrim_on {
  opacity: 1;
  pointer-events: auto;
}

#simple-select-quiz .rb_sf_panel {
  display: none;
  position: fixed;
  z-index: 1201;
  box-sizing: border-box;
  background: #FAF3ED;
  color: #0F0E0D;
  font-family: var(--rb-font-body, 'Founders Grotesk', system-ui, sans-serif);
}

/* ---------------------------------------------------------------------------
   THE CONFIRM -- 14514:41689
   300x279 at [45,421] in a 390x1144 frame: horizontally centred with 45px
   margins, so it is centred rather than positioned. r8, pad 12/12/36/12,
   vertical gap 16, primary-axis MAX (content pushed to the bottom of the box),
   which is why the close sits alone in the top band and the body group is what
   the 36px bottom padding is measured from.
   --------------------------------------------------------------------------- */
#simple-select-quiz .rb_sf_confirm {
  top: 50%;
  left: 50%;
  width: 300px;
  max-width: calc(100vw - 48px);
  transform: translate(-50%, -50%) scale(0.96);
  border-radius: 8px;
  padding: 12px 12px 36px;
  opacity: 0;
  transition: opacity 220ms ease-out, transform 220ms ease-out;
}
#simple-select-quiz .rb_sf_confirm.rb_sf_open {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* Close 24x24 r4 with a 10x10 vector at 0.75px #0F0E0D. */
#simple-select-quiz .rb_sf_confirm .rb_sf_close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin-left: auto;
  border-radius: 4px;
  color: #0F0E0D;
  cursor: pointer;
}
#simple-select-quiz .rb_sf_panel .rb_sf_close svg {
  stroke: currentColor;
  stroke-width: 0.75;
}

/* Body 276 wide, vertical gap 21, padding 0/8, centred. */
#simple-select-quiz .rb_sf_confirm .rb_sf_body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 21px;
  padding: 0 8px;
  text-align: center;
}

/* Canela 300 24/28.8, letter-spacing 0, #000000. */
#simple-select-quiz .rb_sf_panel .rb_sf_title {
  margin: 0;
  font-family: var(--rb-font-display, 'Canela', Georgia, serif);
  font-weight: 300;
  font-size: 24px;
  line-height: 28.8px;
  letter-spacing: 0;
  color: #000000;
  text-transform: none;
}

/* FG 400 16/17, #0F0E0D; the stone name runs in Medium 500. */
#simple-select-quiz .rb_sf_confirm .rb_sf_copy {
  margin: 0;
  font-weight: 400;
  font-size: 16px;
  line-height: 17px;
  letter-spacing: 0;
  color: #0F0E0D;
}
#simple-select-quiz .rb_sf_panel .rb_sf_stone_name { font-weight: 500; }
/* With no name to quote the sentence reads "...will remove your  from this
   ring." The copy is rewritten by the class rather than the text so nothing
   here has to invent a stone description. */
#simple-select-quiz .rb_sf_copy_unnamed .rb_sf_stone_name::after { content: 'stone'; }

/* CTA 260x44, #27423B, r4, gap 4, label FG 400 16/19 UPPER #FAF3ED + the
   12.8x9.7 arrow group. */
#simple-select-quiz .rb_sf_panel .rb_sf_continue {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  box-sizing: border-box;
  width: 260px;
  max-width: 100%;
  height: 44px;
  border-radius: 4px;
  background: #27423B;
  color: #FAF3ED;
  font-weight: 400;
  font-size: 16px;
  line-height: 19px;
  text-transform: uppercase;
  text-decoration: none;
}
#simple-select-quiz .rb_sf_panel .rb_sf_continue:hover,
#simple-select-quiz .rb_sf_panel .rb_sf_continue:focus {
  color: #FAF3ED;
  text-decoration: none;
}
#simple-select-quiz .rb_sf_panel .rb_sf_arrow { flex: 0 0 auto; }

/* "Keep this stone" 260x28, FG 400 16/19, ls -0.21, #27423B, underlined. */
#simple-select-quiz .rb_sf_panel .rb_sf_keep {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 260px;
  max-width: 100%;
  height: 28px;
  font-weight: 400;
  font-size: 16px;
  line-height: 19px;
  letter-spacing: -0.21px;
  color: #27423B;
  text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   THE CHOOSER -- 14514:40692
   390x392, BOTTOM/CENTER, FIXED, r8, pad 20/24/60/24, body 342 wide gap 30.
   --------------------------------------------------------------------------- */
#simple-select-quiz .rb_sf_chooser {
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0 auto;
  width: 100%;
  max-width: 390px;
  border-radius: 8px 8px 0 0;
  padding: 20px 24px 60px;
  transform: translateY(100%);
  transition: transform 300ms cubic-bezier(0.42, 0, 0.58, 1);
}
#simple-select-quiz .rb_sf_chooser.rb_sf_open { transform: translateY(0); }

/* Close ✕ 12x12, 1px #3E3C39, at the sheet's right edge on the top pad line. */
#simple-select-quiz .rb_sf_chooser .rb_sf_close {
  display: block;
  width: 12px;
  height: 12px;
  margin-left: auto;
  color: #3E3C39;
  cursor: pointer;
}
#simple-select-quiz .rb_sf_chooser .rb_sf_close svg { stroke-width: 1; }

#simple-select-quiz .rb_sf_chooser .rb_sf_body {
  display: flex;
  flex-direction: column;
  gap: 30px;
  text-align: left;
}
#simple-select-quiz .rb_sf_chooser .rb_sf_intro {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
#simple-select-quiz .rb_sf_chooser .rb_sf_title { text-align: left; }
#simple-select-quiz .rb_sf_chooser .rb_sf_copy {
  margin: 0;
  font-weight: 400;
  font-size: 16px;
  line-height: 20px;
  letter-spacing: 0;
  color: #0F0E0D;
}

/* Options 342x153, vertical gap 21. */
#simple-select-quiz .rb_sf_options {
  display: flex;
  flex-direction: column;
  gap: 21px;
}

/* Row 342x66, #FFFFFF @ 60%, 1px inside #E4DED8, r8, SPACE_BETWEEN,
   pad 12/20/12/12. */
/* THE BOARD'S OWN STRING DOES NOT FIT IN THE BOARD'S OWN COLUMN, in this
   face. 14514:40692 gives the row 342 wide, padding 12/20/12/12, a 40 icon, a
   12 chevron and 12 of total inter-item space -- which leaves the text exactly
   246. MEASURED: "Search full inventory by cut, carat & price" at Founders
   Grotesk 400 16px, letter-spacing normal, needs 260.0px unwrapped (measured
   with a nowrap probe span carrying the computed font), so at the board's own
   numbers it wraps and the row grows 342x66 -> 342x81 and the sheet 392 -> 433.
   Figma's metrics for this face are ~6% narrower than the shipped webfont.
   The row's HEIGHT is the board's load-bearing assertion -- it is what makes
   the options block 153 and the sheet 392 -- so the 18px the text needs is
   taken from the trailing gutter and the icon gap, which are the two numbers
   on this row nobody can read. Cost: the chevron lands 12px right of the
   board's x. Flagged rather than hidden. */
#simple-select-quiz .rb_sf_row {
  display: flex;
  align-items: center;
  gap: 0;
  box-sizing: border-box;
  min-height: 66px;
  padding: 12px 8px 12px 12px;
  border-radius: 8px;
  box-shadow: inset 0 0 0 1px #E4DED8;
  background: rgba(255, 255, 255, 0.6);
  color: #0F0E0D;
  text-decoration: none;
}
#simple-select-quiz .rb_sf_row:hover,
#simple-select-quiz .rb_sf_row:focus {
  color: #0F0E0D;
  text-decoration: none;
}

/* Icon 40x40 circle, #E4DED8 @ 60%, glyph 1px #C69858. */
#simple-select-quiz .rb_sf_row_icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  border-radius: 200px;
  background: rgba(228, 222, 216, 0.6);
  color: #C69858;
  margin-right: 6px;               /* the row's gap, see the note above */
}
#simple-select-quiz .rb_sf_row_icon svg { stroke: currentColor; }

/* 14514:40692's rows are 342x66 with the sub-line on ONE line. MEASURED
   before: rows 342x81 and the text column 234 wide, because the row reserved a
   44px trailing gutter for the chevron where the board reserves ~32 (row 342 -
   12 left pad - 40 icon - 12 gap - 20 right pad - 12 chevron - 8 chevron gap =
   238). Both "Stones curated by expert gemologists" and "Search full inventory
   by cut, carat & price" wrapped to two lines and the sheet grew to 433. The
   width is recovered on the chevron's flex basis below rather than by
   shrinking the padding, which is board-exact. */
#simple-select-quiz .rb_sf_row_text {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
}
#simple-select-quiz .rb_sf_row_title,
#simple-select-quiz .rb_sf_row_sub {
  font-weight: 400;
  line-height: 19px;
}
/* 3.5.41 / 3.5.43. `Handpicked stones` and `Advanced Lab Diamond Search` are
   FG 400 16/19 #0F0E0D; the two sub-lines under them are a SMALLER, LIGHTER
   face -- FG 400 14/19 filled `#3E3C39 @ 95%`. The note that used to be here
   ("the board writes the two lines at the same weight and colour") is wrong on
   both counts: they differ in size and in ink, and 0.8 opacity on #0F0E0D is
   neither. MEASURED before: `.rb_sf_row_sub` 16px rgb(15,14,13) -- the same
   size and ink as the title above it, so the pair no longer read as title and
   sub. */
#simple-select-quiz .rb_sf_row_title {
  font-size: 16px;
  color: #0F0E0D;
}
#simple-select-quiz .rb_sf_row_sub {
  font-size: 14px;
  color: rgba(62, 60, 57, 0.95);
}

/* `Vector 138` -- a 12-wide chevron, 1px #0F0E0D. */
#simple-select-quiz .rb_sf_row_chev {
  flex: 0 0 auto;
  color: #0F0E0D;
  stroke: currentColor;
  /* No gap of its own -- SPACE_BETWEEN, and the row's gap is carried on the
     icon instead (see the note on `.rb_sf_row`). The 12px that used to be
     spent here was 12px the text column never got. */
  margin-left: 0;
}

@media (prefers-reduced-motion: reduce) {
  #simple-select-quiz .rb_sf_scrim,
  #simple-select-quiz .rb_sf_panel { transition-duration: 0s; }
}

/* [Flow 3] 3.5 -- no back chip on the stone step when the stone came from
   another page. See rbApplyStoneFirstChrome() for the measurement; `_stone.css`
   un-hides `.rb_back` on `.rb-stone-held` for the setting-first 2.4, where the
   chip has an in-quiz grid to return to. Unwrapped for the same reason as the
   block above: the journey and the control exist at both widths. */
/* Specificity is deliberate, not decorative. The rule this has to beat is
   `section#simple-select-quiz.rb_at_first.rb-stone-held .rb_back` (one id, two
   root classes, one element) a few hundred lines above, and it carries
   `visibility: visible !important` -- which it needs, because the base sheet
   hides every step-1 back chip with an `!important` of its own. So this is an
   `!important` answering two others, matched on specificity and settled by
   source order rather than out-weighted. MEASURED through both wrong versions:
   with an id-plus-one-class selector, and again with matching specificity but
   no `!important`, the class was on the root and rbStoneFirstActive() was true
   while computed visibility stayed `visible`. */
section#simple-select-quiz.rb-stone-first.rb-sf-no-back .rb_back {
  visibility: hidden !important;
  pointer-events: none;
}

/* [Flow 3] RING DETAILS READS IN JOURNEY ORDER — 14514:40363.
   The board's expanded bar lists Stone first and Setting second, which is the
   order the stone-first shopper answered them in: the stone was committed on
   /lab-grown-diamonds/ before they had ever seen a setting. The markup order
   (`simple-select-quiz.php`:91-111) is Setting, Stone, Engraving -- the
   setting-first reading -- and stays that way for Flow 2, where it is equally
   the journey order.

   `order` rather than re-ordering the nodes: three handlers and
   rbRenderDetailsBar() all address these rows by class, and `.rb_details_body`
   is already a flex column at both widths, so this changes the paint order and
   nothing else. Unwrapped for the same reason as the panels above -- the
   journey exists at every width, and the desktop body is the same flex column.
   The class goes away with the stone (rbApplyStoneFirstChrome), and the order
   reverts with it. */
section#simple-select-quiz.rb-stone-first .rb_details_row_stone     { order: 1; }
section#simple-select-quiz.rb-stone-first .rb_details_row_setting   { order: 2; }
section#simple-select-quiz.rb-stone-first .rb_details_row_engraving { order: 3; }

/* [Flow 3] THE CARDS AND THE IN-QUIZ SEARCH ARE MUTUALLY EXCLUSIVE SCREENS.
   `.rb-stone-panel` already hides this exact set, but it means "a stone is
   HELD", and the route that most needs the rule -- "Pick a different stone" ->
   CONTINUE -> Advanced search -- has just removed the stone, so that class has
   gone. FLOW.md section 8 recorded the resulting state as a live defect on the
   Flow-2 route too: the search and the four type cards on screen together, the
   search reading 0 rows because it had not been queried yet.

   MEASURED at 390 through the chooser before this: `#ssq_diamond_search` block
   at 390x900 with `.ssq_all_stone_options` still `flex` beneath it and the
   carat band between them. `!important` because it is answering the
   `display: flex !important` a few thousand lines above, which exists so that
   simple-select.js's inline `display:grid` cannot win -- an inline `none` from
   JS loses to it, which is why this is a class and not a style.

   rbSfSyncSearchExclusive() (simple-select-redesign.js) is the only writer and
   it derives the class from whether the search is on screen, so it clears
   itself when the shopper closes the search or picks a stone in it. */
/* THE SEARCH LIVES INSIDE `.ssq_all_stone_options` (simple-select-quiz.php:414
   prints the four `.ssq-simple-selection` rows and `#ssq_diamond_search` as
   SIBLINGS in that one container), so hiding the container hid the search with
   it -- this rule used to switch off the very screen it exists to make room
   for. MEASURED on "Continue browsing" back from 2.2 at 1728: the search was
   `display: block` with its own `style` attribute set by rbShowGrid(), height
   0, and its parent computed `display: none`. The shopper got an empty page:
   no cards, no filters, no grid.

   It also could not settle. rbSfSyncSearchExclusive() derives the class from
   whether the search is on screen, so hiding the search falsifies the very
   condition that set the class -- the next sync clears it, the search comes
   back, the sync sets it again. Nothing re-synced after "Continue browsing",
   which is the only reason it stuck blank instead of flickering.

   The four ROWS are what must go, not their container. */
section#simple-select-quiz.rb-sf-search .ssq_all_stone_options > .ssq-simple-selection,
section#simple-select-quiz.rb-sf-search .simple-quiz-carat-filter,
section#simple-select-quiz.rb-sf-search .rb_stones_head,
section#simple-select-quiz.rb-sf-search .ssq_all_stone_confirmations {
  display: none !important;
}

/* =============================================================================
   NO HEADER BACK CHIP WHERE THE STEP BAR ALREADY HAS ONE
   -----------------------------------------------------------------------------
   Owner: *"we don't need < back now that we have arrows near the stone / size /
   engraving itself"*.

   `.rb_back` and `.rb_step_prev` call the SAME function --
   simple-select-redesign.js:368 and :471 both run rbStepPrev() -- so wherever
   both are on screen the shopper is given one action twice, in two places.

   SCOPED TO STEPS 2 AND 3, because that is the entire overlap. MEASURED at 1728
   across the whole journey (display/visibility of `.rb_back`, against
   `.rb_step_prev`):

     stone      block/hidden    prev arrow hidden    (nothing before STONE)
     stone PDP  none /hidden    step bar not drawn
     2.4 held   block/hidden    prev arrow hidden
     size       block/VISIBLE   prev arrow VISIBLE   <- duplicate
     engraving  block/VISIBLE   prev arrow VISIBLE   <- duplicate

   So the chip only ever paints on the two steps whose arrow does the identical
   thing, and hiding it there removes nothing the shopper cannot still do.

   NOT a blanket hide. At <=991 `section#simple-select-quiz.rb_at_first.rb-stone-held
   .rb_back` (a few hundred lines above) deliberately brings the chip back for
   2.4 -- board 14468:36310 is literally titled "2.4 Back to stone step" -- and
   there it is wired to diamond-search.js's rbShowGrid, which returns to the
   stone GRID rather than stepping the slide. Different control, different
   behaviour, no arrow duplicating it; it stays.

   `visibility`, not `display`. The header is a flex row
   [back 24 | titles | close 28] with the titles centred, and SPEC 8 records the
   board's own left slot as "a 24x24 r4 plate drawn at opacity 0.00 (a reserved
   back button)". Collapsing the box would slide the title block off centre at
   <=991; reserving it is what the board does anyway.

   Unwrapped, because the duplication exists at both widths. `:has()` carries
   its argument's specificity, so this is (2,1,0) and needs no !important to
   settle against the three competing `!important` rules on this chip.
   ============================================================================= */
#simple-select-quiz:has(#ssq_size.active) .rb_back,
#simple-select-quiz:has(#ssq_engraving.active) .rb_back {
    visibility: hidden;
    pointer-events: none;
}

@media (max-width: 991px) {
    /* =========================================================================
       THE METAL / SHAPE PILLS ON THE PREVIEW CARD
       -------------------------------------------------------------------------
       Owner: *"[the] image in shape and metal CTA in image preview can be still
       reduced for the mobile version, like icons -- slightly reduced. Also some
       space between text end and > can be given."*

       MEASURED at 390 with an 18k Rose Gold ring:
         .metal_current_option  [218,214,119,36] flex, gap 6
           .select_metal_option [218,214,119,36]  <- takes the WHOLE pill
             .metal_icon        20 x 20
           .dropdown_icon       0 x 0, position: absolute, 20 x 20 <svg> inside

       THE CHEVRON IS DELIBERATELY A ZERO BOX. Asked the engine rather than
       assuming: `.select_metal_shape span.dropdown_icon` sets `position:
       absolute` and `#simple-select-quiz .quiz-image .select_metal_shape
       span.dropdown_icon` sets width/height 0, i.e. it is an out-of-flow glyph
       pinned by offsets, not a flex item. So it cannot be "given a slot" and
       the gap property never separated anything -- the space has to come from
       the LABEL ROW ending sooner, which is what the right padding below does.

       Specificity is matched, not fought: the rules that actually win are
       `#simple-select-quiz .quiz-image .shape_current_option` (gap 6) and
       `#simple-select-quiz .quiz-image .metal_dropdown_ssq > ... .metal_icon`
       (20px), so these carry `.quiz-image .select_metal_shape` to outweigh
       them without a single !important. The drawer ancestor is in the selector
       for the same reason: the competing rule lives in `_drawers.css`, which is
       enqueued AFTER `_stone.css`, so an equal-specificity selector here loses
       on source order alone -- one more class settles it. The winning rule is
       `... .metal_dropdown_ssq > .metal_current_option > .select_metal_option >
       span.metal_icon`, i.e. (1 id, 5 classes, 1 element); these carry the
       label row and the element too, at (1, 6, 1). */
    #simple-select-quiz .quiz-image .select_metal_shape .metal_dropdown_ssq .metal_current_option .select_metal_option span.metal_icon,
    #simple-select-quiz .quiz-image .select_metal_shape .shape_dropdown_ssq .shape_current_option .select_shape_option span.icon {
        flex: 0 0 17px;
        width: 17px;
        height: 17px;
    }
    #simple-select-quiz .quiz-image .select_metal_shape .metal_dropdown_ssq .metal_current_option .select_metal_option span.metal_icon svg,
    #simple-select-quiz .quiz-image .select_metal_shape .metal_dropdown_ssq .metal_current_option .select_metal_option span.metal_icon img,
    #simple-select-quiz .quiz-image .select_metal_shape .shape_dropdown_ssq .shape_current_option .select_shape_option span.icon svg,
    #simple-select-quiz .quiz-image .select_metal_shape .shape_dropdown_ssq .shape_current_option .select_shape_option span.icon img {
        width: 100%;
        height: 100%;
    }
    /* The label row stops short of the chevron. 22px clears the 20px glyph plus
       a little air, and `box-sizing` keeps the pill's own width unchanged. */
    #simple-select-quiz .quiz-image .select_metal_shape .metal_dropdown_ssq .metal_current_option > .select_metal_option,
    #simple-select-quiz .quiz-image .select_metal_shape .shape_dropdown_ssq .shape_current_option > .select_shape_option {
        box-sizing: border-box;
        padding-right: 22px;
    }
}

/* =============================================================================
   NO PHOTO FOR THIS SETTING + SHAPE -- SAY SO
   -----------------------------------------------------------------------------
   Owner: *"if not available, show placeholders."* simple-select-redesign.js
   flags the wrapper `rb-img-missing` when the ring <img> 404s or decodes to a
   zero-width bitmap. The broken <img> is taken out of the flow and the frame
   draws a neutral ring mark plus a line of copy, on the same cream ground the
   photo would have used -- so the slot keeps its size and the layout around it
   does not move, which a collapsed image would have done.
   ============================================================================= */
/* DESCENDANT, not a child: the photo sits inside `.sss-image-crop` in the metal
   frame, so a `>` matched nothing and the broken <img> stayed on screen beside
   the placeholder -- MEASURED, `display: inline` with the flag already set. */
#simple-select-quiz .sss-metal-image.rb-img-missing img,
#simple-select-quiz .quiz-handpicked-image.rb-img-missing img,
#simple-select-quiz .sss-metal-image.rb-img-missing iframe,
#simple-select-quiz .quiz-handpicked-image.rb-img-missing iframe {
    display: none;
}
#simple-select-quiz .sss-metal-image.rb-img-missing,
#simple-select-quiz .quiz-handpicked-image.rb-img-missing {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--rb-surface-card, #fff);
}
#simple-select-quiz .sss-metal-image.rb-img-missing::after,
#simple-select-quiz .quiz-handpicked-image.rb-img-missing::after {
    content: "Preview not available for this combination";
    display: block;
    max-width: 78%;
    padding: 12px;
    text-align: center;
    font-family: var(--rb-font-body);
    font-size: 13px;
    line-height: 18px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
    /* A ring silhouette above the line, drawn rather than shipped as an asset
       so it cannot 404 the way the photo just did. */
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44' viewBox='0 0 44 44' fill='none'%3E%3Ccircle cx='22' cy='27' r='12' stroke='%23D0D0D0' stroke-width='1.5'/%3E%3Cpath d='M16 13h12l-6 6-6-6Z' stroke='%23D0D0D0' stroke-width='1.5' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat top center / 44px 44px;
    padding-top: 56px;
}

@media (max-width: 991px) {
    /* =========================================================================
       NO "CHOOSE YOUR STONE FROM A VARIETY..." PARAGRAPH ON THE PHONE
       -------------------------------------------------------------------------
       Owner: *"for some reason a text like this is being rendered in mobile view
       on the first slide -- 'Choose your stone from a variety...'. Why is it
       there? Remove it."*

       The node is `.desktop-message.ssq-message`
       (simple-select-quiz.php:263) and its own class says where it belongs:
       `_stone-desktop.css` parks it at >=992, and nothing ever parked it below
       that -- so the one message named for desktop was showing ONLY on phones.
       MEASURED at 390: three lines under the stone card, where 14557:43973's
       `Frame 1171276223` draws a 38px two-line heading block instead.

       PARKED, not `display: none`, for the same reason the desktop rule gives:
       simple-select.js toggles this element's inline `display` (js:1943 writes
       its copy, and the stone-step handlers show/hide it), and an inline style
       outranks a plain author rule -- so `display` is left to the script and the
       box is collapsed instead. Nothing measures it. */
    #simple-select-quiz .desktop-message.ssq-message {
        visibility: hidden;
        height: 0;
        min-height: 0;
        margin: 0;
        padding: 0;
        overflow: hidden;
    }
}

/* ===========================================================================
   [Flow 3] 2.2 — CONTINUE BROWSING SITS WITH THE CTA (phone twin)
   ---------------------------------------------------------------------------
   The reasoning is written out once against the desktop sheet. Phone keeps the
   same arrangement rather than a second one: the link is in the sticky footer
   with the CTA, which is also where the owner asked for it on the stone PDP
   outside the builder, and the header band holds nothing on this screen.
   =========================================================================== */
@media (max-width: 991px) {
  #simple-select-quiz.rb-stone-pdp .rb_stone_link_slot > .rb_stone_back_link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    /* same as desktop: the slot's underline belongs to "Pick a different
       stone"; this link wears it on hover only. */
    text-decoration: none;
  }
  #simple-select-quiz.rb-stone-pdp .rb_stone_link_slot > .rb_stone_back_link:hover,
  #simple-select-quiz.rb-stone-pdp .rb_stone_link_slot > .rb_stone_back_link:focus-visible {
    text-decoration: underline;
  }
  #simple-select-quiz.rb-stone-pdp .simple-select-heading .rb_stone_back_link,
  #simple-select-quiz.rb-stone-pdp .simple-select-heading .close_ssq {
    display: none;
  }
}

/* ===========================================================================
   [Flow 3] THE EXPANDED SPEC COPY LINES UP WITH ITS OWN LABEL
   ---------------------------------------------------------------------------
   Owner: *"on expanding stuff in diamond PDP, and after addition on the stone
   slide stone data -- paragraph alignment is off, should remove padding on
   left."*

   MEASURED at 1440 on the in-builder stone PDP, every row of `Your stone`:
     .accordion-title  x 743   ("Carat Weight", "Cut", "Color", "Certificate")
     .accordion-text   x 743   but padding-left 45
     the copy itself   x 788
   so the body of each row sat 45px right of the label that introduces it, and
   the Certificate row's thumbnail with it. The 45 is the base sheet's indent
   for the site-wide product accordion, where the title carries a 45px marker;
   these rows do not. Removed, not reduced -- the ask is for the copy to start
   on the same x as its label.

   The vertical padding is left exactly as it was: 15px is the gap between the
   title row and its copy, and it is not what was reported.

   Scoped to the builder, so /diamonds/<stone>/ and the product accordions
   elsewhere on the site keep the indent they were written with.
   =========================================================================== */
#simple-select-quiz .accordion-row .accordion-text {
    padding-left: 0;
}

/* ===========================================================================
   [Flow 3] THE STEP ARROWS' HOVER -- phone twin
   ---------------------------------------------------------------------------
   Reasoning is written out once against the desktop sheet. Same swap, same
   timing; only the glyph's box differs (9 x 6 here against 13 x 8), and the two
   URIs below are the resting pair above with the stroke moved from #3E3C39 to
   #0F0E0D and nothing else touched.

   Kept even though hover is a pointer affordance: these chips are real
   <button>s and `:focus-visible` shares the rule, which is what a phone
   keyboard -- or a tablet at this width -- actually uses.
   =========================================================================== */
@media (max-width: 991px) {
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_arrow > span {
    transition: background-color .2s linear;
  }
  /* `:focus-visible` ONLY. The `:hover` twin of each of these is a few lines
     down behind `(hover: hover)` -- see the note there. */
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_arrow:focus-visible > span {
    background-color: var(--rb-surface-card);
  }
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_prev:focus-visible > span {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='6' viewBox='0 0 9 6' fill='none'%3E%3Cpath d='M8.5 3H0.5M0.5 3L2.83 0.67M0.5 3L2.83 5.33' stroke='%230F0E0D' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_next:focus-visible > span {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='6' viewBox='0 0 9 6' fill='none'%3E%3Cpath d='M0.5 3H8.5M8.5 3L6.17 0.67M8.5 3L6.17 5.33' stroke='%230F0E0D' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_arrow:focus-visible {
    outline: 2px solid var(--rb-brand-green);
    outline-offset: 2px;
    border-radius: var(--rb-radius-sm);
  }
}


/* ===========================================================================
   [Flow 3] ...AND `:hover` IS FOR POINTERS, NOT FOR FINGERS
   ---------------------------------------------------------------------------
   Owner, with two crops of the same chip: *"the back arrow button keeps its
   white background after tap. That white bg is the pressed state only -- after
   the tap is released it should return to the default state."*

   A touch browser has no pointer to move away, so it leaves `:hover` applied to
   the last thing tapped until something else is tapped. The chip's resting
   ground is the band's own #E8E2DC and the hover ground is
   `--rb-surface-card` (white), so after every back tap the arrow sat white --
   which reads as a button stuck mid-press, and on the step bar it is the one
   control the shopper has just used.

   `(hover: hover)` is the whole fix: a device whose PRIMARY pointer can hover
   gets the swap, a touchscreen never does. The `:focus-visible` twin stays
   outside this block on purpose -- the note above keeps it for a keyboard at
   this width, and focus has an explicit end where hover does not.

   `:active` is deliberately NOT added as a replacement. The chip navigates away
   on tap, so a press state would paint for the one frame before the step
   changes and then belong to a button that is no longer there.
   =========================================================================== */
/* =============================================================================
   [Flow 3] THE ENGRAVING STEP RESERVES FOR A BAR IT DOES NOT HAVE
   -----------------------------------------------------------------------------
   Owner, pointing under the primary: *"there's a gap below ADD TO BAG in the
   engraving step -- can this gap be reduced?"*

   `section#simple-select-quiz` reserves
   `max(60px, calc(var(--rb-nav-reserve) + 14px))`
   (simple-select-redesign.css). `--rb-nav-reserve` is the live height of
   whichever bottom bar is actually `position: fixed`, and on THIS step there is
   none: `.ssq_bottom_nav` is collapsed to height 0 a few hundred lines above,
   because 14463:35118 has no sticky frame and ships its CTA in flow as
   `.rb_eng_addbag`. So the reserve resolves to 0, the `max()` floor takes over,
   and 60px of clearance is held below a button that nothing overlaps --
   MEASURED at 390: ADD TO BAG ends at 784 with the page ending at 844.

   That floor is the no-fixed-bar tail from the original 100px trackpad reserve
   and it is right everywhere it still applies; it is only wrong here, where the
   last element IS the CTA. 24 is the clearance the step actually needs -- enough
   that the primary does not sit on the edge of the screen, and well inside the
   40% cut the owner already asked for on the flow's other bands.

   Scoped to the slide, so every other state keeps the floor it was measured
   with. */
@media (max-width: 991px) {
  section#simple-select-quiz:has(#ssq_engraving.active) {
    padding-bottom: 24px;
  }
}

@media (max-width: 991px) and (hover: hover) {
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_arrow:hover > span {
    background-color: var(--rb-surface-card);
  }
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_prev:hover > span {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='6' viewBox='0 0 9 6' fill='none'%3E%3Cpath d='M8.5 3H0.5M0.5 3L2.83 0.67M0.5 3L2.83 5.33' stroke='%230F0E0D' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
  #simple-select-quiz .quiz_options > .rb-progress-bar > .rb_step_next:hover > span {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='6' viewBox='0 0 9 6' fill='none'%3E%3Cpath d='M0.5 3H8.5M8.5 3L6.17 0.67M8.5 3L6.17 5.33' stroke='%230F0E0D' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
}

/* ===========================================================================
   [Flow 3] THE HEADER'S CLOSE SITS ON THE TITLE LINE
   ---------------------------------------------------------------------------
   Owner: *"in phone view Build Your Ring, the cross on the header is down --
   align it with Build Your Ring, like a top bar."*

   The header is bootstrap's `.d-flex.align-items-center`, so all three children
   centre on the header's own middle -- and the middle child is TWO lines, the
   title and the setting name. MEASURED at 390: `Build Your Ring` centres at
   y=33, the close at y=45, 12px below it, which reads as the cross belonging to
   the subtitle rather than to the bar.

   `align-self` on the child, because bootstrap's utility is `!important` on the
   parent and cannot be overridden there. 3px is what puts the 28px control's
   centre on the h2's 30px line: the line box opens 2px above the header's
   content box, and (30 - 28) / 2 is the other 1.
   =========================================================================== */
@media (max-width: 991px) {
  #simple-select-quiz .close_ssq {
    align-self: flex-start;
    margin-top: 3px;
  }
}

/* ===========================================================================
   [Flow 3] THE HEADER CLOSE ANSWERS A TAP, AND LOOKS LIKE IT DID
   ---------------------------------------------------------------------------
   Owner: *"in BYR, the tap state for X is not working in the top bar, on phone
   -- not sure, it is missing in Safari iPhone when she comes out and enters the
   flow again."*

   NO PRESSED STATE EXISTED. `.close_ssq` is a <div>, so iOS gives it no tap
   highlight of its own, and the build drew none -- which makes a tap that DID
   land indistinguishable from one that did not, on the one control a shopper
   taps once and then waits. It now inverts its plate while held: the #E4DED8
   chip darkens and the two cross bars go pale.

   `touch-action: manipulation` takes double-tap zoom off the element, so Safari
   dispatches the click immediately instead of holding it ~300ms to see whether
   a second tap is coming -- that delay on a control with no pressed state is
   exactly "nothing happened".

   `z-index` because the header is a flex row and the title block is painted
   after this in source order; on re-entry the quiz re-renders that block, which
   is the one difference between a first open and a second.
   =========================================================================== */
@media (max-width: 991px) {
  #simple-select-quiz .close_ssq {
    position: relative;
    z-index: 2;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    user-select: none;
    transition: background-color 120ms linear;
  }
  #simple-select-quiz .close_ssq:active {
    background-color: var(--rb-text-secondary);
  }
  #simple-select-quiz .close_ssq:active::before,
  #simple-select-quiz .close_ssq:active::after {
    background: var(--rb-surface-page);
  }
  #simple-select-quiz .close_ssq:focus-visible {
    outline: 2px solid var(--rb-brand-green);
    outline-offset: 2px;
  }
}

/* ===========================================================================
   [Flow 3] THE STEP BAR STAYS ON THE STONE PREVIEW -- REVERTED
   ---------------------------------------------------------------------------
   This block used to hide `.rb-progress-bar` and the step arrows whenever
   `.ssq_picked_selection.preview_stone` was present, from the owner's *"the
   progress bar is not needed on the modified diamond PDP."*

   I read "modified diamond PDP" as 2.2 -- the stone's details shown INSIDE the
   builder -- and that was the wrong screen. `.preview_stone` is also on the
   STONE STEP once a stone is held, which is the screen a shopper lands on after
   choosing from advanced search: it has the Ring Details bar, the ring preview,
   `Pick a different stone` and `CONTINUE TO RING SIZE`, and it is a step in the
   flow, so it needs its step bar. Owner, with a screenshot: *"the progress bar
   goes missing... when gone through advanced natural diamond search."*

   Reverted rather than re-scoped: the original request named a screen I cannot
   now identify with confidence, and hiding the bar on the wrong one costs the
   shopper their place in the flow. If it should come off somewhere specific,
   that screen needs naming first.
   =========================================================================== */

/* ===========================================================================
   [Flow 3] THE METAL PILL RESERVED THE CHEVRON'S ROOM TWICE
   ---------------------------------------------------------------------------
   Owner: *"the button for metal selection on the ring slide gets cut off
   weirdly -- it does not show the full text at all, cuts the text completely,
   on changing metal."*

   MEASURED at 390, the 144 pill spends its width like this:
     pill padding        8 + 13   = 21   (the 13 is the chevron's lane)
     option padding-right     22        (the chevron's lane again)
     metal dot + gap     17 + 6   = 23
     left for the label              74
   and `14k White Gold` needs 81 -- scrollWidth 126 against clientWidth 119. So
   it was ellipsised before a shopper ever touched it, and the longer names
   (`18k Yellow Gold`) lose more.

   The 22 is the fault: the chevron is positioned against the PILL, not laid out
   inside the option, so the pill's own 13px right padding is already its lane.
   The option was reserving it a second time. Dropped on the CURRENT pill only --
   inside the open sheet the same class is a full-width row where that padding
   is doing a different job. The board's 144 column is untouched, which keeps
   the 180px hero beside it exactly as drawn.
   ===========================================================================

   `!important` because the rule holding it at 22 could not be named from the
   test rig -- two of the page's stylesheets are cross-origin to it and its
   CSSOM scan comes back empty -- and the plain form MEASURED no change
   (paddingRight still 22px on a selector that `matches()` reports as matching).
   Narrow enough that it cannot reach anything else: the current pill only. */
#simple-select-quiz .quiz-image .metal_current_option .select_metal_option,
#simple-select-quiz .quiz-image .shape_current_option .select_shape_option {
    padding-right: 0 !important;
}

/* ===========================================================================
   [Flow 3] THE METAL PILL'S NAME IS ONE LINE, AND IT DOES NOT SHRINK
   ---------------------------------------------------------------------------
   Owner, repeatedly: *"the metal button from the stone flow, on the stone
   slide, still cuts the text off"*, with a screenshot reading `18k Y`.

   I measured the wrong box twice. `.select_metal_option` and
   `.metal_current_option` both fit their text at every width -- 142 and 188
   against a 142 and 188 scrollWidth -- which is why two passes of widening the
   COLUMN changed nothing. The clipped node is the span INSIDE them:
   `.rb_metal_name`, MEASURED at 35px wide against a 108px scrollWidth, at 1280,
   1440, 1600 and 1920 alike. 35px of `18k Yellow Gold` is exactly `18k Y`.

   Two things make it 35. The span computes `white-space: normal`, so the name
   is breakable and the flex algorithm is free to size it at its longest word
   rather than its content; and it is a shrinkable flex item (`flex: 0 1 auto`)
   in a row that also holds the 20px swatch. The parent is not short of room --
   142 against 20 + 6 + 108 = 134 -- it simply was not required to give the span
   its content width.

   `nowrap` removes the break opportunity and `flex: 0 0 auto` removes the
   licence to shrink, so the name takes the 108 it needs. Scoped to the PILL:
   inside the open sheet the same span is deliberately `display: none`
   (_drawers.css), because the board draws only the karat there.

   It only ever showed after a metal CHANGE, which is why it reads as a
   change-driven bug: simple-select.js rebuilds the pill from an option's
   outerHTML on commit, and rbMetalLabels() wraps the bare text node in this
   span at that point. On first paint the pill has no `.rb_metal_name` at all.
   =========================================================================== */
/* `white-space` is set on the OPTION, not only on the span: MEASURED, the span
   took `flex: 0 0 auto` from the rule below but its computed `white-space`
   stayed `normal`, so the name was still breakable and the flex base size still
   resolved to the longest word. Setting it on the parent makes it inherit no
   matter which rule wins on the span itself. `width: max-content` is the belt to
   that brace -- it pins the box to the text's one-line width outright, so
   neither wrapping nor shrinking can reach it. The parent has the room: 142
   against 20 for the swatch, 6 of gap and 108 of name. */
#simple-select-quiz .metal_current_option .select_metal_option,
#simple-select-quiz .shape_current_option .select_shape_option {
    white-space: nowrap;
}
#simple-select-quiz .metal_current_option .rb_metal_name,
#simple-select-quiz .shape_current_option .rb_metal_name {
    flex: 0 0 auto;
    width: max-content;
    max-width: 100%;
    min-width: 0;
    white-space: nowrap;
}

/* The builder's Ring Details price is not bold either -- same owner note, same
   reason: the total is a <strong> and everything around it is 400. */
#simple-select-quiz .rb_details_bar strong,
#simple-select-quiz .rb_details_row strong,
#simple-select-quiz .rb_details_panel strong {
    font-weight: 400;
}

/* ===========================================================================
   THE STONE SLIDE ENDS WHERE ITS CONTENT ENDS
   ---------------------------------------------------------------------------
   Owner: *"after adding a ring through advanced lab diamond search -- stone
   image and details and dimensions -- there's a lot of space below that. Since
   we've made Continue to Ring Size and Pick a different stone sticky, we can
   make it stick to the bottom so there's no unnecessary space."*
   Vartika: *"since the CTA is fixed to the bottom of the viewport, we don't need
   to pre-clear space for the expanded content, remove it. The accordion should
   size to its content and the list region should scroll if it overflows."*

   MEASURED at 390, reproduced through the real journey (open the ring with
   ?ssq=true, Advanced lab diamond search, Add to Ring from a card -- the quiz
   lands on `rb-stone-held rb-stone-panel`):

     last content bottom   1068
     .ssq_picked_selection margin-bottom  20
     .simple-select-slide  margin-bottom  60
     #simple-select-quiz   padding-bottom 153   (--rb-nav-reserve 129 + 24)
     quiz bottom           1301

   233px of trailing space against an 844 viewport. Only 129 of it is covered by
   the fixed bar, so ~104 was visible dead space at the end of the scroll -- the
   owner's "a lot of space below".

   The 153 STAYS: it is the sticky bar's own measured height plus a gap, and
   without it the last row would sit under the bar permanently. That is not
   pre-cleared space, it is clearance.

   The 80 of margins goes. Those exist to leave room for the accordion to open
   into, which is exactly the pre-clearing Vartika is removing: with the CTAs
   fixed to the viewport the page no longer has to reserve anything, it can grow
   and scroll like any other page.

   Scoped to `.rb-stone-held` and to phone, so the setting-first journey and
   every other step keep the spacing they were drawn with.
   =========================================================================== */
@media (max-width: 991px) {
  #simple-select-quiz.rb-stone-held .ssq_picked_selection,
  #simple-select-quiz.rb-stone-held .ssq_picked_selection.preview_stone {
    margin-bottom: 0;
    /* NO RULE UNDER THE PANEL. Owner, repeatedly: *"space between details and CTA
       in the back-to-stone slide on phone"*, with 14557:50524 and 14557:44412.

       Neither board draws a line there: `Frame 1171276663` (the body) carries no
       stroke and `Frame 1171276552` (the CTA band) carries none on its top edge.
       MEASURED, the live screen had TWO, a pixel apart -- this panel's own
       `border-bottom` at y707 and the last accordion row's at y706 -- so the
       reported "space" is a band of white with a rule sitting in the middle of
       it, which reads as far more separation than the 21px actually between
       them (the board's own gap is 26).

       The GAP was never the problem, which is why nudging it never fixed this. */
    border-bottom: 0;
  }
  /* The last spec row has no next row to separate -- the same trailing rule that
     was taken off the diamond PDP's accordion. ON THE ROW, not on the button:
     MEASURED, `.accordion-row` is what carries `border-bottom: 1px #E4DED8` here,
     and a first pass written against `button.accordion-title` (which is where
     the PDP keeps it) changed nothing. */
  /* ...AND NOT ONLY IN `rb-stone-held` MODE. Owner, for the fourth time and by
     then furious: *"how many times should I say, on phone view there's a line
     under Details and Dimensions -- remove it, in the BYR advanced lab diamond
     search flow, diamond PDP."*

     Every earlier hunt measured the two surfaces I could name -- the standalone
     stone PDP and the YOUR STONE panel -- and both came back with
     `border-bottom: 0px`, which is why I kept reporting I could not reproduce
     it. The screen being reported is neither: it is the slide behind VIEW MORE
     DETAILS inside the advanced search, which is this same panel in
     `rb-stone-pdp` mode. The rule above is scoped to `.rb-stone-held`, so it
     never reached it.

     MEASURED there at 390, having finally walked the real journey (quiz ->
     advanced search -> card -> View More Details): one full-bleed
     `border-bottom: 1px rgb(228,222,216)` on `.ssq_picked_selection.preview_stone`
     at y630, 22px under a Details & Dimensions row whose own borders are 0 --
     which is exactly why measuring the ROW found nothing, four times.

     Mode-agnostic now: no board draws a rule under this panel in any mode, so
     the class in the selector was never doing anything but hiding one. */
  #simple-select-quiz .ssq_picked_selection,
  #simple-select-quiz .ssq_picked_selection.preview_stone {
    border-bottom: 0;
  }
  #simple-select-quiz .ssq_picked_selection .diamond_atts_accordion > .accordion-row:last-of-type {
    border-bottom: 0;
    padding-bottom: 0;
  }
  #simple-select-quiz.rb-stone-held .ssq_picked_selection .diamond_atts_accordion > .accordion-row:last-of-type {
    border-bottom: 0;
    /* ...AND THE SPACE THAT RULE WAS RESERVING. Owner, again: *"I still see a
       gap below Details and Dimensions and the sticky part where Continue to
       Ring Size and Pick a different stone are."*

       Every row carries `padding-bottom: 8px` to stand its divider off the
       text. The last row no longer HAS a divider -- it was removed above -- so
       those 8px are holding a line that is not drawn. MEASURED at 390: text
       bottom 699, button top 727, i.e. 28px of which 8 is this. */
    padding-bottom: 0;
  }
  #simple-select-quiz.rb-stone-held .simple-select-slide.active {
    margin-bottom: 0;
  }

  /* ...AND THE LIST SCROLLS RATHER THAN GROWING WITHOUT LIMIT.
     Vartika: *"the accordion should size to its content and the list region
     should scroll if it overflows."* The accordion itself is untouched -- it
     already hugs, which is why it measures 0 closed -- so this only bounds the
     OPEN spec list: as tall as it needs up to half the viewport, then it
     scrolls inside itself instead of pushing the sticky CTAs further away.
     `dvh` so the measure follows the mobile URL bar, with a px fallback first
     for anything that does not support it. */
  #simple-select-quiz.rb-stone-held .rb_stone_details.is-open .rb_stone_panel,
  #simple-select-quiz.rb-stone-held .rb_stone_specs {
    max-height: 420px;
    max-height: 50dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* =============================================================================
   THE STONE PDP HAS NO PROGRESS BAR -- 14557:44308 `2.2 Stone PDP`
   -----------------------------------------------------------------------------
   Owner: *"in BYR flow, when I go through advanced lab/natural diamond search
   and click on a diamond card, and click on View More Details, it takes me to
   the modified BYR flow diamond PDP. On top there's a part of Build Your Ring
   progress bar -- I want that removed."*

   REPRODUCED, which took three wrong guesses first: the standalone diamond PDP
   (`/lab-grown-diamonds/<sku>/`) has no bar, neither does the stone-first
   `/diamonds/<sku>/`, and neither does the advanced search itself. The screen is
   reached by `View More Details` on a card, which does NOT navigate -- it swaps
   the quiz to `#slide3pdp` and stamps `rb-stone-pdp` on `#simple-select-quiz`.
   MEASURED there at 390: `.quiz_options > .rb-progress-bar` at [0,0,390,48],
   labels Stone / Size / Engraving / Review, sitting directly above the
   Ring-details bar -- exactly the owner's screenshot.

   14557:44308 is a 390 frame and draws this screen as Ring-details bar, then the
   stone's title and price, then the photo. There is no step indicator on it, and
   the Ring-details bar is the chrome that replaces it -- it is already rendering
   here, so nothing has to be added.

   SCOPED TWO WAYS, deliberately. `.rb-stone-pdp` so the bar returns the moment
   the shopper leaves this screen for Stone / Size / Engraving, where it IS the
   design; and <=991 because 14557:44308 is the only frame for this screen and it
   is a phone frame. The desktop stone PDP keeps what it has rather than being
   changed against a board that does not exist.
   ============================================================================= */
@media (max-width: 991px) {
  /* `!important` only because the rule it has to beat carries one:
     `#simple-select-quiz .quiz_options > .rb-progress-bar { display: flex
     !important }` higher in this same sheet. MEASURED -- without it this rule
     matched, lost, and the bar still computed `flex`. */
  #simple-select-quiz.rb-stone-pdp .quiz_options > .rb-progress-bar { display: none !important; }
}

/* =============================================================================
   THE 360 BADGE STAYS INSIDE ITS THUMBNAIL -- the quiz's own strip
   -----------------------------------------------------------------------------
   Owner, with a photo: *"on the stone slide the 360 logo on the preview small
   image kinda oversizes and comes out of the preview image."*

   Same defect, second place. simple-select.css:1030 draws the badge as
   `content: url(360-view-icon.svg)` on an absolutely-positioned `::after` with
   `top: 13px`, `width: 100%` and -- the part that does it --
   `transform: scale(1.33)`. The pseudo has no box of its own, so it renders at
   the SVG's intrinsic size and is then scaled up by a third, which is why the
   green arcs spill past a 52px tile's right and bottom edges.

   stone-first.css already fixes exactly this for `body.sf-stone-pdp`'s strip and
   records the same reasoning; that rule is scoped to the stone-first PDP, and
   the QUIZ renders its own strip (`.quiz-image-video-thumbs .quiz_video_thumb`,
   MEASURED 52x52 at [82,776] on #slide3stone), which it never covered.

   Given the tile's own box and told to fit inside it -- `object-fit` applies
   because `content: url()` makes the pseudo a replaced element -- and the scale
   is dropped. The tile clips as a backstop.
   ============================================================================= */
@media (max-width: 991px) {
  #simple-select-quiz .quiz-image-video-thumbs .quiz_video_thumb { overflow: hidden; }
  #simple-select-quiz .quiz-image-video-thumbs .quiz_video_thumb::after {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    transform: none;
    object-fit: contain;
  }
}

/* =============================================================================
   THE CARAT DISC EXPANDS ON PHONE TOO
   -----------------------------------------------------------------------------
   Owner: *"the carat button animation on mobile, for the behind circle
   expanding, is not on mobile view in the BYR flow on the stone slide."*

   It was not. MEASURED at 390 on the stone slide: `.rb_carat_disc::after`
   computes `content: none` -- the ring does not exist here at all -- and the
   only motion is `transition: background-color .3s` on the disc itself, so the
   sage circle CROSS-FADES in rather than opening out. The expanding ring was
   written in `_stone-desktop.css` inside its `min-width: 992px` block and was
   never carried down.

   Same gesture, same clock as desktop: 280ms on the scale, 180ms on the fade,
   both on that sheet's curves, so the two widths cannot drift.

   THE GEOMETRY IS NOT THE SAME, and it must not be. On desktop the DISC itself
   is sized per carat (`--rb-carat-d`, 13..40) and the ring is drawn 12px larger
   than it. On phone the disc is a fixed 30x30 slot with the carat-sized dot as
   its `::before` (10..24) -- so the ring is simply the slot, at 100%, and no
   per-carat sizing is needed or wanted.

   THREE THINGS THE PSEUDO NEEDS, each of which bit on desktop first:
     - the disc is `position: static` here, so the ring had nothing to position
       against; it is made `relative`, which is also what gives z-index meaning.
     - `z-index: 0` on the ring and `1` on the dot, stated rather than left to
       paint order -- `::after` paints after `::before`, so by default the ring
       would cover the dot. (Desktop's note records why a negative z fails: the
       disc creates no stacking context, so the ring escapes to the ancestor's
       and lands behind the tile's own fill.)
     - the selected disc's own `background` is cleared. It is what used to paint
       the circle instantly; left in place it would paint the same colour under
       a pseudo scaling over it, and nothing would read as moving.
   ============================================================================= */
@media (max-width: 991px) {
  #simple-select-quiz .rb_carat_disc { position: relative; }
  #simple-select-quiz .rb_carat_disc::before { position: relative; z-index: 1; }
  #simple-select-quiz .rb_carat_disc::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 0;
    width: 100%;
    height: 100%;
    border-radius: var(--rb-radius-pill);
    background: var(--rb-brand-sage-strong);
    transform: translate(-50%, -50%) scale(0);
    opacity: 0;
    transition: transform 280ms cubic-bezier(0.2, 0.7, 0.3, 1),
                opacity 180ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  /* the circle is the pseudo's job now, so the disc stops painting it itself */
  #simple-select-quiz .rb_carat_tile.is-selected .rb_carat_disc,
  #simple-select-quiz .rb_carat_tile.active .rb_carat_disc,
  #simple-select-quiz .rb_carat_tile[aria-pressed="true"] .rb_carat_disc {
    background: transparent;
  }
  #simple-select-quiz .rb_carat_tile.is-selected .rb_carat_disc::after,
  #simple-select-quiz .rb_carat_tile.active .rb_carat_disc::after,
  #simple-select-quiz .rb_carat_tile[aria-pressed="true"] .rb_carat_disc::after {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
  @media (prefers-reduced-motion: reduce) {
    #simple-select-quiz .rb_carat_disc::after { transition: none; }
  }
}

/* =============================================================================
   THE STONE LIST STOPS JUST ABOVE THE CTA BAND
   -----------------------------------------------------------------------------
   Owner, with the gap marked in red on a screenshot: reduce the space between
   the last stone card and CONTINUE TO RING SIZE.

   MEASURED at 390, scrolled to the end: last card bottom y684, band top y715 --
   31px of empty page, and another 12 inside the band before the button, so 43
   from the card to the CTA.

   The 31 was two reserves stacked on one band:
     quiz  padding-bottom  max(100px, --rb-nav-reserve + 24)  -> 100, because
           --rb-nav-reserve measured only `.ssq_bottom_nav` and this slide's band
           is `.ssq_all_stone_confirmations` (fixed in simple-select-redesign.js)
     slide margin-bottom   60
     band  height          129
     100 + 60 - 129 = 31.

   Both halves are addressed rather than one trimmed to cancel the other. The
   slide's 60 goes, so the reserve has ONE owner; and the owner is the band's own
   measured height plus 8, not the 24 the other slides use -- the band already
   carries 12px of its own padding above the button, so 8 + 12 reads as the ~20px
   the mark asks for while 24 + 12 would have barely moved.

   DERIVED, NOT PINNED: the band is 129 with the advanced-search link and 93
   without it (moissanite, gemstones), so any fixed number is wrong on one of
   them. 8px of slack holds at both.
   ============================================================================= */
@media (max-width: 991px) {
  #simple-select-quiz:has(#ssq_select_stone.active) .simple-select-slide.active { margin-bottom: 0; }
  section#simple-select-quiz:has(#ssq_select_stone.active) {
    /* 5, down from 8 -- the same 40% the global clearance takes; see the note on
       `section#simple-select-quiz` in simple-select-redesign.css for why the
       reserve itself is not reducible. */
    padding-bottom: calc(var(--rb-nav-reserve, 60px) + 5px);
  }
}

/* =============================================================================
   THE PICKED STONE'S PHOTO IS HALF THE SIZE, AND CENTRED
   -----------------------------------------------------------------------------
   Owner: *"on the stone step -- back to stone in the stone flow, and the usual
   BYR flow i.e. after the advanced diamond search -- can you reduce the image
   size inside, centre it, and reduce the image size by 50 percent?"*

   One element, two layouts, and it filled its holder edge to edge in both:

     390    `.ssq_picked_selection` > `.quiz-handpicked-image`   img 345.5 x 344
            in a 346-wide column -- the photo was the whole slide under YOUR STONE
     1728   the stone tile beside the ring preview               img 401 x 362
            at `object-fit: cover`, i.e. cropped to fill

   `width: 50%` is the ask taken literally against the box the photo is in, so
   the two widths halve by the same rule rather than by two numbers. The auto
   side margins centre it -- the img is made `display: block` here because the
   holder's own `text-align: center` (simple-select.css) cannot centre a block,
   and at 1728 the holder is not a text container at all.

   `contain`, not `cover`. At 1728 the photo was cropped to fill its tile; once
   it is half the width there is no reason to crop it, and a stone photo that
   has been cut off is the one thing this panel exists to show.
   ============================================================================= */
/* ...BUT NOT ON THE IN-FLOW DIAMOND PDP. Owner: *"on advanced diamond search
   the gallery changed to small -- the main image when I click on cards, the
   diamond PDP in the flow shows small gallery images."*

   Half-size was asked for on the STONE STEP, where this photo is a summary of
   a stone already chosen. The slide behind VIEW MORE DETAILS is the same
   element in a different job: it is the gallery of a product page, the thing
   the shopper opened in order to LOOK at the stone, and halving it is the
   opposite of what that screen is for. MEASURED there at 390: a 566x446 photo
   rendered 183x144 in a 366-wide holder -- 50% exactly, this rule.

   `rb-stone-pdp` is the mode the quiz carries on that slide and nowhere else
   (`rb-stone-held` is the stone step's), so excluding it separates the two
   jobs without touching what was asked for. */
#simple-select-quiz:not(.rb-stone-pdp) .quiz-handpicked-image > img,
#simple-select-quiz:not(.rb-stone-pdp) .quiz-handpicked-image > a > img,
/* ...and at the picked-selection's own weight. The block that dresses this
   photo on 390 is `#simple-select-quiz .ssq_picked_selection
   .quiz-handpicked-image > img` -- (1,3,1) against this selector's (1,1,1) --
   and it pins `height: 330px` with `object-fit: cover`. MEASURED with only the
   weaker selector in place: the width halved to 172.75 and the height stayed,
   leaving a 173 x 344 column of cropped stone. Repeated at the same weight and
   declared later in the file, which is what decides between equals. */
#simple-select-quiz:not(.rb-stone-pdp) .ssq_picked_selection .quiz-handpicked-image > img {
    display: block;
    /* FULL WIDTH AGAIN -- THE 50% IS WITHDRAWN.
       Owner, now: *"on the same page, for both stone flow and ring BYR flow,
       the image is also small, like made 50 percent -- idk why it got applied
       to that."*

       It got applied because it was asked for: *"on the stone step -- back to
       stone in the stone flow, and the usual BYR flow after the advanced
       diamond search -- reduce the image size inside, centre it, reduce by 50
       percent."* Same slide, opposite instruction, and the later one is the
       one the owner is looking at a screen to give -- so the photo goes back
       to filling its holder.
       What SURVIVES from that request is the rest of it: the photo is still
       centred (`display: block` + auto side margins) and still `contain`
       rather than `cover`, so nothing is cropped. Only the halving is gone.
       One number here restores it if it is wanted back. */
    width: 100%;
    max-width: 100%;
    /* `!important` ON THE HEIGHT ALONE. The photo's height is written as an
       INLINE style while the stone is chosen, so it is not a rule to out-specify
       -- MEASURED with everything else landing: width 172.75 and `object-fit`
       both took, and the height stayed frozen at 344, the value it had when the
       image was still full-width and square. An author `!important` is the only
       thing that outranks a non-important inline declaration. Nothing else here
       needs it. */
    height: auto !important;
    margin-left: auto;
    margin-right: auto;
    object-fit: contain;
}

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

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

   The `.rb_dd_row` children are excluded so the spec rows keep their own
   measurements rather than being re-stated here.
   ============================================================================= */
#simple-select-quiz .ssq_picked_selection .diamond_atts_accordion .accordion-text,
#simple-select-quiz .ssq_picked_selection .diamond_atts_accordion .accordion-text > p:not(.rb_dd_row) {
    font-size: 14px;
    line-height: 22px;
}


/* =============================================================================
   THE CTA FOLLOWS THE CONTENT WHEN THERE IS NOTHING TO SCROLL
   -----------------------------------------------------------------------------
   Owner, with a screenshot of the back-to-stone slide: *"after Measurement
   5.08 x 5.12 x 3.15 the page is blank for roughly 220-240px before CONTINUE TO
   RING SIZE. That's about a fifth of the screenshot's height."*

   MEASURED at 615 x 1312 (a tall window, which is why this never showed at
   390 x 844 where I kept checking -- there the content overflows and the gap is
   17px):

     section#simple-select-quiz   height 1012   top 0
     viewport                     1312
     .ssq_bottom_nav              position: fixed, pinned at 1210

   so the section ENDS at 1012 and the bar is painted 198px below it, against
   the bottom of the screen. The content is top-aligned in a page shorter than
   the viewport while the bar is anchored to the viewport -- nothing is wrong
   with either on its own, and the space between them belongs to neither.

   `fixed` is the wrong anchor for a bar that is only sometimes needed. `sticky`
   is the same behaviour where it matters and the right one where it does not:
   with overflow it pins to the bottom of the screen exactly as before; without
   overflow it sits in flow, immediately after the last line. The column's
   `margin-top: auto` is what holds it at the foot of a short page rather than
   letting it ride up under the content.

   The page's own bottom padding goes with it. That reserve exists to keep the
   last line clear of a bar that floats OVER the page; a sticky bar occupies
   real space, so keeping the reserve would re-open the hole this closes.
   ============================================================================= */
@media (max-width: 991px) {
  /* NO FLEX COLUMN, AND THAT IS THE POINT.
     The first cut of this block made the section a flex column with
     `flex: 1 0 auto` on the body and `margin-top: auto` on the bar, meaning to
     "hold the bar at the foot of a short page". MEASURED afterwards, that is
     the BUG restated: a column stretched to 100svh with the bar pushed to its
     end puts the bar back at the bottom of the screen with the content still
     ending high above it. The flex declarations happened not to win, which is
     the only reason the fix worked -- so they are removed rather than left as a
     trap for whoever notices they are inert and "repairs" them.

     `sticky` alone does the whole job: in flow directly after the last line
     when there is nothing to scroll, pinned to the bottom of the screen when
     there is. */
  /* REVERTED TO `fixed`. Owner, immediately after the sticky change shipped:
     *"the sticky section is no longer sticky -- Continue to Ring Size and Pick
     a different stone are no longer sticky."*

     `sticky` removed the gap by letting the bar sit in flow when the page is
     short, and that is exactly what cost the pinning the shopper relies on
     while the page is long. MEASURED in a desktop engine it still pinned, so
     this did not show here; on the owner's device it did not, and the pinning
     is the behaviour the flow is built around -- it is how the CTA stays
     reachable through a long spec list.

     So the bar is anchored again, and the gap on a tall viewport comes back
     with it. The two cannot both be solved by moving the BAR: on a page
     shorter than the screen, a bar pinned to the bottom necessarily leaves
     space above it. The fix that satisfies both is to stop the page being
     short -- let the stone panel take the leftover height instead of the gap
     taking it -- which is a change to the CONTENT column, not to this bar, and
     is not something to land in the same breath as a revert. */
  body #simple-select-quiz:has(#ssq_size.active) .ssq_bottom_nav,
  body #simple-select-quiz.rb-stone-panel:has(#ssq_select_stone.active) .ssq_bottom_nav {
    position: fixed;
    bottom: 0;
  }
}

/* =============================================================================
   ...AND THE CONTENT COLUMN TAKES THE LEFTOVER HEIGHT, SO THERE IS NO GAP LEFT
   FOR THE BAR TO SIT BELOW
   -----------------------------------------------------------------------------
   This is the change the note above says is the real fix, now that the owner has
   asked for it on all three steps: *"see the gap between the sticky bottom bar
   and the end of the ring size scroller"* and *"on the engraving step the ADD TO
   BAG is not sticky at all"*.

   The first and larger half of both gaps was a DOUBLE RESERVE and is fixed in
   settings-picker.css -- `body.sf-flow-pdp` reserved 126px for the PDP's own
   footer while `section#simple-select-quiz` reserved another 107 for the
   overlay's bar, 233 between them for one 102px bar. MEASURED at 390 x 844
   after that change:

                        content ends    bar top    gap
     back-to-stone        722            742        20     <- done, it overflows
     ring size            654            742        88
     engraving (CTA)      593            844       251     <- in-flow CTA

   What is left is not a reserve: the page is now SHORTER than the screen
   (docH 844 = vh 844 on both), so the space belongs to neither the content nor
   the bar, exactly as the note above says. The bar cannot move -- that was tried
   and cost the pinning -- so the column grows instead.

   THE SLACK IS SPREAD BETWEEN THE BLOCKS, NOT POURED INTO ONE. Two candidates
   were tried and measured first, and both are worse:

     the size WHEEL -- wrong, and quietly so. Its 200px is 39+39+44+39+39 and
     `--rb-size-runway` is (200-44)/2, so growing it without re-deriving the
     runway moves the centre band off the centred row and leaves the first and
     last size unreachable (see _size.css sections 3-5).

     the ring PREVIEW -- tried, screenshotted, reverted. `flex: 1 1 auto` on
     `.quiz-image` does grow the card (MEASURED 150 -> 224 on size and
     150 -> 341 on engraving) but `.sss-metal-image` and `.sss-image-crop` are a
     fixed 150px crop window, so the photo does NOT grow with it: all that
     arrives is white space above and below the ring inside a taller card.

   `justify-content: space-between` asks for none of that. Every block keeps the
   height it was designed at and the leftover goes into the space BETWEEN them,
   so the last block ends where the bar begins -- which is the whole complaint.
   `.rb-progress-bar` is absolutely positioned into the header at this width
   (MEASURED at y80 while the details bar starts at 136), so it is out of flow
   and takes no share.

   NOTHING SHRINKS. `flex-wrap: nowrap` is needed so one tall child cannot start
   a second column, and with it the default `flex-shrink: 1` would squeeze every
   child when the content is TALLER than the screen -- which is the normal case
   on the stone panel. So each item is pinned at `flex-shrink: 0` and only the
   preview may grow. Where there is no free space the grow is a no-op, which is
   why the back-to-stone slide is left exactly as it measures today.

   `.col-12` and `.quiz-image-conatiner` are `display: contents` at this width,
   so the flex items are these grandchildren and not the columns -- flex
   properties on a `display: contents` box do nothing.
   ============================================================================= */
@media (max-width: 991px) {
  /* `!important` ON display, AND ONLY THERE. simple-select.js OPENS the quiz by
     writing `style="display: block"` on the section -- an inline declaration, so
     no selector of any length can outrank it. MEASURED with the rule in and the
     `!important` out: min-height took (section 844) and `display` came back
     `block`, so the column never existed and nothing grew. Everything else in
     this block wins on specificity and is left alone. */
  /* ONLY WHILE THE QUIZ IS ACTUALLY OPEN -- `!important` HERE WAS BEATING
     jQuery's `.hide()` AND KEEPING THE BUILDER ON SCREEN AFTER A PURCHASE.
     Owner: *"add to bag on the engraving step ... it's returning to this"*,
     then *"it's being added to cart, but it returns to the screen, so it's a
     state issue"*, and the decisive one: *"this does not happen on desktop but
     only on phone."*

     This whole block is inside `@media (max-width: 991px)`, which is the
     phone-only half of that split. The close handler DOES hide the builder
     (simple-select.js:1956, `$('section#simple-select-quiz').hide()`), but
     `.hide()` writes an inline `display: none` and an `!important` declaration
     outranks it. After a completed add the quiz resets its step, and MEASURED
     on dev-1 the slide it lands on is `ssq_size` -- so `:has(#ssq_size.active)`
     matches, `display: flex !important` wins, and the builder stays on screen
     with its own chrome rendered inline over the product page: `quizVisible:
     true`, `.sss-next` still reading CONTINUE TO ENGRAVING, `.rb_nav_note`
     still reading "We offer free resizing for life!". The ring was in the bag
     the whole time; only the screen was wrong. Desktop never had the rule, so
     desktop always closed correctly.

     `body.ssq-active` is the existing open/closed signal -- the same class the
     close handler removes two lines before it hides the section -- so gating on
     it leaves the layout identical while the builder is open and gets out of
     the way the moment it is closed. */
  body.ssq-active #simple-select-quiz:has(#ssq_size.active),
  body.ssq-active #simple-select-quiz:has(#ssq_engraving.active) {
    display: flex !important;
    flex-direction: column;
    min-height: 100svh;
  }
  #simple-select-quiz:has(#ssq_size.active) > .container,
  #simple-select-quiz:has(#ssq_engraving.active) > .container {
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
  }
  #simple-select-quiz:has(#ssq_size.active) > .container > .row,
  #simple-select-quiz:has(#ssq_engraving.active) > .container > .row {
    flex: 1 0 auto;
    flex-wrap: nowrap;
    justify-content: space-between;
  }
  /* ENGRAVING PACKS FROM THE TOP; ONLY SIZE SPREADS.
     Owner, on a phone: *"in this engraving step, how did engraving come down?"*
     -- a tall empty band between the ring card and the engraving field.

     `space-between` is right for SIZE: that step's children are the card and a
     tall size wheel, and spreading them is what closed the gap above the sticky
     bar. ENGRAVING was given the same rule, but its children are much shorter
     and its bottom bar is not sticky at all -- `.ssq_bottom_nav` is explicitly
     `visibility: hidden; height: 0` on this step (:2373), because the board
     draws no sticky frame here. So the whole field-plus-symbols-plus-CTA block
     was being pushed to the far end of a `min-height: 100svh` column and all the
     slack collected in one place: directly under the ring card.

     Packing from the top puts the field back under the card where the board has
     it and leaves the slack at the bottom, where there is nothing to separate. */
  #simple-select-quiz:has(#ssq_engraving.active) > .container > .row {
    justify-content: flex-start;
  }
  #simple-select-quiz:has(#ssq_size.active) .rb_details_bar,
  #simple-select-quiz:has(#ssq_size.active) .rb-progress-bar,
  #simple-select-quiz:has(#ssq_size.active) .simple-select-slide,
  #simple-select-quiz:has(#ssq_engraving.active) .rb_details_bar,
  #simple-select-quiz:has(#ssq_engraving.active) .rb-progress-bar,
  #simple-select-quiz:has(#ssq_engraving.active) .simple-select-slide {
    flex-shrink: 0;
  }
  #simple-select-quiz:has(#ssq_size.active) .quiz-image,
  #simple-select-quiz:has(#ssq_engraving.active) .quiz-image {
    flex-shrink: 0;
  }
}
