/* ==========================================================================
   Discover — Instagram-style product feed + full-screen reel player.

   Scoped entirely under .mr-disc / .mr-reel so it cannot leak into the rest of
   the storefront, which is Bootstrap 4 with a lot of global selectors.

   Theme tokens: maroon #610000 and gold #c9a15f, the same pair the mega menu
   and the listing's hover-gallery dots already use.
   ========================================================================== */

.mr-disc{
  --mrd-maroon:#610000;
  --mrd-gold:#c9a15f;
  --mrd-ink:#171717;
  --mrd-mute:#8a8178;
  --mrd-line:#ece7e2;
  --mrd-bg:#fbfaf9;

  max-width:614px;                    /* Instagram's own feed column width */
  margin:0 auto;
  padding:0 0 72px;
  background:transparent;
}

.mr-disc *{ box-sizing:border-box; }

/* Discover holds a fixed page scale so the sticky rail and feed column never drift.
   This file is only loaded by the Discover view, so targeting the page root here is
   page-scoped — every other page keeps normal pinch-zoom. Chrome and Android honour
   this; iOS needs the gesture blocked in JS, which mr-discover.js does. Pinching a
   photo still zooms the photo. */
html, body{
  touch-action:pan-x pan-y;
  -webkit-text-size-adjust:100%;
}

/* ---------------------------------------------------------------- the rail
   Category "stories": circular thumbnails that double as the filter bar. */

/* The storefront header turns position:fixed (class "sticky", z-index 9999999) the
   moment the page scrolls — custom1.js adds it on any scroll. A rail pinned at
   top:0 therefore slides UNDERNEATH the masthead and only its labels stay visible.
   Pin it at the header's height instead. --mrd-head is measured at runtime by
   mr-discover.js, because the header is 65px on desktop but taller on some
   breakpoints; the 65px fallback keeps this correct even if the script never runs.

   The hairline lives on this wrapper so it lands exactly at the masthead's edge,
   and the background must stay opaque: the rail's margin-top leaves a bare strip
   inside this box, and while pinned the feed has to pass behind it, not through. */
.mr-disc-rail-wrap{
  position:sticky; top:var(--mrd-head, 65px); z-index:20;
  background:#fff;
  border-top:1px solid var(--mrd-line);
  margin-bottom:14px;
}

.mr-disc-rail{
  display:flex;
  gap:10px;
  padding:8px 10px 8px;
  overflow-x:auto;
  overflow-y:hidden;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
  margin-top:5px;
  background:#fff;
  border-bottom:1px solid var(--mrd-line);
}
.mr-disc-rail::-webkit-scrollbar{ display:none; }

.mr-disc-cat{
  flex:0 0 auto;
  width:66px;
  border:0; padding:0; background:none;
  cursor:pointer;
  text-align:center;
  font:inherit;
}

/**
 * No focus rectangle on the chips.
 *
 * It was the browser's own ring, not a rule of ours — nothing in the stylesheets draws
 * an outline here — and it boxes the circle AND its label in a hard rectangle that cuts
 * straight through the rail's design. The owner asked for it gone.
 *
 * Killed only for the pointer. A keyboard user still needs to see where they are, so
 * :focus-visible keeps an indicator; it just speaks the rail's own language — a gold
 * ring on the thumbnail, the same treatment the active chip already uses — instead of
 * a rectangle around everything.
 */
.mr-disc-cat:focus{ outline:none; }

.mr-disc-cat:focus-visible{ outline:none; }
.mr-disc-cat:focus-visible .mr-disc-ring{
  background:linear-gradient(135deg,var(--mrd-gold),var(--mrd-maroon) 70%);
  box-shadow:0 0 0 2px rgba(201,161,95,.45);
}

/* Ring thickness at 55% of what it was: the gradient rim (padding) and the white
   inset (the span's border) are the two things that read as "the border", so both
   are scaled together — thinning only one leaves the rim looking uneven. */
.mr-disc-ring{
  display:block; width:64px; height:64px;
  border-radius:50%;
  padding:1.4px;
  background:var(--mrd-line);
  transition:background .18s ease, transform .18s ease;
}
.mr-disc-cat:hover .mr-disc-ring{ transform:translateY(-1px); }

.mr-disc-cat.is-active .mr-disc-ring{
  background:linear-gradient(135deg,var(--mrd-gold),var(--mrd-maroon) 70%);
}

.mr-disc-ring span{
  display:block; width:100%; height:100%;
  border-radius:50%;
  border:1.1px solid #fff;
  background:#f3efec center/cover no-repeat;
  overflow:hidden;
}

