/* =============================================================================
   [Flow 3] THE HEART IN THE FIELD IS THE DESIGN'S HEART, ON EVERY DEVICE
   -----------------------------------------------------------------------------
   Owner, forwarding the thread: *"Q. Why is the heart so morphed? Can this be
   fixed?"* -- and his own reply in it: *"I've checked on phones and different
   OS and devices, it depends on the ASCII set it allows too."* That reading is
   exactly right, and this is the mechanism behind it.

   The six symbol BUTTONS are artwork -- `engraving-glyph-heart-v2.svg` and
   friends, drawn as background images -- so they are identical everywhere. The
   FIELD is not: pressing a button types a real character into
   `#ssq_eng_field`, U+2764 followed by U+FE0E (simple-select-quiz.php), and the
   field is set in `--rb-font-body`, which has no heart in it.

   MEASURED rather than assumed, via CSS.getPlatformFontsForNode on the field
   with four hearts in it:

     computed font-family   FoundersGrotesk, sans-serif
     fonts actually used    FreeSans   (glyphCount 4)

   So all four hearts came from a substitute the page never asked for, chosen by
   the OS from whatever it happened to have. `document.fonts.check()` is no help
   and is worth knowing about: it returns TRUE for FoundersGrotesk here, because
   it answers "is the family loaded", not "does it have this codepoint". A
   different device has a different first candidate, which is exactly why the
   shape changes from phone to phone.

   The fix is to stop asking the device. `da-engraving-symbols.woff2` is built
   from the theme's own `engraving-glyph-heart-v2.svg` -- the same path the
   button draws -- so the glyph in the field is the glyph in the design. 492
   bytes, three codepoints, nothing else in it.

   `unicode-range` is what keeps it harmless: the face is only ever consulted
   for the heart (U+2764), its text-suit twin (U+2665), and the variation
   selector that follows them (U+FE0E, mapped to an empty zero-width glyph so it
   cannot fall through and draw a box). Every letter the shopper types still
   comes from FoundersGrotesk.

   Geometry: the SVG's 18x16 box is scaled to 700/1000 em and placed ON the
   baseline, so the heart stands at about cap height beside the text instead of
   riding above or below it; 70 units of side bearing each side.

   The other five symbols are raster in the design (cross, infinity, crescent
   and dot are PNG exports; only heart and the star are vector), so they cannot
   be built the same way and still fall back per device. The heart is the one
   that was reported and the one that is typed most.
   ============================================================================= */
@font-face {
  font-family: 'DAEngravingSymbols';
  src: url("../../../assets/fonts/da-engraving-symbols.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: block;
  unicode-range: U+2665, U+2764, U+FE0E;
}

/* =============================================================================
   Ring builder — ENGRAVING step, MOBILE
   -----------------------------------------------------------------------------
   Figma file Ex10uQ9OY3OuzSPi4g2hPb, section 14463:32244 "[Mobile UI] PDP ring
   builder refresh". Frames implemented here:

     14463:35118  1.3 Engraving  (390 x 848)   SPEC.md L10536-11223
     14463:35335  2.5 Engraving  (390 x 848)   SPEC.md L11224-11911
                  Byte-identical to 35118 apart from the frame name, so it is
                  built once. (Verified: the two SPEC blocks differ only in the
                  `## <id> — <name>` heading and the node ids.)

   All y coordinates quoted below are the raw SPEC values. SPEC y is 46px larger
   than the real screen y because every frame carries the 390x46 iPhone
   status-bar mockup (14463:35182 > I14463:35182;13533:33717). Every measurement
   used here is a DIFFERENCE between two SPEC y values, so the 46px offset
   cancels and no rule depends on it.

   WHAT THIS FILE OWNS
   -------------------
   The Engraving block only: 14463:35136 > 14463:35137 (heading + sub-head) and
   14463:35141 > :35142 > :35143 (the text box and the six symbol tiles).
   The setting card above it (14463:35119), the progress bar (14463:35185), the
   header and the sticky footer are shared chrome drawn on 14 of the 25 frames
   and belong to the files that own that chrome. Nothing here touches them.

   CONTRACT — WHY THIS FILE ONLY EVER ADDS DECLARATIONS
   ----------------------------------------------------
   simple-select.js reads the DOM as state. Nothing here changes markup, and
   nothing here sets `display:none` on an element the script reads.

     * simple-select.js:400 —
         if($('.ssq_eng_field').css('display') != "none" && custom_eng != "")
       A COMPUTED STYLE gates whether the engraving reaches the order. If that
       field ever computes to display:none, rings ship with no engraving and
       nothing looks broken. #ssq_eng_field is given `display:block` explicitly
       below and is never hidden by any rule in this file — the design draws it
       on every engraving state, so no hidden state is needed at all. Should a
       future state need to hide it, use visibility:hidden / opacity:0 / a zero
       box / off-screen positioning — NEVER display:none.

     * simple-select.js:2231 — the `.eng_symbol` click handler dispatches on
         $(this).attr("class").split(" ")[1]
       i.e. the SECOND class name (heart / cross / infinity / star / crescent /
       dot). Class names and their order are never touched here. :2225 also
       reads $(this).html() as a fallback, so the unicode glyph text node is
       kept in the DOM — only its rendered size is zeroed (font-size:0 +
       color:transparent), never display:none.

     * #charCounter is written by product-single.js ("n/27"). It is repositioned,
       never hidden.

   Reordering is done with `display:contents` (§4), never by assuming a
   different DOM.

   EVERY NUMBER BELOW IS A FIGMA REST API VALUE, node ids cited inline.
   Letter-spacing really is -0.20999999344348907px in the source; it is written
   as -0.21px and is already tokenised as --rb-ls-tight in
   ../simple-select-redesign.css.
   ============================================================================= */

@media (max-width: 991px) {

  /* ===========================================================================
     1. THE COLUMN
     14463:35136 "Engraving" is 345 wide at x=22 in a 390 frame; its inner
     builder 14463:35137 is 344 wide at the same x. 390 - 345 = 45, split
     22 left / 23 right in the source — SPEC.md's board-wide conventions note
     calls that sub-pixel drift rather than intent, so the column is centred.
     max-width keeps it honest on the 320px-class viewports the board never drew.

     _stone.css puts .quiz_options into `display:contents` and gives both
     `.desktop-message` and `.simple-select-slide` order 4, so the heading and
     the slide are consecutive items of the same flex column, in DOM order.
     =========================================================================== */
  #ssq_engraving.simple-select-slide {
    padding-left: 0;
    padding-right: 0;
    text-align: left;              /* the slide carries .text-center; the design
                                      left-aligns everything in this block, and
                                      text-align is inherited by <input> */
  }
  #ssq_engraving .simple-select-slide-content {
    width: min(344px, calc(100vw - 44px));                  /* 14463:35137 / :35143, the block the design
                                      actually draws. Its parent 14463:35136 is
                                      345 only because it also holds the 346-wide
                                      CTA (§6a), which the DOM does not put on
                                      this slide. */
    max-width: 100%;
    /* x=22, pinned.  Every node on 14463:35136 starts on 22 -- the frame, the
       sub-head, the six tiles (22/82/142/202/262/322) and the 0/27 counter
       (324.2).  An even 344 in a 390 board centres on 23, a whole pixel right
       of all of them and outside the +-0.5 tolerance.  (The 345-wide SIZE
       column centres on 22.5 and is left alone, per _size.css §1.)  The right
       margin stays auto: 390 - 22 - 344 = 24. */
    /* ...UP TO 390. ABOVE IT THE COLUMN CENTRES WITH THE CARD ABOVE IT.
       Owner, on a 430pt phone: the engraving box and ADD TO BAG sitting a score
       of pixels LEFT of the Ring Details bar and the ring card. They were: a
       flat `margin-left: 22px` never moves, while every other block on the
       screen is a 346 column with auto margins that starts centring the moment
       the viewport passes the 390 the boards are drawn at. MEASURED on the
       engraving step, bar and card against the field and the CTA:

                        390                 430
         bar / card     x 22  w 346         x 42  w 346
         text box       x 22  w 344         x 22  w 344   <-- 20 adrift
         ADD TO BAG     x 22  w 346         x 22  w 346   <-- 20 adrift

       `max(22px, (100% - 346px) / 2)` keeps the pin: at 390 the second term is
       exactly 22, so the board's deliberate 22 (rather than the 23 an even 344
       would centre on) is unchanged to the pixel, and from there up the column's
       left edge tracks the card's. The CTA is left-set inside this column and
       follows it without a rule of its own. 346, not this column's own 344,
       because the card is what it has to line up with. */
    margin-left: max(22px, calc((100% - 346px) / 2));
    margin-right: auto;
  }


  /* ===========================================================================
     2. HEADING + SUB-HEAD — 14463:35138
     AL:VERTICAL gap=4:
       14463:35139  "Complimentary Engraving  "  Canela 300 18/19 UPPER #0F0E0D
       14463:35140  sub-head                     Founders 400 14/17     #0F0E0D
     14463:35137 AL:VERTICAL gap=26 -> 26px down to the text box (y 457 -> 483).
     Setting card bottom (231 + 150 = 381) -> heading top 400 = 19px above.

     THE TITLE HAS NO ELEMENT IN THE DOM. The nearest thing is
     `.desktop-message.ssq-message`, which sits immediately above the slides in
     `.quiz_options` and whose copy simple-select.js rewrites per step (:1489
     for engraving). The title is therefore rendered as that element's ::before,
     which makes the rendered order read exactly as the design: title, sub-head,
     content.

     WHY NOT MARKUP: adding an <h3> would be a markup change. Follow-up §6(b):
     a real heading element is the accessible fix; ::before content is invisible
     to most assistive tech.

     `.ssq-message` is a JS WRITE target ($('.ssq-message').text(...)) and
     simple-select.js:1492/1677 toggles its inline `display`. Nothing below
     touches its display.
     =========================================================================== */
  #simple-select-quiz:has(#ssq_engraving.active) .quiz_options > .desktop-message.ssq-message {
    width: min(344px, calc(100vw - 44px));                  /* 14463:35138 — the wrap width the design's
                                      two-line sub-head is measured at */
    max-width: 100%;
    /* x=22, pinned.  The column is 344 wide against a 390 board, so `auto`
       centred it on 23 -- 1px right of every node in 14463:35136 (frame,
       sub-head, tiles, counter all start on 22) and outside the +-0.5
       tolerance.  The right margin stays auto: 390 - 22 - 344 = 24. */
    margin-left: 22px;
    margin-right: auto;
    margin-top: 19px;              /* setting card bottom 381 -> title top 400 */
    margin-bottom: 26px;           /* 14463:35137 AL gap=26 */
    text-align: left;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 14px;               /* 14463:35140 */
    line-height: 17px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary); /* 14463:35140 fill #0F0E0D — NOT the
                                      #3E3C39 secondary used for most body copy */
  }
  /* The <p> exists on first render and is destroyed by the first .text() call;
     both shapes are covered. */
  #simple-select-quiz:has(#ssq_engraving.active) .quiz_options > .desktop-message.ssq-message p {
    margin: 0;
    font-size: inherit;
    line-height: inherit;
    letter-spacing: inherit;
    color: inherit;
  }
  #simple-select-quiz:has(#ssq_engraving.active) .quiz_options > .desktop-message.ssq-message::before {
    content: "COMPLIMENTARY ENGRAVING";   /* 14463:35139, case=UPPER */
    display: block;
    margin-bottom: 4px;                   /* 14463:35138 AL gap=4 */
    font-family: var(--rb-font-display);
    font-weight: 300;
    font-size: 18px;
    line-height: 19px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-primary);        /* #0F0E0D */
  }


  /* ===========================================================================
     3. THE BUILDER BOX — 14463:35143
     AL:VERTICAL gap=22, 344 wide:
       14463:35144  text box    344 x 48   (y 483)
       14463:35148  symbol row  344 x 44   (y 553)   SPACE_BETWEEN, six 44x44
     48 + 22 + 44 = 114 = 14463:35143 height.

     The DOM prints the six symbols as TWO `.engraving_symbols` rows of three;
     the design draws ONE row of six, in the same order (heart, cross, infinity,
     star, crescent, dot). `display:contents` promotes the six buttons to items
     of this flex container without moving a node.

     display:contents is NOT display:none — the element keeps a computed display
     of "contents" and its children keep their own boxes. Nothing in
     simple-select.js reads `.engraving_symbols`.

     Six 44px tiles across 344 leaves 344 - 264 = 80 = 5 x 16, so
     `space-between` with a 16px column-gap reproduces the row exactly and the
     gap only matters if a viewport narrower than the board forces a wrap.
     =========================================================================== */
  #ssq_engraving .sss_swatches_engraving_container {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
    width: min(344px, calc(100vw - 44px));                  /* 14463:35137 / :35143 */
    max-width: 100%;
    margin: 0 auto;                /* base rule is `20px auto`; 14463:35143 puts
                                      the text box flush at the top.  The x=22
                                      origin is set on the 344-wide
                                      .simple-select-slide-content parent. */
    row-gap: 22px;                 /* 14463:35143 AL gap=22 */
    /* 0, not 16. The row is already space-between, so at the authored 344px width the
       free space (344 - 6x44 = 80) divides into exactly the 5 x 16px gaps the design
       draws. Declaring 16px as well makes it a MINIMUM, which is what pushed the sixth
       tile past the edge on a 360px phone. */
    column-gap: 0;
    text-align: left;
  }
  #ssq_engraving .sss_swatches_engraving_container .engraving_symbols {
    display: contents;
  }

  /* The input's wrapper carries an inline `position:relative` (the anchor for
     #charCounter). Matched two ways so it still resolves without :has support. */
  #ssq_engraving .sss_swatches_engraving_container > div:first-child,
  #ssq_engraving .sss_swatches_engraving_container > div:has(> .ssq_eng_field) {
    flex: 0 0 100%;
    width: 100%;
  }


  /* --- 3a. The text box — 14463:35144 / :35145 -----------------------------
     344 x 48, fill #FDFAF8, 1px INSIDE stroke #E4DED8, r=4.
     Value type 14463:35146: Founders Grotesk 400 16/30 #3E3C39, drawn at
     x=32.12 y=492 inside a box at x=22 y=483 -> 9px top, 10.12px left.
     Right padding clears the counter: 344 - (324.2 - 22) = 41.8px.
     The stroke is drawn as an inset shadow rather than a border, so
     9 + 30 + 9 = the exact 48px height with no border-box arithmetic.

     THIS ELEMENT MUST NEVER COMPUTE TO display:none — simple-select.js:400
     gates the whole engraving value on it. See the contract at the top.        */
  #ssq_engraving input#ssq_eng_field {
    display: block;                /* never `none` — js:400 tripwire */
    box-sizing: border-box;
    width: 100%;
    height: 48px;                  /* 14463:35145 */
    margin: 0;                     /* the theme's base input rule adds a top
                                      margin; 14463:35143 puts the box flush */
    padding: 9px 40px 9px 10.12px;   /* right pad follows the counter in */
    border: 0;
    border-radius: var(--rb-radius-sm);                    /* r=4 */
    background: var(--rb-surface-input);                   /* #FDFAF8 */
    box-shadow: inset 0 0 0 var(--rb-stroke) var(--rb-border-subtle);  /* #E4DED8 w=1 INSIDE */
    /* the symbol face is unicode-range'd to the heart alone, so only that
                                      character comes from it -- see the @font-face
                                      note in _engraving.css */
    font-family: 'DAEngravingSymbols', var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 30px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);                       /* #3E3C39 */
    caret-color: var(--rb-text-secondary);                 /* 14463:35146 IS the caret */
  }
  /* MISSING FROM SPEC: the frame is drawn with an empty field showing only a
     caret, so the board carries no placeholder colour. Matched to the field's
     own text colour rather than invented. */
  #ssq_engraving input#ssq_eng_field::placeholder {
    color: var(--rb-text-secondary);
    opacity: 1;
  }

  /* 14463:35147 "0/27" — same Founders 400 16/30 #3E3C39, at x=324.2 y=492,
     box 33.25 wide.
       right = 344 - (324.2 - 22) - 33.25 = 8.55
       top   = 492 - 483 = 9
     product-single.js writes exactly this "n/27" string. */
  #ssq_engraving span#charCounter {
    position: absolute;
    top: 9px;
    /* Anchored on the RIGHT edge, not on x=324.2, so it tracks the field if the
       column is ever narrower than 344. min-width restores the design's exact
       box, and with the node's own align=LEFT that puts the glyphs back on
       x=324.2 in the drawn "0/27" state: 344 - 8.55 - 33.25 = 302.2 = 324.2-22.
       A two-digit count grows the box leftward into the 41.8px the field's
       right padding already reserves, instead of past the field's edge. */
    /* HARD RIGHT, 8px OFF THE EDGE. Owner: *"can we move 0/27 towards [the]
       right edge of the text field, with some padding to its right though --
       but lesser, so that it does not literally touch it, maybe 6 to 10px?"*
       It was pinned by the board's own box: a wide `min-width` slot that the
       text sat at the LEFT of, so the glyphs ended far from the edge --
       MEASURED at 1416, `right: 18.69px` on a 72.69px box left-aligned, which
       puts "0/27" about 63px in. Dropping the slot and right-aligning makes the
       offset mean what it says, so 8 is 8. */
    right: 8px;
    min-width: 0;
    text-align: right;
    white-space: nowrap;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 16px;
    line-height: 30px;
    letter-spacing: var(--rb-ls-tight);
    color: var(--rb-text-secondary);
  }


  /* ===========================================================================
     4. THE SIX SYMBOL TILES — 14463:35149 .. :35168
     Each tile: 44 x 44, fill #E4DED8, r=4,
                DROP_SHADOW off=(-2,2) blur=1 spread=0 #000000 @0.25
     Tile x positions 22 / 82 / 142 / 202 / 262 / 322 (pitch 60 = 44 + 16).

     The unicode glyph in each button is replaced by the exported artwork. The
     text node is NOT removed and NOT display:none'd — only its rendered size is
     zeroed, because simple-select.js:2225 reads $(this).html() as a fallback.
     =========================================================================== */
  #ssq_engraving button.eng_symbol {
    width: 44px;
    height: 44px;
    flex: 0 0 44px;
    padding: 0;
    border: 0;
    border-radius: var(--rb-radius-sm);                    /* r=4 */
    background-color: var(--rb-border-subtle);             /* #E4DED8 — the shared
                                                              token file names this
                                                              hue --rb-border-subtle;
                                                              --rb-brand-sage is the
                                                              DIFFERENT #D8DDCA */
    background-repeat: no-repeat;
    box-shadow: -2px 2px 1px 0 var(--rb-shadow-base);      /* off(-2,2) blur 1
                                                              spread 0 #000 @0.25 */
    font-size: 0;
    line-height: 0;
    color: transparent;
  }

  /* background-position is the glyph's exact frame-relative offset inside its
     44x44 tile; background-size is the glyph's exact drawn size.
     The mobile SPEC dump rounds raster sizes to 2dp (23.51 / 25.78 / 26.56);
     the unrounded values below are the same nodes as reported on the desktop
     board (14465:40550 / :40553 / :40561), where the dump keeps full float
     precision. Same asset, same drawn size. */
  /* GLYPH ASSETS RE-EXPORTED. The three raster marks were the RAW 700x700
     sources placed in Figma, stretched into non-square boxes -- 23.51x19,
     25.78x16, 26.56x23 -- so every one of them was distorted, which is the odd
     edges that got reported. The nodes are RECTANGLEs with an IMAGE fill at
     `scaleMode: STRETCH` and an imageTransform that CROPS the source
     vertically (0.808 / 0.621 / 0.866); the build ignored that transform and
     squashed the whole square instead.

     These are the nodes as FIGMA RENDERS them, exported at 4x -- crop applied,
     aspect correct: 95x76, 104x64, 107x92 against node ratios 1.237 / 1.611 /
     1.155. They are also 433 / 1504 / 1710 bytes against the old 17.5 / 26.5 /
     29.4 KB. `-v2` filenames because these assets are served
     `immutable, max-age=2419200` -- same name would keep the old ones for 28 days.

     NOT converted to SVG, and they cannot be from this source: those three are
     raster IN THE DESIGN. Only heart (VECTOR) and star (GROUP of two VECTORs)
     are vector, and both re-exported byte-for-byte identical -- they were
     already correct. */
  #ssq_engraving button.eng_symbol.heart {
    /* 14463:35151 Vector 18 x 16 at (33,568); tile at (22,553) */
    background-image: url("../../../assets/media/ringbuilder/engraving-glyph-heart-v2.svg");
    background-size: 18px 16px;
    background-position: 11px 15px;
  }
  #ssq_engraving button.eng_symbol.cross {
    /* 14463:35154 image 23.5124988556 x 19 at (91,565); tile at (82,553) */
    background-image: url("../../../assets/media/ringbuilder/engraving-symbol-cross-v2.png");
    background-size: 23.51249885559082px 19px;
    background-position: 9px 12px;
  }
  #ssq_engraving button.eng_symbol.infinity {
    /* 14463:35157 image 25.7777767181 x 16 at (151,568); tile at (142,553) */
    background-image: url("../../../assets/media/ringbuilder/engraving-symbol-infinity-v2.png");
    background-size: 25.77777671813965px 16px;
    background-position: 9px 15px;
  }
  #ssq_engraving button.eng_symbol.star {
    /* 14463:35160 star group 15 x 17.08203125 at (216,568); tile at (202,553).
       The export (engraving-glyph-star-of-david-v2.svg) has an 18 x 21 viewBox;
       it is scaled into the drawn 15 x 17.08203125 box, exactly as Figma does. */
    background-image: url("../../../assets/media/ringbuilder/engraving-glyph-star-of-david-v2.svg");
    /* HEIGHT-LOCKED, width follows. The export's viewBox is 18x21
       (ratio 0.857) because it carries the stroke bleed, while the node
       is drawn 15 x 17.08203125 (0.878) -- forcing both axes stretched the
       star 2.4% wide. Measured. Pinning the height and letting the width
       resolve gives 17.08203125 x 18/21 = 14.64, and x moves 0.18 to keep
       the mark on the same centre. */
    background-size: auto 17.08203125px;
    background-position: 14.18px 15px;
  }
  #ssq_engraving button.eng_symbol.crescent {
    /* 14463:35165 image 26.5633811951 x 23 at (271,564); tile at (262,553) */
    background-image: url("../../../assets/media/ringbuilder/engraving-symbol-crescent-star-v2.png");
    background-size: 26.56338119506836px 23px;
    background-position: 9px 11px;
  }
  #ssq_engraving button.eng_symbol.dot {
    /* 14463:35168 Ellipse 7 x 7 #000000 at (341,572); tile at (322,553).
       Centre = (322 + 19 + 3.5, 553 + 19 + 3.5) -> (22.5, 22.5) tile-relative.
       No asset needed for a solid 7px disc. */
    background-image: radial-gradient(
      circle 3.5px at 22.5px 22.5px,
      #000000 0 100%,
      transparent 100%
    );
  }

  /* WARNING — assets.md:149. engraving-symbol-cross-v2.png, -infinity.png and
     -crescent-star.png are 700 x 700 Noun Project rasters with a burned-in
     credit strip along the bottom, placed in Figma with scaleMode=STRETCH into
     boxes of 23.51 x 19, 25.78 x 16 and 26.56 x 23. The sizes above reproduce
     the Figma rendering EXACTLY — credit strip and non-uniform squash included.
     They are not cropped here: cropping in CSS would move the glyph off the
     design's position and still leave a partial strip. FLAGGED FOR SVG REDRAW,
     see §6(f). */


  /* ===========================================================================
     4b. THE INLINE `ADD TO BAG` CTA — 14463:35169 .. :35177
     346 x 44 at (22, 645) in frame 14463:35118, i.e. the LAST child of the
     Engraving block 14463:35136 and 32px below the builder 14463:35137 —
     AL:HORIZONTAL gap=5, pad 14/0, both axes CENTER, fill #27423B, r=4, clip.
     Label 14463:35171 "ADD TO BAG" Founders Grotesk 400 16/19 ls -0.21 #FAF3ED
     with `textCase: NONE` — the source string is already uppercase, so nothing
     here may depend on `text-transform` to produce it. Glyph 14463:35172 is a
     12 x 13.24 group of four vectors stroked #FAF3ED at w=1, AFTER the label.

     The node ships (simple-select-quiz.php) and proxies its click to the
     footer's own `.sss-next`, so this is the design's one CTA and not a second
     commit path. `_stone.css` §8b collapses the engraving sticky bar to match —
     frame 14463:35118 draws no footer at all.

     346 in a 344 column is the design's own 2px: 14463:35136 is 345 wide only
     because it holds this 346-wide CTA. 22 + 346 = 368 against a 390 board, so
     it stays inside the page's right margin and adds no overflow.
     =========================================================================== */
  /* ===========================================================================
     ADD TO BAG SITS ON THE FLOOR OF THE PANEL
     ---------------------------------------------------------------------------
     Owner: *"Add to Bag in engraving went non-sticky."*

     It did, and this is the other half of the gap fix. This step's children are
     short and `.ssq_bottom_nav` is deliberately collapsed here (_stone.css:2373
     -- the board draws no sticky frame on engraving), so the CTA is an ordinary
     in-content button. It used to LOOK pinned because the whole block was being
     pushed to the far end of a full-height column, and the price of that was the
     tall empty band between the ring card and the text field the owner reported
     earlier. Packing from the top closed the band and, with it, dropped the
     button back into the middle of the screen: MEASURED at 360x800, the card ->
     field gap went 202 -> 45 and the CTA's distance from the bottom of the
     viewport went 24 -> 207.

     Both are wanted, and they are not in conflict -- one is about where the
     SLACK goes, not about where the content starts. The column keeps packing
     from the top and the CTA alone takes the slack above it, so the field stays
     under the card and the button returns to the floor.

     That needs the panel's height to actually reach the button, which is four
     boxes deep: section -> .container -> .row -> the slide -> its content. The
     intermediate `.col-12` and `.quiz_options` are `display: contents` and drop
     out, so the chain is unbroken. `!important` is on the SECTION only, where
     jQuery's `.show()` writes an inline `display: block` that a stylesheet
     cannot otherwise beat; the slides carry no inline style at all (MEASURED:
     every `.simple-select-slide` has an empty style attribute and is switched
     by `.active` alone), so nothing below needs it.

     The 48px the board puts between the symbol row and the CTA moves to the
     symbol row as a bottom margin. Flex margins do not collapse, so it becomes
     a FLOOR: on a screen tall enough the auto margin above the button holds it
     to the floor, and on one too short to spare 48 the board's gap still holds.

     MEASURED after, CTA distance from the bottom of the viewport: 24 at both
     360x800 and 430x932, with the card -> field gap unchanged at 45.
     =========================================================================== */
  #simple-select-quiz:has(#ssq_engraving.active) {
    display: flex !important;
    flex-direction: column;
  }
  #simple-select-quiz:has(#ssq_engraving.active) > .container,
  #simple-select-quiz:has(#ssq_engraving.active) > .container > .row,
  #ssq_engraving.active,
  #ssq_engraving.active > .simple-select-slide-content {
    flex: 1 1 auto;
  }
  #ssq_engraving.active,
  #ssq_engraving.active > .simple-select-slide-content {
    display: flex;
    flex-direction: column;
  }
  #ssq_engraving .sss_swatches_engraving_container {
    margin-bottom: 48px;
  }

  #ssq_engraving .rb_eng_addbag {
    display: flex;
    align-items: center;
    justify-content: center;
    /* 8, not the board's 5 -- same reason as the desktop CTA in
       _stone-desktop.css: an all-caps label plus a 12px lock read as one clump
       at 5. Measured at 390: label 123..205.9, lock 211..223, content centred in
       the 346 button but crowded. */
    gap: 8px;
    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));
    /* 100% here is the 344 column, which would clamp the design's 346 to 344.
       Bounded on the VIEWPORT instead -- 390 - 2 x 22 = 346, so nothing changes
       on the board's own width and narrower screens still keep the 22px gutter. */
    max-width: calc(100vw - 44px);
    height: 44px;
    /* WAS 32 (14463:35136's itemSpacing). [Flow 3] 14514:40420 puts the symbol
       row at @22,553 44 tall and ADD TO BAG at @22,645, i.e. 48 between them.
       MEASURED at 390 with the 32: symbol row 507 (board 507, exact) and the
       CTA at 583 against the board-relative 599. */
    /* the board's 48 now lives on the symbol row above (see the block before
       this one); here it becomes auto so the button takes the column's slack. */
    margin: auto 0 0;
    padding: 14px 0;
    -webkit-appearance: none;
    appearance: none;
    border: 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-align: center;
    text-transform: none;        /* the source string is already uppercase */
    color: var(--rb-surface-page);   /* #FAF3ED -- also the text-on-green token */
    cursor: pointer;
  }
  #ssq_engraving .rb_eng_addbag .rb_eng_addbag_icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 12px;
    width: 12px;
    height: 13.24px;
    /* Optical lift against the all-caps label -- see the desktop CTA's note.
       Measured at 390: label box 12.5..31.5, lock 15.4..28.6. */
    margin-bottom: 1px;
  }
  /* The inline SVG is authored in a 12 x 14 viewBox; 14463:35172 measures
     12 x 13.24, so the box is pinned and the art scales into it. */
  #ssq_engraving .rb_eng_addbag .rb_eng_addbag_icon svg {
    display: block;
    width: 12px;
    height: 13.24px;
  }
  #ssq_engraving .rb_eng_addbag .rb_eng_addbag_icon svg path {
    stroke: currentColor;
    stroke-width: 1px;           /* 14463:35173 .. :35177 */
  }


  /* ===========================================================================
     5. STATES
     flows/STATES.md:15-19 — the only state annotation anywhere near this screen
     is stamp 14463:36449 "disabled state", pinned over 1.3 Engraving. It marks
     a REGION; no component on the board carries a disabled variant, and hover,
     pressed, loading and focus are not designed anywhere on the board. So no
     :hover / :focus / [disabled] rule is invented here. MISSING FROM SPEC.
     =========================================================================== */


  /* ===========================================================================
     6. FOLLOW-UPS — what the design asks for that this file cannot do
     ---------------------------------------------------------------------------
     a) ADD TO BAG ON THE ENGRAVING SCREEN — NOW BUILT, see §4b. The markup
        landed (`button.rb_eng_addbag`, a proxy onto the footer's `.sss-next`),
        so the design's inline CTA is drawn here and _stone.css §8b collapses
        the sticky bar this frame does not have. STILL OUTSTANDING: the node
        renders at >= 992px too, where 14465:40538 draws no inline CTA. Hiding
        it there is a `@media (min-width: 992px)` rule and belongs to
        _engraving-desktop.css, not to this file.

     b) TWO CSS-GENERATED STRINGS. The step title (§2) has no element in the
        DOM and is drawn with `content`. Real markup would make it accessible.

     c) SUB-HEAD COPY MISMATCH. simple-select.js:1489 writes "Personalize your
        ring with a complimentary custom engraving of up to 27 characters. It's
        optional, but a beautiful way to add meaning — or skip it if you prefer
        to keep it classic." 14463:35140 reads "Personalize your ring with a
        free custom engraving on the inside of the band (optional)." At 14px/17
        in a 344px box the design's string is 2 lines (34px tall, as drawn); the
        JS string is 4. A copy change in JS, not CSS.

     d) PLACEHOLDER. The DOM's placeholder is "Type your message or symbol...";
        the board draws an empty field with only a caret, so there is no
        designed placeholder string or colour. See §3a.

     f) RASTER SYMBOLS. cross / infinity / crescent-star must be redrawn as SVG
        (assets.md:149). See the warning in §4.

     g) SHARED CHROME NOT STYLED HERE. The setting card (14463:35119), the
        progress bar (14463:35185), the page header and the sticky footer are
        drawn on this frame but are shared by 14+ frames on the board and belong
        to the files that own that chrome.
     =========================================================================== */

}