.mr-disc-ring span.mr-disc-all{
  display:flex; align-items:center; justify-content:center;
  background:linear-gradient(135deg,#3a0000,var(--mrd-maroon));
  color:var(--mrd-gold);
  font-size:11px; font-weight:700; letter-spacing:.09em;
}

.mr-disc-cat b{
  display:block;
  margin-top:6px;
  font-size:10.5px; font-weight:500; line-height:1.25;
  color:var(--mrd-mute);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.mr-disc-cat.is-active b{ color:var(--mrd-maroon); font-weight:700; }

/* ------------------------------------------------------------- the toolbar */

.mr-disc-toolbar{
  display:flex; align-items:center; gap:8px;
  padding:0 12px 12px;
}

.mr-disc-seg{
  display:inline-flex;
  border:1px solid var(--mrd-line);
  border-radius:999px;
  background:#fff;
  padding:2px;
}

.mr-disc-seg button{
  border:0; background:none;
  padding:5px 14px;
  border-radius:999px;
  font-size:12px; font-weight:600; letter-spacing:.03em;
  color:var(--mrd-mute);
  cursor:pointer;
  transition:background .18s ease, color .18s ease;
}
.mr-disc-seg button.is-on{
  background:var(--mrd-maroon);
  color:#fff;
}

.mr-disc-chk{
  margin-left:auto;
  display:inline-flex; align-items:center; gap:7px;
  font-size:12px; color:var(--mrd-mute);
  cursor:pointer; user-select:none;
}
.mr-disc-chk input{ accent-color:var(--mrd-maroon); width:14px; height:14px; cursor:pointer; }

/* ---------------------------------------------------------------- the post */

.mr-post{
  background:#fff;
  border:1px solid var(--mrd-line);
  border-radius:14px;
  margin:0 8px 20px;
  overflow:hidden;
}

.mr-post-head{
  display:flex; align-items:center; gap:10px;
  padding:11px 13px;
}

.mr-post-avatar{
  flex:0 0 auto;
  width:34px; height:34px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:linear-gradient(135deg,#3a0000,var(--mrd-maroon));
  color:var(--mrd-gold);
  font-size:11px; font-weight:700; letter-spacing:.05em;
}

.mr-post-id{ min-width:0; flex:1 1 auto; }

/* !important on every anchor colour below is not laziness. The theme's index.min.css
   ships a global `a { color:#212529 !important }`, which no amount of specificity can
   beat — without this the reel caption renders near-black on a dark scrim and the
   tags/CTA lose their maroon. Only colour is forced; nothing else needs it. */
.mr-post-id a{
  display:block;
  font-size:13.5px; font-weight:600; color:var(--mrd-ink) !important;
  text-decoration:none;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.mr-post-id a:hover{ color:var(--mrd-maroon) !important; }

.mr-post-sub{
  display:block;
  font-size:11px; color:var(--mrd-mute);
  letter-spacing:.04em; text-transform:uppercase;
}

.mr-post-flag{
  flex:0 0 auto;
  font-size:9.5px; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase;
  padding:3px 8px; border-radius:999px;
  background:#f6f2ee; color:var(--mrd-mute);
}
.mr-post-flag.is-oos{ background:#fdf0f0; color:#a33; }

/* --- media --------------------------------------------------------------- */

/* The shape now lives on the box, not the image, and is written inline per post
   from the cover image's own ratio (clamped 4:5..4:3 server side). Forcing one
   house ratio meant cropping the catalogue's 79% landscape photos into a portrait
   frame, which scaled them up before display — the main cause of the pixelation.
   The inline aspect-ratio is the real value; 1/1 here is only the pre-CSS default. */
.mr-post-media{
  position:relative;
  aspect-ratio:1/1;
  background:#f3efec;
  cursor:pointer;
  overflow:hidden;
}

.mr-post-track{
  display:flex;
  height:100%;
  overflow-x:auto; overflow-y:hidden;
  scroll-snap-type:x mandatory;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
}
.mr-post-track::-webkit-scrollbar{ display:none; }

/* Slides are the DIRECT children of the track: image slides, plus the video slide
   which wraps a <video> and its still. Descendant selectors would catch the still
   as well and treat it as a slide of its own. */
.mr-post-track > img,
.mr-post-track > .mr-post-vslide{
  flex:0 0 100%;
  width:100%; height:100%;
  scroll-snap-align:center;
  display:block;
  background:#f3efec;
}
.mr-post-track > img{ object-fit:cover; }

/* The still sits ON TOP of the video and fades out when playback actually starts,
   so the hand-off is a cross-fade instead of a jump cut. */
.mr-post-vslide{ position:relative; overflow:hidden; }

.mr-post-vslide video,
.mr-post-vslide .mr-post-vposter{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  display:block;
}

/* No transition, on purpose.
   The still is swapped for the video the moment the video can paint a frame, and
   that frame is the same picture — so there is nothing to fade between. Fading it
   invented a visible "photo, then video" hand-off, which is the lag the owner was
   seeing. One image throughout is what Instagram does. */
.mr-post-vposter{
  z-index:1;
  opacity:1;
}
.mr-post-vslide.is-ready .mr-post-vposter{ opacity:0; }

/* Only a video post is a doorway to the reel; an image post is read in place. */
.mr-post-media{ cursor:default; }
.mr-post-media.has-video{ cursor:pointer; }

/**
 * During a pinch the card lifts above its neighbours, and the transform composites
 * rather than reflowing the carousel.
 *
 * What this must NOT do is touch the track's overflow. The track is the horizontal
 * scroll container, and overflow:visible stops it being one — which silently resets
 * scrollLeft to 0. The effect was that pinching the second or third slide threw the
 * carousel back to the first: the correct slide was being scaled all along, but it
 * had been laid out off to the side while slide one filled the card. Measured at
 * 596px scrollLeft before the class, 0 immediately after.
 *
 * The cost is that a zoomed slide is clipped to the card instead of spilling past it.
 * That is the right trade — a pinch that zooms the wrong picture is broken, a pinch
 * that zooms within the card is simply a zoom.
 */
.mr-post-media.is-pinching{ z-index:2; }
.mr-post-track > img,
.mr-post-track > .mr-post-vslide{ will-change:transform; }

/* Safari below 15 has no aspect-ratio; give the box a sane height rather than none. */
@supports not (aspect-ratio:1/1){
  .mr-post-media{ min-height:78vw; }
  .mr-post-track > img,
  .mr-post-track > .mr-post-vslide{ height:78vw; }
}

/**
 * Below the media, centred — not floating over it.
 *
 * Over the image they landed on whatever happened to be at the bottom of the photo,
 * which for pale gold jewellery on a pale ground meant white dots on white, and they
 * took a strip of the product with them. Out here they are legible against the card
 * whatever the picture is doing, so the colours can drop the white-on-dark treatment
 * and the shadow that went with it.
 */
.mr-post-dots{
  display:flex; justify-content:center; align-items:center; gap:5px;
  padding:9px 0 2px;
  pointer-events:none;
}
.mr-post-dots i{
  width:6px; height:6px; border-radius:50%;
  background:rgba(0,0,0,.16);
  transition:background .2s ease, transform .2s ease;
}
.mr-post-dots i.is-on{ background:var(--mrd-maroon); transform:scale(1.25); }

/**
 * Feed sound button, bottom left of the media — the chevron has the bottom right and
 * the REEL badge the top right, so the three never collide. Same visual language as
 * the reel's chrome, and the same rule: one glyph at a time, muted by default because
 * autoplay is only permitted muted.
 */
.mr-post-sound{
  position:absolute; left:10px; bottom:10px;
  display:flex; align-items:center; justify-content:center;
  width:30px; height:30px;
  border:1px solid rgba(255,255,255,.22);
  border-radius:50%;
  background:rgba(0,0,0,.55);
  box-shadow:0 2px 8px rgba(0,0,0,.4);
  -webkit-backdrop-filter:blur(3px);
  backdrop-filter:blur(3px);
  color:#fff;
  cursor:pointer;
  padding:0;
}
.mr-post-sound svg{
  width:16px; height:16px;
  fill:none; stroke:currentColor; stroke-width:2.1;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.55));
}
.mr-post-sound .mr-ico-loud{ display:none; }
.mr-post-sound.is-loud .mr-ico-mute{ display:none; }
.mr-post-sound.is-loud .mr-ico-loud{ display:block; }
.mr-post-sound.is-loud{
  background:rgba(255,255,255,.94);
  color:#1a1a1a;
  border-color:rgba(0,0,0,.12);
}
.mr-post-sound.is-loud svg{ filter:none; }

/**
 * Carousel hint, bottom right — the affordance the owner pointed at in the Instagram
 * reference. Only rendered for posts with more than one slide, and hidden once the
 * last slide is reached so it always means "there is more this way".
 *
 * Indicator, not a control: pointer-events are off so it behaves like the REEL badge
 * and cannot swallow the tap that opens the reel on a video post.
 */
/**
 * Carousel hint, bottom right: a counter and the arrows in one pill.
 *
 * Three designs in, the lesson was that an ARROW can always be read as decoration,
 * however large or bright it is — the eye files it as chrome and moves on. A NUMBER
 * cannot: "1/4" is information, and it is what Instagram itself puts on a carousel.
 * The chevrons stay beside it to carry the direction a number does not.
 *
 * White pill on maroon text, because a translucent dark chip only ever read against
 * the light shots; white holds up over gold, black velvet and the red backdrops the
 * catalogue shoots on.
 *
 * Indicator, not a control: pointer-events off, so it behaves like the REEL badge and
 * cannot swallow the tap that opens the reel on a video post.
 */
.mr-post-next{
  position:absolute; right:11px; bottom:11px;
  display:flex; align-items:center; gap:5px;
  height:26px; padding:0 9px 0 10px;
  border-radius:999px;
  background:rgba(255,255,255,.96);
  color:var(--mrd-maroon);
  box-shadow:0 2px 10px rgba(0,0,0,.3);
  -webkit-backdrop-filter:blur(3px);
  backdrop-filter:blur(3px);
  pointer-events:none;
  opacity:1;
  transition:opacity .18s ease;
}

.mr-next-num{
  font-size:11.5px; font-weight:800; letter-spacing:.02em;
  line-height:1;
  font-variant-numeric:tabular-nums;   /* 1/4 and 4/4 must not change the pill's width */
  white-space:nowrap;
}

/* The arrows get their own box so the flow animation cannot drag the number with it. */
.mr-next-arrows{
  position:relative;
  display:block;
  width:15px; height:13px;
  flex:0 0 auto;
}

.mr-next-c{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  animation:mrHintFlow 1.5s ease-in-out infinite;
}
.mr-next-c:nth-child(2){ animation-delay:.25s; }

.mr-next-c svg{
  width:13px; height:13px;
  fill:none; stroke:currentColor; stroke-width:2.8;
}

/* Overlapped and out of phase, the two chevrons read as direction rather than as a
   glyph twitching in place. */
@keyframes mrHintFlow{
  0%   { transform:translateX(-5px); opacity:0; }
  25%  { opacity:1; }
  70%  { transform:translateX(3px);  opacity:1; }
  100% { transform:translateX(7px);  opacity:0; }
}

/**
 * Last slide: the ARROWS go, the number stays.
 *
 * Earlier the whole hint disappeared at the end, which threw away the useful half —
 * "4/4" still tells the reader where they are, and a pill that vanishes reads as a
 * glitch. Only the promise of more is withdrawn.
 */
.mr-post-media.is-end .mr-next-arrows{ display:none; }
.mr-post-media.is-end .mr-post-next{ padding:0 10px; }

@media (prefers-reduced-motion:reduce){
  .mr-post-next{ transition:none; }
  /* One static arrow rather than none, so the direction survives without motion. */
  .mr-next-c{ animation:none; }
  .mr-next-c:nth-child(2){ display:none; }
}

.mr-post-play{
  position:absolute; top:11px; right:11px;
  display:flex; align-items:center; gap:6px;
  padding:6px 11px;
  border-radius:999px;
  background:rgba(0,0,0,.45);
  backdrop-filter:blur(3px);
  color:#fff;
  font-size:11px; font-weight:700; letter-spacing:.08em;
  pointer-events:none;
}
.mr-post-play svg{ width:13px; height:13px; fill:currentColor; }

/* --- actions ------------------------------------------------------------- */

.mr-post-actions{
  display:flex; align-items:center; gap:5px;
  padding:9px 8px 3px;
}

.mr-act{
  border:0; background:none;
  width:42px; height:42px;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:50%;
  cursor:pointer;
  color:var(--mrd-ink);
  transition:background .16s ease, transform .16s ease, color .16s ease;
}
.mr-act:hover{ background:#f6f2ee; }
.mr-act:active{ transform:scale(.9); }
.mr-act svg{ width:25px; height:25px; fill:none; stroke:currentColor; stroke-width:1.65; }

/* Trolley wheels read as smudges when they are hairline rings at this size. */
.mr-act-cart svg circle,
.mr-reel-cart svg circle{ fill:currentColor; stroke:none; }

.mr-act.is-saved{ color:var(--mrd-maroon); }
.mr-act.is-saved svg{ fill:var(--mrd-maroon); stroke:var(--mrd-maroon); }

.mr-act-cart{ margin-left:auto; }

.mr-post-meta{ padding:2px 14px 14px; }

.mr-post-price{
  font-size:15px; font-weight:700; color:var(--mrd-ink);
  margin:0 0 4px;
}

.mr-post-login{
  display:inline-flex; align-items:center; gap:6px;
  border:1px solid var(--mrd-line);
  background:#fff;
  color:var(--mrd-maroon);
  font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  padding:6px 12px; border-radius:999px;
  cursor:pointer;
  margin-bottom:6px;
}
.mr-post-login:hover{ background:#faf6f2; }

/* Category chips, in place of a caption that only repeated the card's own title. */
.mr-post-cats{
  display:flex; flex-wrap:wrap; gap:6px;
  margin:0 0 7px;
}
.mr-post-cat{
  display:inline-flex; align-items:center;
  border:1px solid #e7ded4;
  background:#fbf7f3;
  color:var(--mrd-maroon) !important;   /* theme forces a { color } with !important */
  font-size:11.5px; font-weight:600; letter-spacing:.03em;
  padding:5px 12px;
  border-radius:999px;
  text-decoration:none;
  transition:background .16s ease, border-color .16s ease;
}
.mr-post-cat:hover{ background:var(--mrd-maroon); border-color:var(--mrd-maroon); color:#fff !important; }

.mr-post-tags{ margin-top:5px; }
.mr-post-tags a{
  font-size:12px; color:var(--mrd-maroon) !important;
  text-decoration:none; margin-right:7px;
}
.mr-post-tags a:hover{ text-decoration:underline; }

/* --- feed states --------------------------------------------------------- */

/* Chrome's scroll anchoring re-pins the viewport when posts are appended, which
   keeps the load sentinel permanently in range and turns infinite scroll into a
   runaway (measured: 72 pages in 4 seconds). Opting out makes the sentinel's
   geometry mean what it says. */
.mr-disc-feed{ overflow-anchor:none; }
#mr_disc_sentinel{ overflow-anchor:none; }

.mr-disc-more{
  display:block;
  margin:8px auto 20px;
  border:1px solid var(--mrd-line);
  background:#fff;
  color:var(--mrd-maroon);
  font-size:12px; font-weight:700; letter-spacing:.07em; text-transform:uppercase;
  padding:11px 26px;
  border-radius:999px;
  cursor:pointer;
}
.mr-disc-more:hover{ background:#faf6f2; }

.mr-disc-spinner{
  display:none;
  margin:22px auto;
  width:26px; height:26px;
  border:2.5px solid var(--mrd-line);
  border-top-color:var(--mrd-maroon);
  border-radius:50%;
  animation:mrDiscSpin .8s linear infinite;
}
.mr-disc-spinner.is-on{ display:block; }
@keyframes mrDiscSpin{ to{ transform:rotate(360deg); } }

.mr-disc-end,
.mr-disc-empty{
  text-align:center;
  color:var(--mrd-mute);
  font-size:13px;
  padding:26px 16px;
}
.mr-disc-empty b{ display:block; color:var(--mrd-ink); font-size:15px; margin-bottom:4px; }

/* ====================================================================== reel
   Full-screen vertical player. One scroll container with mandatory y snapping —
   native momentum on iOS, and no scroll hijacking to fight with.
   ========================================================================= */

/* Stacked at 1000000000, NOT the ten-million it used to be.
   `ul.main-nav` in stylesheet.css carries z-index:999999999 — nine nines — so the site's
   own top nav painted straight through the top of an open reel on desktop. Ten million
   never stood a chance against it.

   Deliberately NOT the 32-bit maximum: two theme rules clamp to 2147483647 and must stay
   ABOVE the reel — `div#productadded-msg-box` (the "added to order" confirmation raised
   from the reel's own panel) and `.intl-tel-input .country-list` (the phone dropdown in
   the in-reel login). Sitting at 1e9 clears the nav while leaving both of those on top.

   The whole reel stack moved by the same +990000000, so every layer inside it — chrome,
   sheet, backdrop, modal, overlay — keeps its original relative order. */
.mr-reel{
  position:fixed; inset:0;
  /* The site header is position:fixed at z-index 9999999, so anything less than
     this leaves the masthead sitting on top of a "full screen" reel. */
  z-index:1000000000;
  background:#000;
  display:none;
}
.mr-reel.is-open{ display:block; }

body.mr-reel-lock{ overflow:hidden; }

.mr-reel-track{
  height:100%;
  overflow-y:auto; overflow-x:hidden;
  scroll-snap-type:y mandatory;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior:contain;
}
.mr-reel-track::-webkit-scrollbar{ display:none; }

.mr-reel-slide{
  position:relative;
  height:100%;
  scroll-snap-align:start;
  scroll-snap-stop:always;            /* one flick = one reel, never two */
  display:flex; align-items:center; justify-content:center;
  overflow:hidden;
}

/* The 9:16 stage. On desktop it is a centred phone-shaped pane, like Instagram's
   own web reels; on mobile it fills the screen. */
.mr-reel-stage{
  position:relative;
  width:100%; height:100%;
  max-width:min(100vw, calc(100vh * 9 / 16));
  background:#0a0a0a;
  overflow:hidden;
}

/* Explicit stacking. The <video> is appended to the stage at runtime, so in DOM
   order it lands AFTER the scrim and would paint straight over the gradient,
   leaving the caption sitting on bare video with nothing behind it. These
   z-indexes pin the layers regardless of insertion order. */
.mr-reel-stage video{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  display:block;
  z-index:1;
}

/* Blurred fill behind the media, so a non-9:16 image never sits on dead black. */
.mr-reel-bg{
  position:absolute; inset:-12%;
  z-index:0;
  background:center/cover no-repeat;
  filter:blur(26px) brightness(.42) saturate(1.1);
  transform:scale(1.08);
}

/* While pinching, the media has to be free to grow past the stage's edge. */
.mr-reel-stage.is-pinching{ overflow:visible; z-index:4; }
.mr-reel-stage video,
.mr-reel-stage img.mr-reel-poster{ will-change:transform; }

/* Same hand-off as the feed: a real still over the video, cross-faded once frames
   are moving, instead of the poster attribute's instant swap. */
.mr-reel-poster{
  position:absolute; inset:0;
  z-index:2;
  width:100%; height:100%;
  object-fit:cover;
  display:block;
  opacity:1;
}
.mr-reel-slide.is-ready .mr-reel-poster{ opacity:0; }

.mr-reel-scrim{
  position:absolute; inset:auto 0 0 0;
  z-index:3;
  /* Was 58%. The caption is far shorter now, so the gradient only has to cover the
     bottom strip — less of the clip sits under a dark wash. */
  height:34%;
  background:linear-gradient(to top,rgba(0,0,0,.88) 0%,rgba(0,0,0,.66) 26%,rgba(0,0,0,.26) 62%,transparent);
  pointer-events:none;
}

/* --- reel chrome --------------------------------------------------------- */

.mr-reel-close,
.mr-reel-sound{
  position:absolute;
  /* env() so a notch can never eat them if the page ever opts into viewport-fit=cover.
     max() keeps the normal 14px everywhere else. */
  top:max(14px, env(safe-area-inset-top, 0px));
  /* Comfortably above every layer inside a slide (the highest is the scrim group at
     3-5). At 6 the old double-tap heart at 7 outranked them, and anything else added
     to a slide could too — these two must always be reachable. */
  z-index:9;
  width:44px; height:44px;
  border:0; border-radius:50%;
  /* Was rgba(0,0,0,.42) with a 1.8px stroke, which over pale jewellery on a bright
     phone screen washed out to almost nothing — the owner could not find either
     button. Darker disc, a real border and a drop shadow so the control reads against
     any frame. */
  /**
   * NO backdrop-filter here, deliberately.
   *
   * The owner reported the close button as "almost invisible" on an iPhone while being
   * fine on every other device — and backdrop-filter was the only iOS-specific thing in
   * this rule. On iOS Safari a backdrop-filtered element inside a position:fixed overlay
   * (which the reel is) can lose its own background entirely, leaving nothing but the
   * thin stroke: exactly the symptom described. It was decorative anyway — a blur behind
   * a 60%-black disc buys almost nothing — so it is gone rather than special-cased.
   *
   * The contrast that was doing the real work stays, and goes further: a darker disc, a
   * brighter keyline and a heavier stroke, none of which depend on a filter being
   * honoured.
   */
  background:rgba(0,0,0,.66);
  box-shadow:0 2px 12px rgba(0,0,0,.5);
  border:1px solid rgba(255,255,255,.34);
  color:#fff;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer;
}
/**
 * font-size and line-height are GONE from here.
 *
 * They were left over from when this button held a text "x" glyph. It is an SVG in a
 * flex container now, and on the owner's iPhone the cross collapsed to a single dot
 * inside an otherwise-correct disc — while the mute button beside it, which never had
 * a font-size, rendered perfectly. That difference is the whole clue.
 */
.mr-reel-close{ left:14px; }
.mr-reel-sound{ right:14px; }

/**
 * Sized AND pinned against flex.
 *
 * An SVG flex item with only width/height can be shrunk by iOS Safari, which computes
 * its intrinsic basis differently from Blink — the classic symptom being exactly what
 * was reported: a glyph squashed to nothing while its container looks fine. flex:0 0
 * auto plus matching min-* dimensions makes the size non-negotiable on every engine.
 *
 * Nothing here changes what Android or desktop already render: the box is still 23px.
 * These declarations only remove the freedom to shrink it.
 */
.mr-reel-close svg,.mr-reel-sound svg{
  width:23px; height:23px;
  min-width:23px; min-height:23px;
  flex:0 0 auto;
  display:block;
  fill:none; stroke:currentColor; stroke-width:2.5;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.7));
}

/* One glyph at a time. Muted is the default because autoplay is only allowed muted. */
.mr-reel-sound .mr-ico-loud{ display:none; }
.mr-reel-sound.is-loud .mr-ico-mute{ display:none; }
.mr-reel-sound.is-loud .mr-ico-loud{ display:block; }

/* Sound on is a state worth seeing at a glance, not just a different glyph. */
.mr-reel-sound.is-loud{
  background:rgba(255,255,255,.94);
  color:#1a1a1a;
  border-color:rgba(0,0,0,.12);
}
.mr-reel-sound.is-loud svg{ filter:none; }

/* The caption is deliberately small. Every millimetre it takes is a millimetre of
   jewellery the reader cannot see, and the product page is one tap away on the title,
   so this is a label rather than a panel: one line of title, the SKU, the price. */
.mr-reel-info{
  position:absolute;
  left:0; right:60px; bottom:0;
  z-index:5;
  padding:10px 14px 14px;
  color:#fff;
}

/* One line, clipped. A long title used to wrap to three and push the price up over
   the video; an ellipsis costs nothing since the whole title is on the linked page. */
.mr-reel-info h3{
  font-size:13px; font-weight:600; line-height:1.3;
  margin:0 0 1px;
  color:#fff;
  display:-webkit-box; -webkit-line-clamp:1; -webkit-box-orient:vertical;
  overflow:hidden;
}
.mr-reel-info h3 a{ color:#fff !important; text-decoration:none; }

.mr-reel-sku{
  font-size:9.5px; letter-spacing:.07em; text-transform:uppercase;
  color:rgba(255,255,255,.66);
  display:block; margin-bottom:3px;
}

.mr-reel-price{
  font-size:15px; font-weight:700;
  margin:0;
}

.mr-reel-login{
  display:inline-flex; align-items:center;
  border:1px solid rgba(255,255,255,.45);
  background:rgba(255,255,255,.12);
  color:#fff;
  font-size:9.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  padding:4px 10px; border-radius:999px;
  cursor:pointer; margin:1px 0 0;
}

.mr-reel-rail{
  position:absolute; right:8px; bottom:22px;
  z-index:5;
  display:flex; flex-direction:column; gap:16px;
  align-items:center;
}

.mr-reel-act{
  border:0; background:none;
  color:#fff;
  display:flex; flex-direction:column; align-items:center; gap:3px;
  cursor:pointer;
  padding:4px 6px;                    /* real touch target around the glyph */
  text-shadow:0 1px 6px rgba(0,0,0,.5);
}
.mr-reel-act svg{
  width:30px; height:30px;
  fill:none; stroke:currentColor; stroke-width:1.6;
  filter:drop-shadow(0 1px 4px rgba(0,0,0,.55));
}
.mr-reel-act small{ font-size:10.5px; letter-spacing:.04em; opacity:.92; }
.mr-reel-act:active{ transform:scale(.9); }
.mr-reel-act.is-saved svg{ fill:#ff2d55; stroke:#ff2d55; }

/* Buffering pip — the origin serves these straight, with no CDN in front, so a
   slow first byte is a real state the player has to show rather than hide. */
.mr-reel-wait{
  position:absolute; top:50%; left:50%;
  width:30px; height:30px; margin:-15px 0 0 -15px;
  z-index:6;
  border:2.5px solid rgba(255,255,255,.28);
  border-top-color:#fff;
  border-radius:50%;
  animation:mrDiscSpin .8s linear infinite;
  display:none;
}
.mr-reel-slide.is-waiting .mr-reel-wait{ display:block; }

.mr-reel-hint{
  position:absolute; left:0; right:0; bottom:96px;
  z-index:5;
  text-align:center;
  color:rgba(255,255,255,.82);
  font-size:11.5px; letter-spacing:.06em;
  pointer-events:none;
  animation:mrHintFade 3.4s ease forwards;
}
@keyframes mrHintFade{ 0%,60%{ opacity:1; } 100%{ opacity:0; } }

/* --------------------------------------------------- the order panel
   Off-canvas from the right, full height. Formerly a bottom sheet / centred
   popup — only the presentation changed. #mr_sheet, #mr_sheet_body, [data-close]
   and the .mr-var rows inside keep exactly the contract the order flow relies on. */

.mr-sheet{
  position:fixed; inset:0;
  z-index:1000000010;
  visibility:hidden;
  pointer-events:none;
}
.mr-sheet.is-open{ visibility:visible; pointer-events:auto; }

.mr-sheet-veil{
  position:absolute; inset:0;
  background:rgba(20,10,6,.5);
  opacity:0;
  transition:opacity .32s ease;
  backdrop-filter:blur(2px);
  -webkit-backdrop-filter:blur(2px);
}
.mr-sheet.is-open .mr-sheet-veil{ opacity:1; }

.mr-sheet-card{
  position:absolute; top:0; right:0; bottom:0;
  width:100%;
  display:flex; flex-direction:column;
  background:#fff;
  box-shadow:-18px 0 48px -22px rgba(45,0,0,.45);
  transform:translateX(100%);
  transition:transform .38s cubic-bezier(.22,.85,.28,1);
  will-change:transform;
}
.mr-sheet.is-open .mr-sheet-card{ transform:none; }

@media (min-width:768px){
  .mr-sheet-card{ width:560px; max-width:94vw; }
}

@media (prefers-reduced-motion:reduce){
  .mr-sheet-card,.mr-sheet-veil{ transition:none; }
}

/* --- header ------------------------------------------------------------- */

.mr-sheet-head{
  flex:0 0 auto;
  display:flex; align-items:center; gap:12px;
  padding:max(14px, env(safe-area-inset-top)) 16px 14px;
  border-bottom:1px solid #efe9e3;
  background:linear-gradient(180deg,#fffdfb,#fff);
}

.mr-sheet-x{
  flex:0 0 auto;
  width:42px; height:42px;
  border:0; border-radius:50%;
  background:#f5efe9;
  color:#610000;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer;
  transition:background .16s ease, transform .16s ease;
}
.mr-sheet-x:hover{ background:#ece2d8; }
.mr-sheet-x:active{ transform:scale(.92); }
.mr-sheet-x svg{ width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:2; }

.mr-sheet-headtxt{ min-width:0; }

.mr-sheet-card h4{
  font-size:12px; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:#610000;
  margin:0 0 2px;
}
.mr-sheet-sub{
  font-size:13px; color:#8a8178;
  margin:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

/* --- body --------------------------------------------------------------- */

.mr-sheet-scroll{
  flex:1 1 auto;
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
  padding-bottom:max(20px, env(safe-area-inset-bottom));
}

.mr-sheet-meta{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:14px 16px 10px;
}
.mr-sheet-price{
  font-size:19px; font-weight:700; color:#171717;
  margin:0;
}
.mr-sheet-full{
  display:inline-flex; align-items:center; gap:5px;
  font-size:12px; font-weight:600; letter-spacing:.03em;
  color:#610000 !important;
  text-decoration:none;
  white-space:nowrap;
}
.mr-sheet-full:hover{ text-decoration:underline; }
.mr-sheet-full svg{ width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:2.2; }

.mr-sheet-vh{
  font-size:11px; font-weight:700; letter-spacing:.09em; text-transform:uppercase;
  color:#8a8178;
  margin:6px 0 10px;
  padding:0 16px;
}

/* --- variants, as a thumbnail grid -------------------------------------- */

#mr_sheet_body{
  display:grid;
  grid-template-columns:repeat(2, minmax(0,1fr));
  gap:12px;
  padding:0 16px;
}

@media (min-width:520px){
  #mr_sheet_body{ grid-template-columns:repeat(3, minmax(0,1fr)); }
}

/* Same four children as before — image, label, stepper, button — re-laid out as a
   card. Grid areas rather than new markup, so the order handler still finds
   everything exactly where it expects it. */
.mr-var{
  display:grid;
  grid-template-columns:1fr auto;
  grid-template-areas:
    "img img"
    "id  id"
    "qty add";
  align-items:center;
  gap:8px;
  padding:8px;
  border:1px solid #efe9e3;
  border-radius:14px;
  background:#fff;
  transition:border-color .16s ease, box-shadow .16s ease;
}
.mr-var:hover{ border-color:#e0d4c7; box-shadow:0 6px 18px -14px rgba(45,0,0,.4); }

.mr-var img{
  grid-area:img;
  width:100%; height:auto;
  aspect-ratio:1/1;
  object-fit:cover;
  border-radius:10px;
  background:#f3efec;
}

.mr-var-id{ grid-area:id; min-width:0; }
.mr-var-id b{
  display:block;
  font-size:12.5px; font-weight:700; color:#171717;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.mr-var-id small{ font-size:11px; color:#8a8178; }

.mr-var-qty{ grid-area:qty; justify-self:start; }
.mr-var-add{ grid-area:add; justify-self:end; }

.mr-sheet *{ box-sizing:border-box; }

/* Same reason as the sheet: the reel is not inside .mr-disc, so it missed the reset
   above. Without this, any padded element sized in % goes over its box — the trap
   that breaks scroll-snap on the slides. */
.mr-reel *{ box-sizing:border-box; }

.mr-var-qty{
  display:inline-flex; align-items:stretch;
  height:34px;
  border:1px solid #e4ddd6; border-radius:999px;
  background:#fff;
  overflow:hidden; flex:0 0 auto;
}

.mr-var-qty button{
  appearance:none; -webkit-appearance:none;
  border:0; margin:0; padding:0;
  background:none;
  width:32px; height:100%;
  display:inline-flex; align-items:center; justify-content:center;
  color:#610000; cursor:pointer;
  transition:background .15s ease;
}
.mr-var-qty button:hover{ background:#faf4ef; }
.mr-var-qty button:active{ background:#f3e9e0; }
.mr-var-qty button:disabled{ opacity:.3; cursor:default; background:none; }

.mr-var-qty button svg{
  width:14px; height:14px;
  fill:none; stroke:currentColor; stroke-width:2.1; stroke-linecap:round;
}

.mr-var-qty input{
  appearance:none; -webkit-appearance:none;
  border:0; border-left:1px solid #efe9e3; border-right:1px solid #efe9e3;
  outline:0; background:none;
  width:36px; height:100%; padding:0;
  text-align:center;
  font-size:13px; font-weight:700; color:#171717;
  -moz-appearance:textfield;
}
.mr-var-qty input:focus{ background:#fdfaf7; }
.mr-var-qty input::-webkit-outer-spin-button,
.mr-var-qty input::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }

.mr-var-add{
  border:0; border-radius:999px;
  background:#610000; color:#fff;
  font-size:11.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  padding:9px 14px; cursor:pointer; flex:0 0 auto;
  transition:background .16s ease;
}
.mr-var-add:hover{ background:#7a0b0b; }
.mr-var-add:disabled{ cursor:default; }
.mr-var-login{ background:#8a8178; }
.mr-var-login:hover{ background:#6f675f; }

/* In-flight and confirmed states. The panel no longer closes on add, so the card
   itself has to say what happened — otherwise a second tap feels like the first
   one did nothing. */
.mr-var-add.is-busy{
  position:relative;
  min-width:62px;
  color:transparent;
}
.mr-var-add.is-busy::after{
  content:'';
  position:absolute; top:50%; left:50%;
  width:13px; height:13px; margin:-6.5px 0 0 -6.5px;
  border:2px solid rgba(255,255,255,.35);
  border-top-color:#fff;
  border-radius:50%;
  animation:mrDiscSpin .7s linear infinite;
}
.mr-var-add.is-done{
  background:#1f7a3d;
  opacity:1;
}

.mr-var.is-added{
  border-color:#bcd8c5;
  background:#f6fbf7;
}

/* -------------------------------------------------------- variant lightbox
   Opened from a thumbnail in the add-to-order sheet, so it has to sit above it. */

.mr-var-thumb{ cursor:zoom-in; }

.mr-lb{
  position:fixed; inset:0;
  z-index:1000000030;
  background:rgba(12,8,6,.94);
  display:none;
}
.mr-lb.is-open{ display:block; }

.mr-lb-stage{
  position:absolute; inset:0 0 96px 0;
  overflow:hidden;
}

.mr-lb-track{
  display:flex;
  height:100%;
  transition:transform .28s cubic-bezier(.22,.8,.3,1);
  will-change:transform;
}

.mr-lb-slide{
  flex:0 0 100%;
  height:100%;
  margin:0;
  display:flex; align-items:center; justify-content:center;
  padding:22px;
}
.mr-lb-slide img{
  max-width:100%; max-height:100%;
  object-fit:contain;              /* the whole piece, never cropped */
  border-radius:6px;
  user-select:none; -webkit-user-drag:none;
}

.mr-lb-close{
  position:absolute; top:14px; right:14px;
  z-index:3;
  width:48px; height:48px;
  border:0; border-radius:50%;
  background:rgba(255,255,255,.14);
  color:#fff;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer;
}
.mr-lb-close svg{ width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:1.9; }

.mr-lb-nav{
  position:absolute; top:50%; transform:translateY(-50%);
  z-index:3;
  width:52px; height:52px;
  border:0; border-radius:50%;
  background:rgba(255,255,255,.14);
  color:#fff;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer;
}
.mr-lb-nav:hover{ background:rgba(255,255,255,.24); }
.mr-lb-nav svg{ width:24px; height:24px; fill:none; stroke:currentColor; stroke-width:2; }
.mr-lb-prev{ left:12px; }
.mr-lb-next{ right:12px; }

.mr-lb-foot{
  position:absolute; left:0; right:0; bottom:0;
  padding:0 18px max(18px, env(safe-area-inset-bottom));
  text-align:center;
}
.mr-lb-cap{
  color:#fff;
  font-size:13.5px; letter-spacing:.03em;
  margin:0 0 10px;
}
.mr-lb-dots{ display:flex; justify-content:center; gap:6px; }
.mr-lb-dots i{
  width:7px; height:7px; border-radius:50%;
  background:rgba(255,255,255,.35);
  transition:background .2s ease, transform .2s ease;
}
.mr-lb-dots i.is-on{ background:var(--mrd-gold,#c9a15f); transform:scale(1.25); }

/* Touch devices swipe; the arrows just eat the photo's width. */
@media (max-width:767px){
  .mr-lb-nav{ display:none; }
  .mr-lb-slide{ padding:14px; }
  .mr-lb-close{ width:52px; height:52px; }
  .mr-lb-close svg{ width:24px; height:24px; }
}

/* ------------------------------------------------------------------ toast */

.mr-disc-toast{
  position:fixed; left:50%; bottom:26px;
  transform:translate(-50%,14px);
  z-index:1000000020;
  background:rgba(20,16,14,.94);
  color:#fff;
  font-size:13px;
  padding:11px 18px;
  border-radius:999px;
  opacity:0;
  pointer-events:none;
  transition:opacity .2s ease, transform .2s ease;
  max-width:88vw; text-align:center;
}
.mr-disc-toast.is-on{ opacity:1; transform:translate(-50%,0); }

/* ------------------------------------------------------------- responsive */

@media (max-width:767px){
  .mr-disc{ padding-bottom:86px; }     /* clears the mobile bottom bar */
  .mr-post{
    margin:0 0 14px;
    border-left:0; border-right:0;
    border-radius:0;
  }
  .mr-disc-rail{ padding:8px 8px 8px; gap:9px; }
  .mr-disc-ring{ width:60px; height:60px; }
  .mr-disc-cat{ width:62px; }
  .mr-disc-cat b{ font-size:11px; }

  /* Sized against a real iPhone, not an emulator: big enough to read against a
     full-bleed product photo, then pulled back 20% from a first pass that overshot.
     Still well clear of Apple's 44px target minimum. */
  /**
   * Sized off the viewport, not in fixed pixels.
   *
   * These were 54px boxes around 40px glyphs, a figure arrived at on an iPhone. On a
   * narrower Android the same 40px eats a far bigger share of the row and reads as
   * bulky — the pixels did not change, the proportion did. vw fixes the actual problem:
   *
   *   360px phone -> 31.7px glyph      390px -> 34.3px      430px -> 37.8px
   *
   * so a narrow screen gets its bulk back and a large one keeps roughly the size the
   * owner approved. The clamp floor keeps the tap target legal on a very small screen
   * and the ceiling stops a tablet-ish width inflating them again.
   */
  /**
   * The mobile BASELINE is the Android size: 33px glyph in a 45px box.
   *
   * FROZEN — 2026-08-11. The owner signed this off as correct on Android after several
   * rounds. Do not retune it to fix something seen on an iPhone: iOS has its own block
   * at the end of this file, and that separation is the whole point. The box stays at
   * 45px, comfortably over the 40px floor a tap target needs.
   *
   * iOS takes 15% the other way, in its own block at the end of this file. Width cannot
   * separate the two platforms — a modern iPhone is 375-430 and a modern Android 360-412,
   * so they overlap — which is why the last two attempts fixed one phone by breaking the
   * other. The platform itself has to be the condition, not the width.
   */
  .mr-post-actions{ gap:5px; padding:10px 8px 4px; }
  .mr-act{ width:45px; height:45px; }
  .mr-act svg{ width:33px; height:33px; stroke-width:1.5; }

  .mr-post-play{ padding:7px 13px; font-size:12px; }
  .mr-post-play svg{ width:15px; height:15px; }
  .mr-post-dots i{ width:7px; height:7px; }

  .mr-post-avatar{ width:38px; height:38px; font-size:12px; }
  .mr-post-id a{ font-size:14.5px; }
  .mr-post-sub{ font-size:11.5px; }
  .mr-post-price{ font-size:16.5px; }
  .mr-post-caption{ font-size:13.5px; }
  .mr-post-tags a{ font-size:12.5px; }
  .mr-post-login{ font-size:12px; padding:8px 14px; }

  /* Reel chrome: the rail is the primary way to act on a reel, so it gets the
     biggest step up. */
  /* Spacing and sizing taken off the Instagram mobile reel the owner sent: icons a
     little over 30px, roughly 68px between one icon and the next, sitting close to the
     right edge. The old rail was ~78px apart with 12px captions, which read as a menu
     rather than a set of controls. */
  .mr-reel-rail{ gap:15px; bottom:24px; right:8px; }
  .mr-reel-act{ padding:3px 6px; gap:2px; }
  .mr-reel-act svg{ width:33px; height:33px; stroke-width:1.7; }
  .mr-reel-act small{ font-size:10px; letter-spacing:.02em; opacity:.9; }

  /* Heavier shadow than the desktop rail gets: on mobile these sit ON the video, and
     a hairline white glyph over pale gold is exactly what disappears. */
  .mr-reel-act svg{ filter:drop-shadow(0 1px 3px rgba(0,0,0,.7)); }
  .mr-reel-act small{ text-shadow:0 1px 3px rgba(0,0,0,.75); }

  .mr-reel-close,.mr-reel-sound{ width:48px; height:48px; }
  .mr-reel-close svg,.mr-reel-sound svg{ width:24px; height:24px; }

  /* Still readable at arm's length, but a fraction of the height it used to take. */
  .mr-reel-info{ right:72px; padding:10px 14px 16px; }
  .mr-reel-info h3{ font-size:14px; }
  .mr-reel-sku{ font-size:10.5px; }
  .mr-reel-price{ font-size:16.5px; }
  .mr-reel-login{ font-size:11px; padding:5px 12px; }

  /* The order panel is thumb-driven. Note the old row-layout overrides are gone:
     a fixed 52px image would have fought the card grid's full-width thumbnail. */
  .mr-var{ padding:8px; gap:7px; }
  .mr-var-id b{ font-size:13px; }
  .mr-var-qty{ height:38px; }
  .mr-var-qty button{ width:34px; }
  .mr-var-qty button svg{ width:16px; height:16px; }
  .mr-var-qty input{ width:34px; font-size:14px; }
  .mr-var-add{ font-size:11.5px; padding:10px 12px; }
}

/* Desktop reel: keep the close button clear of the phone-shaped stage. */
@media (min-width:768px){
  .mr-reel-close{ left:20px; top:18px; }
  .mr-reel-sound{ right:20px; top:18px; }
  .mr-reel-stage{ border-radius:12px; }
}

@media (prefers-reduced-motion:reduce){
  .mr-sheet-card{ animation:none; }
  .mr-reel-hint{ animation:none; opacity:.85; }
}


/* ===================================================== desktop reel layout ===
   Modelled on Instagram's web reels, which the owner asked for by example: the clip
   is an inset portrait pane, the actions sit OUTSIDE it to the right rather than on
   top of the jewellery, and a pair of arrows on the far right say "there is more".
   The left-hand side of Instagram's layout (profile block, caption column) is
   deliberately NOT copied — the owner asked to skip it, and our caption already
   lives in the pane.

   The rail is a sibling of .mr-reel-stage, not a child: the stage is overflow:hidden
   to contain the blurred backdrop, so anything placed beside the video from inside it
   would simply be clipped away.
   ========================================================================== */

.mr-reel-nav{ display:none; }

@media (min-width:1024px){

  .mr-reel-slide{
    display:flex; flex-direction:row;
    align-items:center; justify-content:center;
    gap:20px;
  }

  /* Sized off the viewport height so the pane is always a true portrait rectangle
     with breathing room top and bottom. No padding on the slide to achieve it —
     the slide is height:100% and a scroll-snap target, and padding there is exactly
     what pushes a snap container out of alignment. */
  .mr-reel-stage{
    flex:0 0 auto;
    width:auto;
    height:calc(100vh - 52px);
    aspect-ratio:9 / 16;
    max-width:min(52vw, calc((100vh - 52px) * 9 / 16));
    border-radius:10px;
    box-shadow:0 18px 60px rgba(0,0,0,.55);
  }

  /* Out of the video and alongside it. flex-end plus the same 26px the stage is
     inset by lines the last icon up with the bottom of the clip. */
  .mr-reel-rail{
    position:static;
    align-self:flex-end;
    margin:0 0 26px;
    gap:22px;
    flex:0 0 auto;
  }

  .mr-reel-act{ padding:2px 4px; gap:5px; }
  .mr-reel-act svg{
    width:26px; height:26px; stroke-width:1.7;
    filter:none;                      /* off the video now, so no shadow needed */
  }
  .mr-reel-act small{ font-size:11px; letter-spacing:.03em; opacity:.85; }
  .mr-reel-act:hover{ opacity:1; transform:translateY(-1px); }
  .mr-reel-act{ transition:transform .14s ease, opacity .14s ease; }

  /* The caption has the pane to itself again, so it can sit clear of the rail. */
  .mr-reel-info{ right:0; padding:14px 18px 18px; }
  .mr-reel-info h3{ font-size:14px; }

  /* --- next / previous ---------------------------------------------------- */
  .mr-reel-nav{
    display:flex; flex-direction:column; gap:14px;
    position:fixed; top:50%; right:34px;
    transform:translateY(-50%);
    z-index:6;
  }

  .mr-reel-navbtn{
    width:44px; height:44px;
    display:flex; align-items:center; justify-content:center;
    border:0; border-radius:50%;
    background:rgba(255,255,255,.92);
    color:#1a1a1a;
    cursor:pointer;
    transition:background .14s ease, transform .14s ease, opacity .14s ease;
  }
  .mr-reel-navbtn svg{ width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:2; }
  .mr-reel-navbtn:hover{ background:#fff; transform:scale(1.06); }
  .mr-reel-navbtn:active{ transform:scale(.94); }

  /* Kept in place rather than hidden: an arrow that vanishes at the first reel makes
     the whole control jump, and a dimmed one still reads as "nothing above here". */
  .mr-reel-navbtn:disabled{
    opacity:.32; cursor:default; transform:none;
    background:rgba(255,255,255,.5);
  }

  /* Clear of the arrows. */
  .mr-reel-sound{ right:92px; }
}

/* Wider still: nudge the arrows out so they never crowd the rail. */
@media (min-width:1400px){
  .mr-reel-nav{ right:56px; }
  .mr-reel-sound{ right:116px; }
}

/* ============================================================== tooltips ===
   Scoped to Discover's own surfaces, never a bare [data-tip] selector — the
   storefront has its own tooltip conventions and this must not reach them.

   Hover-capable, fine pointers only. On a touch screen :hover latches after a tap
   and the bubble sits there over the jewellery until you tap elsewhere, so there is
   nothing to gain and a stuck label to lose. Phones keep the aria-labels, which is
   what actually serves a screen reader.

   Pure CSS on ::after/::before: no JS, no listeners on every icon, and nothing to
   leak when the feed recycles cards.
   ========================================================================== */

@media (hover:hover) and (pointer:fine){

  /**
   * position:relative ONLY on hosts that are statically positioned.
   *
   * A blanket `[data-tip]{ position:relative }` looked harmless and was not. At (0,1,1)
   * and later in the file it beat .mr-post-sound, .mr-reel-close and .mr-reel-sound —
   * all three position:absolute — and knocked them out of place. The feed's mute button
   * ended up 20px BELOW its media box and was clipped away entirely by the media's
   * overflow:hidden, and the reel's close and mute buttons lost their corners too.
   *
   * An already-positioned element is already a containing block for its own
   * pseudo-elements, so it needs nothing from here. Only add classes to this list that
   * are genuinely static, and check the computed position before doing so.
   */
  .mr-disc .mr-act[data-tip],
  .mr-reel .mr-reel-act[data-tip],
  .mr-reel .mr-reel-navbtn[data-tip]{ position:relative; }

  .mr-disc [data-tip]::after,
  .mr-reel [data-tip]::after,
  .mr-sheet [data-tip]::after{
    content:attr(data-tip);
    position:absolute;
    left:50%; bottom:calc(100% + 9px);
    transform:translate(-50%, 4px);
    z-index:40;

    white-space:nowrap;
    padding:6px 10px;
    border-radius:7px;
    background:rgba(18,16,15,.94);
    -webkit-backdrop-filter:blur(6px);
    backdrop-filter:blur(6px);
    border:1px solid rgba(255,255,255,.08);
    box-shadow:0 6px 20px rgba(0,0,0,.28);

    color:#fff;
    font-size:11px; font-weight:600; letter-spacing:.03em;
    line-height:1.25; text-transform:none;

    opacity:0; pointer-events:none;
    /* Delay on the way IN only, so dragging the cursor across a row of icons does not
       fire four bubbles; instant on the way out. */
    transition:opacity .16s ease .38s, transform .16s ease .38s;
  }

  /* The caret. Same colour as the bubble, no border, so the two read as one shape. */
  .mr-disc [data-tip]::before,
  .mr-reel [data-tip]::before,
  .mr-sheet [data-tip]::before{
    content:'';
    position:absolute;
    left:50%; bottom:calc(100% + 4px);
    transform:translate(-50%, 4px);
    z-index:41;
    width:8px; height:8px;
    background:rgba(18,16,15,.94);
    clip-path:polygon(50% 100%, 0 0, 100% 0);
    opacity:0; pointer-events:none;
    transition:opacity .16s ease .38s, transform .16s ease .38s;
  }

  .mr-disc [data-tip]:hover::after,
  .mr-disc [data-tip]:focus-visible::after,
  .mr-reel [data-tip]:hover::after,
  .mr-reel [data-tip]:focus-visible::after,
  .mr-sheet [data-tip]:hover::after,
  .mr-sheet [data-tip]:focus-visible::after,
  .mr-disc [data-tip]:hover::before,
  .mr-disc [data-tip]:focus-visible::before,
  .mr-reel [data-tip]:hover::before,
  .mr-reel [data-tip]:focus-visible::before,
  .mr-sheet [data-tip]:hover::before,
  .mr-sheet [data-tip]:focus-visible::before{
    opacity:1;
    transform:translate(-50%, 0);
  }

  /* --- to the LEFT: the reel rail and the nav arrows hug the right edge, and a
         centred bubble there would run off the window. -------------------- */
  .mr-reel [data-tip-pos="left"]::after{
    left:auto; right:calc(100% + 9px);
    bottom:50%;
    transform:translate(4px, 50%);
  }
  .mr-reel [data-tip-pos="left"]::before{
    left:auto; right:calc(100% + 4px);
    bottom:50%;
    transform:translate(4px, 50%) rotate(-90deg);
  }
  .mr-reel [data-tip-pos="left"]:hover::after,
  .mr-reel [data-tip-pos="left"]:focus-visible::after{ transform:translate(0, 50%); }
  .mr-reel [data-tip-pos="left"]:hover::before,
  .mr-reel [data-tip-pos="left"]:focus-visible::before{ transform:translate(0, 50%) rotate(-90deg); }

  /* --- to the RIGHT: the feed's sound button sits at the media's bottom-left, where
         a bubble above it would be clipped by the media box. --------------- */
  .mr-disc [data-tip-pos="right"]::after{
    left:calc(100% + 9px); right:auto;
    bottom:50%;
    transform:translate(-4px, 50%);
  }
  .mr-disc [data-tip-pos="right"]::before{
    left:calc(100% + 4px); right:auto;
    bottom:50%;
    transform:translate(-4px, 50%) rotate(90deg);
  }
  .mr-disc [data-tip-pos="right"]:hover::after,
  .mr-disc [data-tip-pos="right"]:focus-visible::after{ transform:translate(0, 50%); }
  .mr-disc [data-tip-pos="right"]:hover::before,
  .mr-disc [data-tip-pos="right"]:focus-visible::before{ transform:translate(0, 50%) rotate(90deg); }

  /* The media clips its children, so a tip on the sound button needs the box opened
     up for the moment it is showing. Only while hovered, so nothing else escapes. */
  .mr-post-media:has(.mr-post-sound:hover){ overflow:visible; z-index:3; }

  @media (prefers-reduced-motion:reduce){
    .mr-disc [data-tip]::after,  .mr-reel [data-tip]::after,  .mr-sheet [data-tip]::after,
    .mr-disc [data-tip]::before, .mr-reel [data-tip]::before, .mr-sheet [data-tip]::before{
      transition:opacity .01ms;
    }
  }
}

/* ========================================================== focus rings ====
   The browser's own focus ring, again — the same thing that boxed the category
   chips. On the action icons it draws a rounded rectangle around the heart or the
   trolley the moment you click one, which on a white card is the most prominent
   thing in the row. Gone for the pointer.

   NOT gone for the keyboard. Tabbing through a feed with no visible focus is
   unusable, so :focus-visible keeps an indicator — a soft gold ring, offset so it
   traces the glyph rather than boxing it, in the same gold the rail already uses.
   Chrome and Safari only match :focus-visible for keyboard interaction on buttons,
   which is exactly the split we want.

   Deliberately NOT a blanket [class] { outline:none }: this lists the surfaces so a
   future control cannot lose its focus indication by accident.
   ========================================================================== */

.mr-disc button:focus,
.mr-disc a:focus,
.mr-reel button:focus,
.mr-sheet button:focus{ outline:none; }

.mr-disc button:focus-visible,
.mr-disc a:focus-visible,
.mr-reel button:focus-visible,
.mr-sheet button:focus-visible{
  outline:2px solid rgba(201,161,95,.6);
  outline-offset:2px;
  border-radius:8px;
}

/* The chips have their own treatment (a gold ring on the thumbnail), so keep this
   generic one off them. */
.mr-disc .mr-disc-cat:focus-visible{ outline:none; }

/* ================================================ modals over the reel ====
   The reel is fixed at z-index 1000000000, above the site header. Bootstrap modals sit
   at ~1050, so a login or inquiry form opened from inside the reel used to render
   BEHIND it — which is why the code closed the reel first and dropped the reader back
   to the feed to sign in.

   While the reel is open (body carries .mr-reel-lock) every modal is lifted above it,
   so the form appears over the slide and the reader keeps their place. Scoped to that
   class so nothing changes for modals anywhere else on the storefront.
   ========================================================================== */

/**
 * !important, reluctantly but deliberately.
 *
 * The theme already puts #login_modal at 99999999, so the FORM was fine. The backdrop
 * is another matter: something in the theme pins it at 9999999 with a priority this
 * rule could not beat on specificity alone — measured, our 10000090 lost to it — which
 * left the reel showing at full brightness behind the form instead of dimmed under it.
 * The declaration is scoped to body.mr-reel-lock, so it applies only while the reel is
 * actually open and every other modal on the storefront is untouched.
 */
body.mr-reel-lock .modal-backdrop,
body.mr-reel-lock .modal-backdrop.show{ z-index:1000000090 !important; }

body.mr-reel-lock .modal{ z-index:1000000100 !important; }

/* The theme's ajax spinner shows while the login form is being fetched, and has to
   clear the modal it belongs to. */
body.mr-reel-lock #overlay{ z-index:1000000120 !important; }

/* =========================================== already in the order =========
   Same idea as the heart for the wish list: the trolley fills in when any variation of
   the product is in the open order, so a card or a slide reads at a glance without
   opening the panel. Maroon rather than the heart's pink, because this is a commercial
   state and not a sentiment.
   ========================================================================== */

.mr-act-cart.is-incart svg,
.mr-reel-cart.is-incart svg{
  fill:var(--mrd-maroon, #610000);
  stroke:var(--mrd-maroon, #610000);
}

/* On the reel the rail sits on the photograph on mobile, so the filled glyph needs the
   same white keyline the other icons get, or maroon-on-dark disappears. */
@media (max-width:767px){
  .mr-reel-cart.is-incart svg{
    fill:#fff; stroke:#fff;
    filter:drop-shadow(0 1px 3px rgba(0,0,0,.75));
  }
  .mr-reel-cart.is-incart small{ color:#fff; }
}

/* --- the panel's add / remove buttons ------------------------------------
   Icons, not words. "Remove from order" cannot sit beside the quantity stepper on a
   phone at a size that stays tappable, and an icon pair with tooltips says the same
   thing in the space available. */

.mr-var-add,
.mr-var-del{
  flex:0 0 auto;
  width:42px; height:36px;
  display:flex; align-items:center; justify-content:center;
  border:0; border-radius:9px;
  cursor:pointer;
  transition:background .16s ease, opacity .16s ease, transform .12s ease;
}

.mr-var-add{ background:var(--mrd-maroon, #610000); color:#fff; }
.mr-var-add:hover{ filter:brightness(1.12); }

/* Remove is outlined, not filled: it must be reachable but never the loudest thing in
   the row, or a panel of ordered variations reads as a wall of destructive buttons. */
.mr-var-del{
  background:#fdf3f3;
  color:#a33;
  box-shadow:inset 0 0 0 1px rgba(163,51,51,.35);
}
.mr-var-del:hover{ background:#fbe9e9; }

.mr-var-add svg,
.mr-var-del svg{
  width:19px; height:19px;
  fill:none; stroke:currentColor; stroke-width:1.9;
}

.mr-var-add:active,
.mr-var-del:active{ transform:scale(.94); }

.mr-var-add:disabled,
.mr-var-del:disabled{ opacity:.55; cursor:default; }

/* Mid-request: the glyph is replaced by a spinner so the row cannot be double-fired. */
.mr-var-add.is-busy svg,
.mr-var-del.is-busy svg{ visibility:hidden; }
.mr-var-add.is-busy::after,
.mr-var-del.is-busy::after{
  content:'';
  position:absolute;
  width:15px; height:15px;
  border:2px solid currentColor; border-top-color:transparent;
  border-radius:50%;
  animation:mrDiscSpin .7s linear infinite;
}
.mr-var-add, .mr-var-del{ position:relative; }

.mr-var-add.is-done{ background:#1d7a45; }

/* A row already in the order gets a quiet tint, so the state is legible even before
   the reader parses which button is which. */
.mr-var.is-incart{ background:#fbf7f4; }

/* ===================================== recently updated category ring =====
   Instagram's unseen-story ring, doing a different job: this category gained a product
   in the last week.

   The rim is the whole signal, so it is BOTH thicker than a normal chip's and gradient
   — the owner cut ring thickness to 55% earlier for the resting state, and that stays;
   only a fresh chip gets the extra weight, which is what makes freshness legible at a
   glance in a row of otherwise identical circles.

   The sweep is a rotating pseudo-element rather than an animated conic gradient:
   animating a gradient angle needs @property, which is Chromium-only, whereas rotating
   a layer works everywhere and composites on the GPU.
   ========================================================================== */

.mr-disc-cat.is-fresh .mr-disc-ring{
  position:relative;
  padding:3.4px;                        /* against 1.4px at rest — the weight IS the cue */
  background:transparent;
  overflow:hidden;

  /* A breathing halo as well as the sweep. The rim alone only reads once you look at
     the chip; a halo that expands and fades catches the eye that is not looking yet,
     which is what "more prominent" actually needs. */
  animation:mrRingGlow 2.4s ease-in-out infinite;
}

.mr-disc-cat.is-fresh .mr-disc-ring::before{
  content:'';
  position:absolute; inset:-25%;

  /* The near-white stop is the point of this gradient. A smoothly graded ring rotating
     is almost impossible to perceive — the eye needs an EDGE to track, so there is a
     narrow bright glint that travels round the rim. Everything else is the house
     maroon-and-gold. */
  background:conic-gradient(from 0deg,
              var(--mrd-maroon) 0deg,
              #a33 40deg,
              var(--mrd-gold) 92deg,
              #fff4de 118deg,
              var(--mrd-gold) 146deg,
              #8a1a1a 240deg,
              var(--mrd-maroon) 360deg);

  animation:mrRingSweep 2.8s linear infinite;
}

@keyframes mrRingGlow{
  0%, 100% { box-shadow:0 0 0 0 rgba(201,161,95,.6); }
  55%      { box-shadow:0 0 0 6px rgba(201,161,95,0); }
}

/* The thumbnail sits above the sweep, so only the rim shows it. */
.mr-disc-cat.is-fresh .mr-disc-ring > span{
  position:relative;
  z-index:1;
}

@keyframes mrRingSweep{ to{ transform:rotate(360deg); } }

/* Subtle, on purpose: one slow revolution, no pulsing, nothing that competes with the
   jewellery below it. Seven seconds reads as "alive" without drawing the eye off the
   feed. */
@media (prefers-reduced-motion:reduce){
  .mr-disc-cat.is-fresh .mr-disc-ring,
  .mr-disc-cat.is-fresh .mr-disc-ring::before{ animation:none; }
  /* Still obvious standing still: the thick gradient rim carries it on its own. */
  .mr-disc-cat.is-fresh .mr-disc-ring::before{ background:linear-gradient(135deg,var(--mrd-gold),var(--mrd-maroon) 70%); }
}

/* ============================================ out of stock ================
   A corner ribbon rather than a badge or an overlay. A chip would have to queue up
   with the REEL badge, the counter pill and the sound button; a full overlay would
   hide the jewellery, which is the one thing the reader came for. A stamp across the
   corner is unmissable and costs almost none of the picture.

   Built from a rotated band clipped by the media box, so there is no image to load and
   nothing to go wrong at any card size.
   ========================================================================== */

.mr-post-ribbon,
.mr-reel-ribbon{
  position:absolute; top:0; left:0;
  width:112px; height:112px;
  overflow:hidden;
  z-index:6;
  pointer-events:none;
}

/**
 * The band has to be CENTRED ON THE CORNER DIAGONAL, or it renders as a lopsided wedge
 * with the text running off one end — which is exactly what it was doing.
 *
 * The arithmetic, so the next person does not have to rediscover it: place the band's
 * centre at (d, d) and, rotated -45deg, it spans the line x + y = 2d, entering at
 * (0, 2d) and leaving at (2d, 0). With d = 40 the visible chord is 40 x 2 x sqrt(2) =
 * 113px, comfortably more than the ~72px "SOLD OUT" needs at this size, and the band is
 * symmetrical about the corner because its centre sits on the diagonal.
 *
 * Hence width 160 (half-length 80, more than the 57 needed so both ends clip cleanly),
 * left -40 to put the centre at x = 40, and top 27 to put it at y = 40 once the band's
 * own height is accounted for. The previous numbers had the centre at (51, 37.5) — 13.5px
 * off the diagonal, which is the whole defect.
 */
.mr-post-ribbon i,
.mr-reel-ribbon i{
  position:absolute;
  top:27px; left:-40px;
  width:160px;
  padding:6px 0;
  transform:rotate(-45deg);

  background:linear-gradient(135deg, #7a1414, var(--mrd-maroon, #610000) 55%, #3f0000);
  box-shadow:0 2px 10px rgba(0,0,0,.35);

  color:#fff;
  font-size:10px; font-weight:800; letter-spacing:.12em;
  line-height:1.25;
  text-transform:uppercase; font-style:normal;
  text-align:center;
  white-space:nowrap;
  /* A gold hairline top and bottom: the detail that stops it reading as a flat sticker. */
  border-top:1px solid rgba(201,161,95,.55);
  border-bottom:1px solid rgba(201,161,95,.55);
}

/* On a reel the ribbon shares the corner with the close button, so it starts lower. */
.mr-reel-ribbon{ top:56px; }

/* --- the order icon, read-only ------------------------------------------
   Kept in place and dimmed rather than hidden: the row holds its shape, the reader can
   see the action exists, and the tooltip says why it is unavailable. */
.mr-act-cart.is-locked,
.mr-reel-cart.is-locked{
  opacity:.4;
  cursor:not-allowed;
}
.mr-act-cart.is-locked:active,
.mr-reel-cart.is-locked:active{ transform:none; }

/* A locked icon must never look "filled in" as though it were ordered. */
.mr-act-cart.is-locked svg,
.mr-reel-cart.is-locked svg{ fill:none; }

/* ============================================== iOS icon sizing ===========
   The one place in this file that targets a platform rather than a viewport.
   
   Android and iOS overlap in CSS width, so no media query can tell them apart — that is
   why two rounds of width-based tuning each fixed one phone and broke the other. What
   DOES separate them is the engine: -webkit-touch-callout is implemented by iOS WebKit
   and by nothing else, so @supports for it is a reliable iOS test that needs no
   user-agent sniffing and no JavaScript.
   
   Wrapped in a touch-device query as well, so a desktop WebKit that happens to
   understand the property can never pick this up.
   
   15% above the 40/54 baseline the owner approved on an iPhone, which is what was asked
   for: a 46px glyph in a 62px box. Android keeps the smaller size set in the mobile
   block above.
   ========================================================================== */

@media (hover:none) and (pointer:coarse){
  @supports (-webkit-touch-callout:none){
    /**
     * Button back to 62px — shrinking it to 52px last time read as the icons getting
     * smaller again, which was not the intent and is not what was asked for.
     *
     * The space comes out of the LAYOUT instead, leaving the button alone: the gap goes
     * to zero and each button pulls 3px into its neighbour. Between two glyphs that is
     * 8 + 8 of box padding, minus 6 of overlap = 10px, against 21px originally. The
     * tap target stays a full 62px because a negative margin moves the box without
     * resizing it — the one way to tighten the look and keep the target.
     *
     * margin-left:auto has to be restated for the trolley: the shorthand-free margins
     * above would otherwise cancel the rule that pushes it to the right-hand end.
     */
    .mr-post-actions{ gap:0; padding:10px 8px 4px; }

    .mr-act{
      width:62px; height:62px;
      margin-left:-3px; margin-right:-3px;
    }
    .mr-act svg{ width:46px; height:46px; stroke-width:1.45; }

    .mr-act-cart{ margin-left:auto; margin-right:-3px; }
  }
}