/* =============================================================================
   THE FIELD IS FULL, AND IT SAYS SO
   -----------------------------------------------------------------------------
   `maxlength="27"` already stops the 28th character; product-single.js's
   updateCharCounter() now flags the state and prints the note. All this sheet
   does is paint them.

   The red restates the field's own `box-shadow` border rather than adding a
   second one: the resting border IS an inset shadow (there is no `border`
   property on this input at all), so a `border-color` here would draw a ring
   OUTSIDE the existing one instead of recolouring it.
   ============================================================================= */
#ssq_engraving input#ssq_eng_field.is-maxed {
    box-shadow: inset 0 0 0 var(--rb-stroke) #C65858;
}
/* OUT OF FLOW, UNDER THE FIELD. Owner: *"that message must be just under the
   text field, why the fuck is it moving the engraving buttons"*.

   product-single.js now appends this into the field's own wrapper, which
   carries an inline `position: relative` (the #charCounter anchor). Absolute
   here so the note costs the wrapping flex row nothing: as a normal-flow
   sibling it was a full-width flex item and shoved the six symbol tiles down a
   line the instant it appeared, then pulled them back up on delete.

   It lands in the row-gap that already separates the field from the tiles --
   22px at <=991, 60px at >=992 -- so nothing has to be reserved for it either:
     mobile   4 (offset) + 17 (line) = 21 <= 22
     desktop  6 (offset) + 19 (line) = 25 <= 60
   The mobile size is a notch smaller than the desktop one for exactly that
   reason. `right: 0` rather than a width so a long string wraps inside the
   field's own 344/752 box instead of running past it. */
#ssq_engraving .ssq_eng_maxnote {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    margin: 0;
    font-family: var(--rb-font-body);
    font-weight: 400;
    font-size: 13px;
    line-height: 17px;
    letter-spacing: var(--rb-ls-tight);
    color: #C65858;
    text-align: left;
    pointer-events: none;
}
#ssq_engraving .ssq_eng_maxnote.is-visible { display: block; }
@media (min-width: 992px) {
    #ssq_engraving .ssq_eng_maxnote {
        top: calc(100% + 6px);
        font-size: 14px;
        line-height: 19px;
    }
}
