/* ==========================================================================
   Silacart — Offers page
   Loaded AFTER assets/css/style.css. Nothing in the existing stylesheet is
   modified or overridden; every class here is prefixed `off-` and everything
   is scoped under .offers-page.
   ========================================================================== */

.offers-page {
  /* Section tints, per the mockup's alternating bands. The hero and the promo
     carousel share this warm sand ground, so it runs unbroken behind both —
     but only inside the container, never edge to edge. */
  --off-cream: #f8e4c9;
  --off-pink: #fdeff0;
  --off-blue: #eaf4fb;
  --off-light: #f6f8f9;
  --off-ivory: #fbfae7;

  /* Accents */
  --off-gold: #e0aa3e;
  --off-gold-dark: #c8912a;
  --off-teal: #009dab;
  --off-teal-dark: #007a85;
  /* The View all button's own teal, a step darker than --off-teal. Separate
     because --off-teal-dark is the *hover* of --off-teal and lands lighter
     than this, so it cannot serve as this button's ground or its hover. */
  --off-viewall-bg: #006671;
  --off-viewall-bg-dark: #00505a;
  --off-brown: #4a3423;
  --off-brown-2: #8a6a45;
  --off-hero-brown: #6d4e35;
  --off-hero-eyebrow: #e6b75b;
  --off-brands-bg: #0e7c88;
  --off-brands-panel: #d7fcff;
  --off-brand-badge: #10bfd0;
  --off-purple: #6d4b9f;
  --off-orange: #ef8f2a;
  --off-ink: #1f2937;
  --off-muted: #6b7280;
  --off-line: #e5e7eb;
  /* Carousel nav arrows, taken from the design's "Button - Navigation
     Arrows" component: 40px white circle, 1px #BCC9CB at 20%, #3D494B
     chevron. Deliberately its own tokens rather than --off-ink/--off-line,
     which the headings and card borders share. */
  --off-nav-size: 40px;
  --off-nav-ico: #3d494b;
  --off-nav-line: rgba(188, 201, 203, 0.2);
  --off-radius: 12px;
  --off-radius-lg: 20px;
}

/* Long single-word headlines (product names, brand names) wrap instead of
   pushing their card wide — the design sets this on the `sc-page` element,
   which here is `.offers-page` itself. */
.offers-page h1,
.offers-page h2,
.offers-page h3,
.offers-page h6,
.offers-page p {
  overflow-wrap: break-word;
}

/* --------------------------------------------------------------------------
   Shared section shell
   -------------------------------------------------------------------------- */
.offers-page .off-section {
  padding-block: 34px;
}

.offers-page .off-tint-cream {
  background-color: var(--off-cream);
}

.offers-page .off-tint-pink {
  background-color: var(--off-pink);
}

.offers-page .off-tint-blue {
  background-color: var(--off-blue);
}

.offers-page .off-tint-light {
  background-color: var(--off-light);
}

.offers-page .off-tint-ivory {
  background-color: var(--off-ivory);
}

.offers-page .off-section-title {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.2px;
  color: var(--off-ink);
  margin-bottom: 0;
}

.offers-page .off-viewall {
  font-size: 13px;
  font-weight: 600;
  color: var(--off-teal);
  text-decoration: none;
  white-space: nowrap;
}

.offers-page .off-viewall:hover,
.offers-page .off-viewall:focus-visible {
  color: var(--off-teal-dark);
}

.offers-page .off-viewall-btn {
  display: inline-flex;
  align-items: center;
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  background-color: var(--off-teal);
  border-radius: 999px;
  padding: 9px 22px;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s ease;
}

.offers-page .off-viewall-btn:hover,
.offers-page .off-viewall-btn:focus-visible {
  background-color: var(--off-teal-dark);
  color: #fff;
}

.offers-page .off-btn-gold {
  display: inline-flex;
  align-items: center;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: #2a1c0d;
  background-color: var(--off-gold);
  border-radius: 999px;
  padding: 12px 30px;
  text-decoration: none;
  transition: background-color 0.15s ease;
}

.offers-page .off-btn-gold:hover,
.offers-page .off-btn-gold:focus-visible {
  background-color: var(--off-gold-dark);
  color: #2a1c0d;
}

/* --------------------------------------------------------------------------
   1. Hero
   -------------------------------------------------------------------------- */
.offers-page .off-hero {
  overflow: hidden;
}

.offers-page .off-hero-inner {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 300px;
  /* The sand ground sits on the inner block, so it is bounded by the container
     and never runs the full width of the viewport. */
  background-color: #f8e0c6;
  border-radius: 12px 12px 0 0;
  overflow: hidden;
}

/* The artwork fills the whole band; the copy overlays it. */
.offers-page .off-hero-media {
  position: absolute;
  inset: 0;
}

.offers-page .off-hero-img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center right;
}

.offers-page .off-hero-copy {
  position: relative;
  width: 36%;
  padding: 34px 12px 34px 50px;
  color: #fff;
}

/* Node 1472-11867. The 12px line box is the design's own — smaller than the
   18px type it holds, which is how the eyebrow sits tight above the title
   there. In CSS that only sizes the box; the caps still draw at their full
   height and simply overhang it by a pixel either side, which is what the
   design draws too. `margin-bottom` stays the frame gap's stand-in, so the
   shorter line box does open the eyebrow-to-title space by a few pixels. */
.offers-page .off-hero-eyebrow {
  font-size: 18px;
  font-weight: 800;
  line-height: 12px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--off-hero-eyebrow);
  margin-bottom: 16px;
}

/* Node 1472-11862: 40/52 ExtraBold at -1.68px. The line height is written as
   a ratio rather than the design's literal 52px because the title steps down
   to 32/27/24 below xl — a pinned 52px line box would stay behind and leave
   the smaller headings swimming in it. 1.3 is 52/40, so at full size it
   resolves to the design's figure exactly. The tracking stays absolute: it is
   an optical correction for this weight at this size, and scaling it with the
   font would undo the correction. */
.offers-page .off-hero-title {
  font-size: 40px;
  font-weight: 800;
  line-height: 1.3;
  letter-spacing: -1.68px;
  text-transform: uppercase;
  color: #fff;
  margin-bottom: 16px;
}

/* Node 1472-11865: 16/26 Medium in #EEEEEE. The colour was a 92% white, which
   lands close over the brown ground but drifts with whatever artwork the
   record carries — the design names a flat grey, so it is set flat.

   No ch cap here — the column width alone decides where the line breaks, which
   keeps the sentence on one line as the design has it. */
.offers-page .off-hero-text {
  font-size: 16px;
  font-weight: 500;
  line-height: 26px;
  letter-spacing: 0;
  color: #eeeeee;
  margin-bottom: 26px;
}

.offers-page .off-hero-copy .off-btn-gold {
  padding-block: 9px;
}

/* Lock the band's proportions so the artwork is never squeezed or letterboxed
   as the viewport widens. */
@media (min-width: 992px) {
  .offers-page .off-hero-inner {
    aspect-ratio: 1870 / 515;
  }
}

/* Between md and lg the artwork's brown panel is cropped away, so the white
   copy needs its own ground. Below md the image stacks above the copy on the
   solid brown block instead, and no scrim is wanted. */
@media (min-width: 768px) and (max-width: 991.98px) {
  .offers-page .off-hero-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
      90deg,
      rgba(56, 38, 24, 0.92) 0%,
      rgba(56, 38, 24, 0.72) 42%,
      rgba(56, 38, 24, 0.1) 100%
    );
  }
}

/* --------------------------------------------------------------------------
   2. Promo tile carousel
   -------------------------------------------------------------------------- */
/* The sand ground continues straight down from the hero with no break, and
   stops at the container edge rather than running edge to edge. */
.offers-page .off-promo-section {
  padding-block: 0 34px;
}

.offers-page .off-promo-band {
  padding: 38px 27px 44px;
  border-radius: 0 0 12px 12px;
  background: #f8e0c6;
}

/* The design's "Promo Card" frame is 280.83px fill-width x 408px fixed height.
   Expressed as a ratio rather than a fixed height because the carousel goes
   6-up / 3-up / 1.5-up across breakpoints — a literal 408px would leave the
   much wider 1.5-up mobile card squat. At the design's own width this ratio
   resolves to 408px exactly.

   The #D3E4FF at 30% is the frame's fill, sitting behind the photo; it shows
   only while the image loads or if one is missing. */
/*.offers-page .off-promo-tile {*/
/*  position: relative;*/
/*  display: block;*/
/*  border-radius: 12px;*/
/*  overflow: hidden;*/
/*  aspect-ratio: 281 / 408;*/
/*  background: rgba(211, 228, 255, 0.3);*/
/*  text-decoration: none;*/
/*}*/

.offers-page .off-promo-tile img {
  width: 100%;
  /*height: 100%;*/
  object-fit: cover;
  display: block;
}

/* Safari only learned `aspect-ratio` in 15. On anything older the declaration
   above is dropped, the tile keeps no height of its own, and the image's
   `height: 100%` resolves against an auto-height parent — i.e. to `auto` — so
   the row collapses to whatever the artwork happens to measure, or to nothing
   at all while it is still loading. The percentage-padding box is the same
   408:281 frame stated in a spelling every version understands; the image is
   taken out of flow so it fills the frame the padding reserves. */
@supports not (aspect-ratio: 1 / 1) {
  .offers-page .off-promo-tile {
    height: 0;
    /* 408 / 281 */
    padding-top: 145.196%;
  }
  .offers-page .off-promo-tile img {
    position: absolute;
    top: 0;
    left: 0;
  }
}

/* Copy sits at the TOP of the tile in the design. The scrim is barely there —
   just enough to hold the text apart from a light photograph. */
.offers-page .off-promo-copy {
  position: absolute;
  /* Longhands first, then the shorthand: `inset` is Safari 14.1, and without
     these an older iPhone drops the whole declaration and the copy falls back
     to `auto` on all four sides — i.e. into the tile's top-left corner at its
     shrink-to-fit width, over an unscrimmed photo. */
  top: 0;
  right: 0;
  left: 0;
  inset: 0 0 auto 0;
  display: block;
  padding: 22px 19px 26px;
  background: linear-gradient(
    180deg,
    rgba(9, 17, 28, 0.3) 0%,
    rgba(9, 17, 28, 0) 100%
  );
  color: #fff;
  border-radius: 15px 15px 0 0;
}

.offers-page .off-promo-eyebrow {
  display: block;
  font-size: 14px;
  line-height: 1.35;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.94);
  margin-bottom: 2px;
}

.offers-page .off-promo-head {
  display: block;
  font-size: 26px;
  font-weight: 700;
  line-height: 1.15;
  text-transform: uppercase;
  margin-bottom: 6px;
}

/* Word-based headlines are set a step down so they stay on one line, as in
   the design — the percentage headlines keep the full size. */
.offers-page .off-promo-head-sm {
  font-size: 22px;
}

.offers-page .off-promo-sub {
  display: block;
  font-size: 14px;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.94);
  margin-bottom: 18px;
}

.offers-page .off-promo-code {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  color: var(--off-ink);
  background-color: #fff;
  border-radius: 4px;
  padding: 4px 10px;
  margin-bottom: 14px;
}

.offers-page .off-promo-pill {
  display: inline-block;
  font-size: 14px;
  font-weight: 600;
  color: #fff;
  background-color: var(--off-teal);
  border-radius: 6px;
  padding: 8px 19px;
  transition: background-color 0.15s ease;
}

/*.offers-page .off-promo-tile:hover .off-promo-pill,*/
/*.offers-page .off-promo-tile:focus-visible .off-promo-pill {*/
/*  background-color: var(--off-teal-dark);*/
/*}*/

/* --------------------------------------------------------------------------
   3. Offers by category
   -------------------------------------------------------------------------- */
/* Title and the category picker, separated from the body by a hairline. */

/* 16px/21px in #3D494B, per the design's "Select Category" text node. The
   colour is the one the nav arrows already use (--off-nav-ico), not the
   muted grey the rest of the page's secondary copy takes — a slate rather
   than a neutral, and darker than --off-muted at #6b7280. */
.offers-page .off-cat-label {
  font-size: 16px;
  font-weight: 400;
  line-height: 21px;
  color: var(--off-nav-ico);
  margin-bottom: 0;
}

/* The tinted panel behind the whole section, per the design's 1864x1064
   frame. It lives inside .container-fluid rather than on the <section>, so
   the tint stops at the container's 1900px cap instead of running the full
   viewport — which is what left this the only band on the page bleeding
   edge to edge while the hero and the promo strip stayed inset.

   The <section>'s own padding-block still spaces this panel from the bands
   above and below; the 25px here is the gap between the panel's edge and
   its content. */
.offers-page .off-cat-panel {
  border-radius: var(--off-radius);
  padding: 25px;
}

/* The rating cluster is 4px between the star, the score and the count (node
   1472-12203); category_v2.css sets 3px. Everything else about it already
   matches the design — 12px SemiBold in #3D494B — so the gap is the only
   declaration here. */
.offers-page .sc-rating {
  gap: 4px;
}

/* 12px between "Select Category" and the dropdown — the design's own step,
   which falls between Bootstrap's gap-2 (8px) and gap-3 (16px). */
.offers-page .off-cat-picker {
  gap: 12px;
}

/* The design's 32px gap between the header block and the product grid. Its
   own class for the same reason: Bootstrap goes 24px (mb-4) then 48px (mb-5),
   with nothing at 32. */
.offers-page .off-cat-gap {
  margin-bottom: 32px;
}

/* Two gutters Bootstrap has no step for, set through its own custom
   properties so the columns keep doing the arithmetic:

   - 40px between the grid and the side banner. The design's row is 1814
     wide, holding a 1283 grid and a 491 banner; 1814 - 1283 - 491 = 40.
   - 20px between the cards. The grid block is 864 tall for two 422px rows,
     and 864 - 422 - 422 = 20. (The banner is 860, four short of the grid —
     which is why the gutter cannot be read off the banner's height.) */
.offers-page .off-cat-row {
  --bs-gutter-x: 40px;
  --bs-gutter-y: 40px;
}

/* The two axes differ, so they are set separately. Across: the Product Grid
   row is 1283 wide holding four 308.75 cards, and 1283 - (4 x 308.75) leaves
   48 over three gaps — 16 each. Down: the grid block is 864 for two 422 rows,
   which leaves 20. */
.offers-page .off-cat-grid {
  --bs-gutter-x: 16px;
  --bs-gutter-y: 20px;
}

/* The design's "Options" control: 183px fixed, 8px radius, 1px border, and
   asymmetric padding — 40px on the right to clear the chevron, 16px on the
   left for the label. */
.offers-page .off-select {
  border-radius: 8px;
  border: 1px solid #bcc9cb;
  background: #f5f3f3;
  font-size: 15px;
  font-weight: 500;
  width: 183px;
  padding: 8px 40px 8px 16px;
  font-family: inherit;
}

/* The chosen category, restated large, with the shortcut to the full listing. */

.offers-page .off-cat-title {
  font-size: 32px;
  font-weight: 700;
  color: var(--off-ink);
  margin-bottom: 0;
}

/* The design's View all button: #006671 on a 1px border of the same colour,
   8px radius, 8/24 padding and an 8px gap to the chevron.

   The fill is a full step darker than `--off-teal`, which is why the hover
   gets its own token — `--off-teal-dark` (#007a85) is *lighter* than this, so
   reusing it would brighten the button on hover instead of darkening it.

   min-height rather than the design's fixed 43px, so a longer label or a
   translation grows the button instead of clipping; the inline-flex centring
   inherited from .off-viewall-btn handles the extra room. */
.offers-page .off-cat-viewall {
  gap: 8px;
  border: 1px solid var(--off-viewall-bg);
  border-radius: 8px;
  font-size: 15px;
  padding: 8px 24px;
  min-height: 43px;
  background-color: var(--off-viewall-bg);
}

.offers-page .off-cat-viewall:hover,
.offers-page .off-cat-viewall:focus-visible {
  background-color: var(--off-viewall-bg-dark);
  border-color: var(--off-viewall-bg-dark);
}

/* Tall promo beside the grid; drops below it on mobile. `height: 100%` is
   what lands it level with the grid, whatever the grid measures.

   Uncapped on purpose. The earlier `max-height: 900px` was sized against the
   design's 860px banner with headroom, but live cards run taller than the
   design's 422px rows — real product names, the price row, the reserved
   heights that keep a row even — so the grid column measures 942 and the cap
   was clipping the banner 42px short of it. A ceiling here can only ever
   reintroduce that gap, since the grid's height is content-driven; the floor
   below is the half that has to stay, for a grid too short to fill the
   column. */
/* The box takes the artwork's own proportions rather than stretching to the
   grid beside it. The design's banner is 491x860 and the artwork shipped for
   it is 491x860 to the pixel, so a box of that ratio holds the whole image
   with nothing cropped at any width.

   `height: 100%` was the earlier reading of the design's "Fixed (860px)" —
   the banner and the grid do end level in the mockup, because 860 is what two
   422px cards and their gutter come to. But the height and the ratio cannot
   both be honoured once the real cards are taller than 422: stretching the box
   to a taller grid makes it narrower than 491/860, and `cover` then eats the
   sides — which is exactly what cropped "SUMMER SALE" off the top of the live
   banner. The ratio is the half worth keeping; the two lining up again is a
   matter of the card height, not of this rule. */
.offers-page .off-tall-promo {
  position: relative;
  display: block;
  aspect-ratio: 491 / 860;
  border-radius: var(--off-radius);
  overflow: hidden;
  text-decoration: none;
}
/* Static variant used when the banner has no live-offer target — rendered
   as a <span> instead of an <a>, so no default text-cursor / hover state. */
.offers-page .off-tall-promo--static {
  cursor: default;
}

/* `cover` still, not `contain`: with the box now on the artwork's own ratio
   the two agree, so `cover` crops nothing — and it keeps the box filled edge
   to edge if a future upload is a slightly different shape, where `contain`
   would letterbox it inside the rounded corners. */
.offers-page .off-tall-promo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The upper half of the tile is a flat dark ground in the design, with the
   photograph only showing through below it. */
.offers-page .off-tall-copy {
  position: absolute;
  inset: 0 0 auto 0;
  display: block;
  padding: 72px 20px 40px;
  text-align: center;
  color: #fff;
  background: linear-gradient(
    180deg,
    rgba(45, 52, 49, 0.97) 0%,
    rgba(45, 52, 49, 0.95) 55%,
    rgba(45, 52, 49, 0) 100%
  );
}

.offers-page .off-tall-kicker {
  display: block;
  font-size: 40px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--off-gold);
  margin-bottom: 6px;
}

.offers-page .off-tall-upto {
  display: flex;
  flex-direction: column;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.05;
  text-transform: uppercase;
}

.offers-page .off-tall-pct {
  font-size: 66px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -1px;
}

.offers-page .off-tall-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 999px;
  background-color: rgba(255, 255, 255, 0.08);
  padding: 7px 16px;
}

/* --------------------------------------------------------------------------
   4. Top fragrance brands
   -------------------------------------------------------------------------- */
.offers-page .off-brands {
  padding-block: 34px;
}

/* Teal banner on top, pale cyan panel below, joined as one rounded block.
   12px, per the panel node's bottom corners — not --off-radius-lg (20px),
   which stays as it is for the three other blocks that use it. */
.offers-page .off-brands-card {
  border-radius: var(--off-radius);
  overflow: hidden;
}

.offers-page .off-brands-banner {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 300px;
  padding: 54px 24px 54px 7%;
  background-color: var(--off-brands-bg);
  color: #fff;
}

/* The artwork is absolutely positioned after the copy in the markup, so
   without this it paints over the text. */
.offers-page .off-brands-copy {
  position: relative;
  z-index: 1;
  max-width: 52%;
}

/* Teal wash between artwork and copy, so the headline reads at every width. */
.offers-page .off-brands-banner::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(
    90deg,
    var(--off-brands-bg) 0%,
    rgba(14, 124, 136, 0.9) 34%,
    rgba(14, 124, 136, 0) 70%
  );
}

/* The artwork bleeds off the banner's right edge rather than sitting in the
   flow beside the copy. */
.offers-page .off-brands-strip {
  position: absolute;
  inset: 0 0 0 auto;
  width: 46%;
  height: 100%;
  object-fit: cover;
  object-position: left center;
}

.offers-page .off-brands-eyebrow {
  font-size: 17px;
  font-weight: 500;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--sc-amber);
  margin-bottom: 10px;
}

.offers-page .off-brands-title {
  font-size: 34px;
  font-weight: 700;
  line-height: 1.2;
  color: #fff;
  margin-bottom: 10px;
}

.offers-page .off-brands-sub {
  font-size: 16px;
  color: rgba(255, 255, 255, 0.9);
  margin-bottom: 0;
}

/* 30px above and below, 24px either side (node 1472-12763). The 47px row
   gap the same node specifies is on the grid inside, as --bs-gutter-y. */
.offers-page .off-brands-panel {
  background-color: var(--off-brands-panel);
  padding: 30px 24px;
}

.offers-page .off-brands-grid {
  --bs-gutter-x: 24px;
  --bs-gutter-y: 47px;
}

.offers-page .off-brand-tile {
  display: block;
  text-decoration: none;
  color: var(--off-ink);
  /* The tile is a flex item of `.off-brands-grid`, so its automatic minimum
     size is its content's min-content width — and the name below never wraps,
     which makes that the full run of text. A brand name longer than its share
     of the row would push the columns out of shape and wrap the grid. Zero is
     what lets the name be ellipsised instead of widening its column. */
  min-width: 0;
}

.offers-page .off-brand-thumb {
  position: relative;
  display: block;
  aspect-ratio: 282.67 / 320;
  border-radius: 10px;
  overflow: hidden;
  background-color: rgba(255, 255, 255, 0.6);
  /* No margin: the name row below carries its own 16px of top padding, which
     is what separates it from the artwork in the design. */
  margin-bottom: 0;
}

.offers-page .off-brand-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.3s ease;
}

.offers-page .off-brand-tile:hover .off-brand-thumb img,
.offers-page .off-brand-tile:focus-visible .off-brand-thumb img {
  transform: scale(1.06);
}

/* Sits low on the artwork in the design, not in the corner: node 1472-13347
   places it 21px from the left and 252px down a 320px box, which leaves 24px
   below it. 10px of padding around a 24px line box is what makes it 44 tall.

   The node reads "Width Fixed (138px)", but that is the DIOR instance being
   measured — AFNAN and 212 NYC carry "UP TO 50% OFF" in the same component
   and run wider. Left to hug, so the longer labels are not clipped. */
.offers-page .off-brand-badge {
  position: absolute;
  left: 21px;
  bottom: 24px;
  font-size: 24px;
  font-weight: 800;
  line-height: 24px;
  letter-spacing: 0;
  text-transform: uppercase;
  color: #fff;
  background-color: var(--off-brand-badge);
  padding: 10px;
  border-radius: 5px;
}

/* One line, then an ellipsis; the full name is on the tile's `title`, which
   is what a truncated name is read from. The design's name row is a single
   24px line — 16 + 24 + 16 is its 56px height — so a name that wrapped grew
   its tile past the row beside it. "MERCEDES BENZ" was doing exactly that.

   `nowrap` + `text-overflow` rather than the `-webkit-line-clamp: 1` this
   rule used to carry, because the clamp cannot finish the job here: it holds
   the box to one line, but `overflow: hidden` clips at the *padding* box, so
   the 16px of bottom padding left a 16px band of the second line still
   showing below the ellipsis. With no second line to leak there is nothing
   for the padding to reveal.

   The trade is that `nowrap` takes this element's min-content width back to
   the full run of text — a brand name with no spaces would push its column
   wider. `min-width: 0` on the tile above is what answers that, and it
   covers the case `overflow-wrap: anywhere` used to: the name is ellipsised
   at the column's own width whether or not it has a space to break at. */
.offers-page .off-brand-name {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* 28px/24px Bold in #1B1C1C, inside a row 16px padded on every side —
     16 + 24 + 16 is the design's 56px name row. The colour is the near-black
     the card copy uses, not --off-ink (#1f2937), which is a blue-grey. */
  padding: 16px;
  font-size: 20px;
  font-weight: 700;
  line-height: 24px;
  letter-spacing: 0;
  text-transform: uppercase;
  color: #1b1c1c;
}

/* --------------------------------------------------------------------------
   5/7/9/11. Product carousel rows
   Arrows sit just outside the track, matching the rest of the site.
   -------------------------------------------------------------------------- */
.offers-page .off-product-carousel .owl-nav button.owl-prev,
.offers-page .off-product-carousel .owl-nav button.owl-next {
  position: absolute;
  top: 42%;
  transform: translateY(-50%);
  width: var(--off-nav-size);
  height: var(--off-nav-size);
  border-radius: 50%;
  background-color: #fff;
  border: 1px solid var(--off-nav-line);
  color: var(--off-nav-ico);
  box-shadow: 0 12px 28px rgba(16, 24, 40, 0.12);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  transition:
    background-color 0.15s ease,
    color 0.15s ease;
}

.offers-page .off-product-carousel .owl-nav button.owl-prev {
  left: -19px;
}

.offers-page .off-product-carousel .owl-nav button.owl-next {
  right: -19px;
}

.offers-page .off-product-carousel .owl-nav button.owl-prev:hover,
.offers-page .off-product-carousel .owl-nav button.owl-next:hover,
.offers-page .off-product-carousel .owl-nav button.owl-prev:focus-visible,
.offers-page .off-product-carousel .owl-nav button.owl-next:focus-visible {
  background-color: var(--off-teal);
  border-color: var(--off-teal);
  color: #fff;
}

/* Owl 2.3.4 ships `touch-action: manipulation` on `.owl-stage`, which tells
   the browser it may claim a horizontal pan — the exact gesture the drag
   handlers need. 2.2.1 said `pan-Y` there and the handlers still assume it.
   `.owl-carousel.owl-drag .owl-item { touch-action: pan-y }` narrows it again
   on engines that intersect the whole ancestor chain, but iOS Safari settles
   the gesture off the nearer ancestor and swallows the swipe, so the strip
   cannot be dragged by hand on an iPhone.

   owl.carousel.min.css loads AFTER this file (core.xml lines 190 / 199), so a
   same-specificity rule here would lose; the `.offers-page` prefix is what
   wins the cascade. Scoped to this page, which is all this file governs. */
.offers-page .owl-carousel .owl-stage {
  touch-action: pan-y;
}

/* Every carousel item on this page IS a link wrapped around a full-bleed
   image — the promo tiles and the banner cards are `<a><img></a>`, unlike the
   product rails elsewhere on the site where the image sits inside a card.
   That is the shape iOS Safari treats as draggable content: a swipe that
   starts on the image can be taken over by the system drag / long-press
   callout instead of reaching Owl, and when WebKit claims the gesture it
   fires `touchcancel` — which Owl binds straight to `onDragEnd`, so the swipe
   dies halfway with the stage parked between two slides.

   Turning the native affordances off on the tile and its image leaves the
   whole gesture to Owl. `user-select` is only restated for older WebKit,
   which needs the prefix; Owl already sets the unprefixed form on
   `.owl-drag .owl-item`. Tapping still works — this suppresses dragging and
   the long-press menu, not the click. */
/*.offers-page .owl-item a,*/
.offers-page .owl-item img {
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.offers-page .off-promo-carousel .owl-nav button.owl-prev,
.offers-page .off-promo-carousel .owl-nav button.owl-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: var(--off-nav-size);
  height: var(--off-nav-size);
  border-radius: 50%;
  background-color: #fff;
  border: 1px solid var(--off-nav-line);
  color: var(--off-nav-ico);
  box-shadow: 0 4px 14px rgba(16, 24, 40, 0.16);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
}

/* Straddle the outer card edges, sitting on the sand. Kept shallow so the
   circle clears the band padding at every width — at -17px the next arrow ran
   past the container edge and got clipped on wide screens. Each bump to
   --off-nav-size moves this by half the growth, so the circle keeps its centre:
   -8px at 34px, -11px now the design's 40px applies. */
.offers-page .off-promo-carousel .owl-nav button.owl-prev {
  left: -11px;
}

.offers-page .off-promo-carousel .owl-nav button.owl-next {
  right: -11px;
}

/* The promo strip used to force its nav visible unconditionally, on the
   assumption that it always loops. It does not: offers.js decides `loop` from
   the tile count, so an under-filled strip (a section publishing four banners)
   is a non-looping rail — and the override then left two arrows on screen that
   could not move anything. It now carries the same `.off-rail-loops` marker
   the product rails use (offers.js :: keepNavWhileLooping), so the generic
   rule further down covers it and the arrows disappear exactly when they stop
   being able to do anything. */


/* The same trap on the product rails, reached the moment they went six-up: a
   rail holding exactly six cards has nothing "extra" to scroll by Owl's
   reckoning, so it disables the nav — while `loop` survives (Owl only drops
   loop below the visible count) and autoplay keeps rotating the track. The
   rail moves on its own but cannot be moved by hand.

   Unlike the promo strip above, this cannot be a blanket override: a rail can
   legitimately hold fewer cards than the track shows — Stationery has three —
   and there Owl really does turn looping off, so arrows would be dead. So
   offers.js marks only the rails that genuinely loop, by testing for clone
   elements, and the override hangs off that marker.

   It has to live in CSS rather than in the JS that sets the marker, because
   Owl redraws the nav and re-adds `disabled` after every slide: a class the
   JS strips is back by the first click, while this rule outranks Owl's own
   `.owl-nav.disabled { display: none }` for as long as the marker is set. */
.offers-page .owl-carousel.off-rail-loops .owl-nav.disabled {
  display: block;
}

/* --------------------------------------------------------------------------
   6/12. Wide promotional strips
   -------------------------------------------------------------------------- */
.offers-page .off-strip {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border-radius: var(--off-radius-lg);
  overflow: hidden;
  min-height: 190px;
  padding-inline: 20px;
  text-decoration: none;
  text-align: center;
}

.offers-page .off-strip-purple {
  background: linear-gradient(100deg, #56368a 0%, var(--off-purple) 100%);
}

.offers-page .off-strip-orange {
  background: linear-gradient(100deg, #f0a13f 0%, var(--off-orange) 100%);
}

.offers-page .off-strip-img {
  flex: 0 0 auto;
  max-width: 24%;
  height: auto;
  align-self: flex-end;
}

.offers-page .off-strip-copy {
  flex: 1 1 auto;
  display: block;
  color: #fff;
  padding-block: 24px;
}

.offers-page .off-strip-title {
  display: block;
  font-size: 30px;
  font-weight: 700;
  line-height: 1.15;
  text-transform: uppercase;
  margin-bottom: 8px;
}

.offers-page .off-strip-sub {
  display: block;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.9);
}

/* --------------------------------------------------------------------------
   8/10. Banner tiles
   -------------------------------------------------------------------------- */
.offers-page .off-banner-tile {
  position: relative;
  display: block;
  height: 100%;
  min-height: 200px;
  border-radius: var(--off-radius);
  overflow: hidden;
  text-decoration: none;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;
}

.offers-page .off-banner-tile:hover,
.offers-page .off-banner-tile:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 12px 28px rgba(16, 24, 40, 0.12);
}

.offers-page .off-banner-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.offers-page .off-banner-copy {
  position: absolute;
  inset: auto 0 0 0;
  display: block;
  padding: 18px 20px;
  background: linear-gradient(
    180deg,
    rgba(9, 17, 28, 0) 0%,
    rgba(9, 17, 28, 0.82) 68%
  );
  color: #fff;
}

.offers-page .off-banner-title {
  display: block;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.25;
  margin-bottom: 10px;
}

.offers-page .off-banner-link {
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
}

.offers-page .off-banner-btn {
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: #2a1c0d;
  background-color: var(--off-gold);
  border-radius: 999px;
  padding: 8px 18px;
}
.offers-page .last_minute_image {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 0;
  object-fit: cover;
  object-position: right center;
  height: 100%;
  width: 100%;
}

/* --------------------------------------------------------------------------
   Responsive — mobile first in intent, expressed as max-width steps to match
   the rest of the site's stylesheet.
   -------------------------------------------------------------------------- */
@media (max-width: 1199.98px) {
  .offers-page .off-hero-title {
    font-size: 32px;
  }
  .offers-page .off-hero-copy {
    padding-left: 34px;
    width: 39%;
  }
  .offers-page .off-brands-title {
    font-size: 28px;
  }
  .offers-page .off-brands-banner {
    padding-left: 5%;
  }
  .offers-page .off-brand-name {
    font-size: 16px;
  }
  .offers-page .off-brand-badge {
    font-size: 13px;
    left: 12px;
    bottom: 16px;
    padding: 8px 10px;
        line-height: 1;
  }
  .offers-page .off-strip-title {
    font-size: 24px;
  }
}

@media (max-width: 991.98px) {
  .offers-page .off-brands-grid {
    --bs-gutter-x: 18px;
    --bs-gutter-y: 15px;
}
  .offers-page .off-hero-inner {
    min-height: 260px;
  }
  .offers-page .off-hero-copy {
    width: 46%;
  }
  .offers-page .off-hero-title {
    font-size: 27px;
  }
  /* The artwork crops toward its right below lg, so the brown ground the copy
     sits on is no longer guaranteed — lay a scrim under the text. */
  .offers-page .off-hero-img {
    object-position: right center;
  }
  .offers-page .off-brands-banner {
    min-height: 0;
    padding: 34px 24px;
  }
  /* The copy takes the full width here, so the wash has to carry all the way
     across rather than fading out at 70%. */
  .offers-page .off-brands-banner::after {
    background: linear-gradient(
      90deg,
      rgba(14, 124, 136, 0.96) 0%,
      rgba(14, 124, 136, 0.86) 55%,
      rgba(14, 124, 136, 0.55) 100%
    );
  }
  .offers-page .off-brands-copy {
    max-width: 100%;
  }
  /* Stacked under the grid below lg, where a 491x860 portrait block would run
     most of a phone screen, so the banner is re-cut wide. The `height: auto`
     and `min-height: 0` this rule used to carry are gone with the base rule's
     `height: 100%` — the ratio is now the only thing setting its height.

     Note this crops: the artwork is portrait and this box is landscape, so
     `cover` takes the top and bottom off. That was the intent before the
     artwork was pinned to 491x860; if the whole banner has to be readable on
     a phone too, the answer is a separate wide upload, not a fit mode. */
  /*.offers-page .off-tall-promo {*/
  /*  aspect-ratio: 49 / 43;*/
  /*}*/
  .offers-page .off-tall-copy {
    padding-top: 44px;
  }
  .offers-page .off-cat-title {
    font-size: 24px;
  }
  .offers-page .off-strip-title {
    font-size: 20px;
  }
}

@media (max-width: 767.98px) {
  .offers-page .off-section {
    padding-block: 24px;
  }
  /* Below md the diagonal has no room to read — the panel becomes the whole
     block, with the photograph stacked above it. */
  .offers-page .off-hero-inner {
    display: block;
    min-height: 0;
    background-color: var(--off-hero-brown);
    border-radius: 12px 12px 0 0;
    overflow: hidden;
  }
  .offers-page .off-hero-media {
    position: static;
    height: 210px;
  }
  .offers-page .off-hero-copy {
    width: 100%;
    max-width: 100%;
    padding: 24px 22px 28px;
  }
  .offers-page .off-hero-title {
    font-size: 24px;
  }
  .offers-page .off-hero-text {
    font-size: 13.5px;
    /* The desktop rule pins the design's 26px line box; at 13.5px that is
       nearly double-spaced, so the ratio takes over below sm. */
    line-height: 1.6;
  }
  .offers-page .off-promo-band {
    padding: 22px 16px 26px;
  }
  .offers-page .off-section-title {
    font-size: 18px;
  }
  /* Strip artwork would crowd the copy at this width. */
  .offers-page .off-strip-img {
    display: none;
  }
  .offers-page .off-strip {
    min-height: 0;
    text-align: left;
    padding-inline: 22px;
  }
  .offers-page .off-strip-title {
    font-size: 19px;
  }
  .offers-page .off-banner-tile {
    min-height: 170px;
  }
  .offers-page .off-product-carousel .owl-nav button.owl-prev,
  .offers-page .off-promo-carousel .owl-nav button.owl-prev {
    left: -8px;
  }
  .offers-page .off-product-carousel .owl-nav button.owl-next,
  .offers-page .off-promo-carousel .owl-nav button.owl-next {
    right: -8px;
  }
}

@media (max-width: 575.98px) {
  /* 25px of panel padding on top of the container's own 30px leaves a phone
     barely any room for a card, so the panel gives most of it back. */
  .offers-page .off-cat-panel {
    padding: 16px;
  }
  .offers-page .off-select {
    flex: 1 1 auto;
  }
  .offers-page .off-brands-title {
    font-size: 21px;
  }
  .offers-page .off-brand-name {
    font-size: 14px;
    padding: 13px 13px 0;
        line-height: 1;
  }
  .offers-page .off-brands-panel {
    padding: 18px 14px 24px;
  }
  .offers-page .off-brands-banner {
    padding: 26px 18px;
  }
  .offers-page .off-brands-eyebrow {
    font-size: 13px;
    letter-spacing: 1.2px;
  }
  .offers-page .off-brands-sub {
    font-size: 14px;
  }
  .offers-page .off-cat-title {
    font-size: 16px;
  }
  .offers-page .off-cat-viewall {
        font-size: 13px;
        padding: 7px 14px;
        min-height: auto;
    }
.offers-page .off-cat-gap {
    margin-bottom: 19px;
}
  .offers-page .off-cat-label {
    font-size: 13px;
  }
  .offers-page .off-select {
    font-size: 14px;
  }
  /* The banner headline would otherwise run past a 375px viewport. */
  .offers-page .off-tall-kicker {
    font-size: 28px;
  }
  .offers-page .off-tall-pct {
    font-size: 46px;
  }
  .offers-page .off-tall-upto {
    font-size: 15px;
  }
  .offers-page .off-tall-copy {
    padding: 30px 16px 26px;
  }
  .offers-page .off-tall-pill {
    font-size: 12px;
    padding: 6px 12px;
  }
  .offers-page .off-promo-head {
    font-size: 19px;
  }
  .offers-page .off-promo-copy {
    padding: 16px 14px 20px;
  }
  .offers-page .off-select {
    min-width: 0;
  }
  .offers-page .off-promo-pill{font-size: 12px; padding: 6px 12px}
  .offers-page .off-promo-carousel .owl-nav button.owl-prev, .offers-page .off-promo-carousel .owl-nav button.owl-next{
    height: 30px;
    width: 30px;
  }
}

/* ==========================================================================
   Section styles the offers page borrows from the redesigned home mock.
   They live here — scoped to .offers-page — instead of category_v2.css
   because the home redesign that owns them hasn't landed yet; when it does
   this block can move out wholesale and nothing on this page changes.
   The `--sc-*` tokens are already defined by category_v2.css (:root).
   ========================================================================== */

/* The design's pink band. Only a fallback in practice: offers.xml renders
   `section['background']` inline from the offer.section record, which always
   wins over this. Kept in step with offer_section.py's BACKGROUND_HEX['pink']
   so a band that loses its record colour still lands on the design's tint. */
.offers-page {
  --sc-fav-bg: #ffeded;
}

/* ---- Tinted panels holding a heading + a product rail ---------------------- */
.offers-page .sc-fav-band,
.offers-page .sc-trending-band,
.offers-page .bg-box_deal {
  border-radius: 12px;
  display: flex;
  padding: 15px;
  flex-direction: column;
  align-items: flex-end;
  gap: 14px;
  align-self: stretch;
}

.offers-page .sc-fav-band {
  background-color: var(--sc-fav-bg);
}

/* Heading + View all (node 1472-9385). The design's row is 43px tall with a
   12px gap and a 15px inset of its own — which sits *inside* the band's own
   15px padding, so the heading starts 30px from the band edge while the
   carousel below it starts at 25 (its own 10px inset). The two are genuinely
   different in the design, so the inset belongs here rather than being folded
   into the band's padding.

   `min-height` rather than the design's fixed 43: the height is the button's
   in practice, and pinning it would let a wrapped heading overflow the row
   instead of growing it. */
.offers-page .sc-band-head {
  gap: 12px;
  min-height: 43px;
  padding-inline: 15px;
}

/* The band heading, per node 1472-9395: 24/700 with a 43.2px line box (the
   row's full height, which is what centres it against the button) and the
   design's own -0.72px tracking. Restated because the shared .sc-section-title
   in home_v2.css / category_v2.css is 20/600 at -0.2px — the page-level
   heading size, a step below this one. #1B1C1C rather than --off-ink: the
   design's text black, half a shade off the #1F2937 the body copy takes. */
.offers-page .sc-fav-band .sc-section-title,
.offers-page .sc-trending-band .sc-section-title,
.offers-page .bg-box_deal .sc-section-title {
  font-size: 24px;
  font-weight: 700;
  line-height: 43.2px;
  letter-spacing: -0.72px;
  color: #1b1c1c;
}

/* The banner row's heading, per node 1472-10708: 25/700 with the same 43.2px
   line box and -0.72px tracking the rail headings take, in the design's text
   black. Without this the row falls back to the shared .sc-section-title
   (20/600 at -0.2px) — the rule above only reaches headings sitting inside a
   tinted band, and a banner row has none.

   25px, not the rails' 24px. The two nodes really do differ by a pixel; the
   figure is copied rather than harmonised, since nothing here can tell whether
   that is intent or drift in the file.

   The 18px margin the shared rule sets goes to the design's 10px gap between
   the heading and the artwork below it (node 1472-10701). */
.offers-page .off-row-title {
  font-size: 25px;
  font-weight: 700;
  line-height: 43.2px;
  letter-spacing: -0.72px;
  color: #1b1c1c;
  margin-bottom: 10px;
}

/* The band's View all, per node 1472-9396 — the same control the category
   grid's already draws (.off-cat-viewall above), so the figures are the same
   ones: 43px tall, 8px radius, 8/24 padding, an 8px gap to the chevron, and
   #006671 on both the fill and the 1px border.

   Written against `.btn.btn-primary` because the rail template reaches for
   Bootstrap's button rather than .off-viewall-btn, and Bootstrap's own
   .btn-primary carries a fill, a border colour and a 6px radius that have to
   be beaten. An inline `view_all_style` from the section record still wins
   over all of this, which is the point of that field. */
.offers-page .sc-band-head .btn.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 43px;
  padding: 8px 24px;
  font-size: 15px;
  font-weight: 600;
  color: #fff;
  background-color: var(--off-viewall-bg);
  border: 1px solid var(--off-viewall-bg);
  border-radius: 8px;
  white-space: nowrap;
}

.offers-page .sc-band-head .btn.btn-primary:hover,
.offers-page .sc-band-head .btn.btn-primary:focus-visible {
  color: #fff;
  background-color: var(--off-viewall-bg-dark);
  border-color: var(--off-viewall-bg-dark);
}

/* The chevron's own gap is the flex `gap` above, so Bootstrap's utility
   margin on it would double the spacing. */
.offers-page .sc-band-head .btn.btn-primary .bi {
  margin-left: 0 !important;
}

/* The rail's 10px inset (node 1472-9407). Padding on the Owl root rather than
   a margin so the stage narrows with it — jQuery's `width()` reads the
   content box, which is what Owl measures each item against. The nav arrows
   are absolutely positioned and resolve against the padding box, so their
   -18px offsets are unaffected. */
.offers-page .sc-fav-band .sc-favorites-carousel,
.offers-page .sc-trending-band .sc-trending-carousel,
.offers-page .bg-box_deal .sc-topdeals-carousel {
  padding-inline: 10px;
}

/* The rail card's frame, per node 1472-9462: a gold hairline at 48% and the
   design's soft 0 1px 2px shadow, against the #BCC9CB / 0 4px 4px the grid
   card takes below. Scoped to the bands on purpose — home_v2.css swapped this
   same gold tint for a neutral #E5E7EB hairline across every listing card,
   and that swap has to stand everywhere except here, where the design asks
   for the tint against the band's colour. */
.offers-page .sc-fav-band .deal-card,
.offers-page .sc-trending-band .deal-card,
.offers-page .bg-box_deal .deal-card {
  border-color: rgba(250, 204, 21, 0.48);
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}

.offers-page .sc-trending-band {
  background-color: #fff6e5;
}

.offers-page .bg-box_deal {
  background: #e4fdff;
}

/* Cards keep a white ground against the tinted panel. */
.offers-page .sc-fav-band .deal-card,
.offers-page .sc-trending-band .deal-card,
.offers-page .bg-box_deal .deal-card {
  background-color: #fff;
}

/* White, not the design's #F6F6F6 grid card. Every product photo carries a
   white background of its own, so a grey card turned each image into a pasted
   white patch — the separation the grey was meant to remove, just moved from
   image-box-vs-body up to photo-vs-card. Matching the card to the photos is
   what actually makes the surface read as one, and it puts the grid card in
   step with the rail card (node 1472-9408), which is white on both its face
   and its body container. Set on the card rather than per container so it
   reaches the body without needing a body wrapper. */
.offers-page #offCatGrid .deal-card {
  background-color: #fff;
}

/* The design's body is a 5px-gap stack (node 1472-12072). Live spaces it with
   Bootstrap margins instead — `mb-3` on the meta row, an 8px margin under the
   title — which is three times the design's step and is most of why the
   rendered card runs taller than its 422px. The margins are overridden rather
   than swapped for a flex `gap`, because `.button_block` is absolutely
   positioned and would drop out of a flex flow. */
.offers-page #offCatGrid .sc-deal-meta {
  margin-bottom: 5px;
}

/*.offers-page #offCatGrid .deal-card h6 {*/
/*  margin-bottom: 5px;*/
/*}*/

/* The delivery pill and the rating stay on one line, which is what keeps the
   title, price and discount chip below them at the same height in every card
   of a row.

   This used to set `flex-wrap: wrap` and that was the whole bug: category_v2
   .css:716 pins `.sc-deal-meta` to `nowrap` precisely so the rating cannot
   drop under the delivery pill — the wrap QA flagged on narrow desktop cards
   — and this rule handed that back for the offers page alone. A card whose
   pill reads "DELIVERY WITHIN 1 HOUR" wrapped where its neighbour reading
   "WITHIN 1 HOUR" did not, and everything below it sat a line lower.

   Nothing extra is needed to make one line work: category_v2 already gives
   the pill `min-width: 0` + an ellipsis and fixes the rating at
   `flex-shrink: 0`, so the pill is what gives up space on a narrow card. */

/* The design's image container: 306.75 x 213 (a 1.44:1 box, not the square
   home_v2.css gives it), #F6F6F6 ground, 1px rule along the bottom, and full
   width of the card interior.

   Full-bleed needs the negative margin because the markup has no body
   wrapper — `.deal_div` and the text blocks are all direct children of
   `.deal-card`, so the card's own padding is what insets the image. Pulling
   it back by exactly that padding lands the image on the card edge; the
   card's `overflow: hidden` (main.css) clips it to the rounded corners. The
   padding is a custom property so the mobile block can change one value and
   keep the bleed, button and body inset in step. */
/*.offers-page .deal_div {*/
/*  height: auto;*/
/*  margin: calc(var(--off-card-pad, 16px) * -1) calc(var(--off-card-pad, 16px) * -1)*/
/*    0;*/
/*  aspect-ratio: 306.75 / 213;*/
  /* White, matching the card face and the photos' own background: with the
     card no longer grey, a tinted box would be the separation again. The
     design's 1px rule along the bottom goes with it — on one continuous white
     surface that line is the only thing left dividing the photo from the copy
     below it. The card's own border and shadow still bound the card. */
/*  background-color: #fff;*/
/*}*/

/* The rails draw a taller image box than the grid does. Both come from the
   design, and they genuinely differ: the grid card (node 1472-12062) is
   306.75x213, the rail card (node 1472-9408) is 280.5x240. The rule above is
   the grid's, so the rails restate their own — otherwise a rail photograph is
   cropped to a shape the design never gives it. */
/*.offers-page .sc-favorites-carousel .deal_div,*/
/*.offers-page .sc-topdeals-carousel .deal_div,*/
/*.offers-page .sc-trending-carousel .deal_div {*/
/*  aspect-ratio: 280.5 / 240;*/
/*}*/

/* The anchor wrapping the image is inline by default; making it a block keeps
   the negative margins above predictable and drops the inline line-box gap
   that would otherwise sit under the image. This also catches the anchor
   around the title, where it changes nothing — that one already wraps a
   block-level h6. */
/*.offers-page .deal-card > a {*/
/*  display: block;*/
/*}*/

/* ---- Promo banner cards ---------------------------------------------------- */
.offers-page .sc-promo-card {
  position: relative;
  display: block;
  height: 100%;
  /* home_v2.css styles .sc-promo-card unscoped and pins it to a 1:1 box for
     the homepage's square tiles. That file loads on every page since /offers
     moved to the v2 layout, and a square box crops these wide banners down
     their middle — so the ratio is handed back to the artwork here. */
  aspect-ratio: auto;
  border-radius: var(--sc-radius);
  overflow: hidden;
  text-decoration: none;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;
}

.offers-page .sc-promo-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---- Rail arrows ----------------------------------------------------------- */
/* One rule for every rail on the page rather than one per carousel class —
   the arrows are identical and the page has four of them.

   The promo and product carousels are excluded: they carry their own vertical
   placement and edge offsets further up this file, and both selectors weigh
   the same (0,4,1), so without the :not() this rule would win on source order
   alone and silently restyle them to top 42% / -18px. The circle itself is now
   shared through --off-nav-size and friends, so all three match the design. */
.offers-page .owl-carousel:not(.off-promo-carousel):not(.off-product-carousel) .owl-nav button.owl-prev,
.offers-page .owl-carousel:not(.off-promo-carousel):not(.off-product-carousel) .owl-nav button.owl-next {
  position: absolute;
  top: 42%;
  transform: translateY(-50%);
  width: var(--off-nav-size);
  height: var(--off-nav-size);
  border-radius: 50%;
  background-color: #fff;
  border: 1px solid var(--off-nav-line);
  color: var(--off-nav-ico);
  box-shadow: var(--sc-shadow-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  transition:
    background-color 0.15s ease,
    color 0.15s ease;
}

.offers-page .owl-carousel:not(.off-promo-carousel):not(.off-product-carousel) .owl-nav button.owl-prev {
  left: -18px;
}

.offers-page .owl-carousel:not(.off-promo-carousel):not(.off-product-carousel) .owl-nav button.owl-next {
  right: -18px;
}

.offers-page .owl-carousel:not(.off-promo-carousel):not(.off-product-carousel) .owl-nav button.owl-prev:hover,
.offers-page .owl-carousel:not(.off-promo-carousel):not(.off-product-carousel) .owl-nav button.owl-next:hover {
  background-color: var(--sc-teal);
  border-color: var(--sc-teal);
  color: #fff;
}

/* The favourites band is the one rail whose cards fill the panel top to
   bottom, so the 42% above lands the arrows high on it. The design centres
   them there instead. */
.offers-page .sc-fav-band .sc-favorites-carousel .owl-nav button.owl-prev,
.offers-page .sc-fav-band .sc-favorites-carousel .owl-nav button.owl-next {
  top: 50%;
}

/* The nav chevrons are inline SVG (see offers.js). They inherit `color`
   through `stroke="currentColor"`, so every existing colour and hover rule
   above still applies; this only pins the box, since font-size does not size
   a replaced element. */
.offers-page .owl-nav button .off-nav-ico {
  width: 7.4px;
  height: 12px;
  display: block;
}

/* ---- FAQ card -------------------------------------------------------------- */
.offers-page .sc-faq-card {
  background-color: #fff;
  border: 1px solid var(--sc-line);
  border-radius: var(--off-radius-lg);
  padding: 28px;
}

@media (max-width: 991.98px) {
  .offers-page .sc-fav-band .sc-section-title {
    font-size: 19px;
    margin-bottom: 14px;
    /* The desktop rule pins the design's 43.2px line box, which is the head
       row's own height — left alone it would hold a 19px heading in a 43px
       line and push the band's rhythm out below lg. */
    line-height: 1.35;
  }
  .offers-page .owl-carousel:not(.off-promo-carousel):not(.off-product-carousel) .owl-nav button.owl-prev {
    left: -10px;
  }
  .offers-page .owl-carousel:not(.off-promo-carousel):not(.off-product-carousel) .owl-nav button.owl-next {
    right: -10px;
  }
}

@media (max-width: 767.98px) {
  .offers-page .sc-trending-band .sc-section {
    padding-block: 24px;
  }
  /* Stacked full width — let each banner keep its own proportions. */
  .offers-page .sc-promo-card {
    min-height: 0;
    height: auto;
  }
  .offers-page .sc-promo-card-wide {
    aspect-ratio: auto;
  }
  .offers-page .sc-promo-card img {
    height: auto;
  }
}

/* Narrow phones: section headings step down once more, as in the design. */
@media (max-width: 400px) {
  .offers-page .sc-section-title {
    font-size: 17px;
  }
}

/* --------------------------------------------------------------------------
   Product card — the pieces offer-badge.css takes over
   The redesigned card (border, delivery pill, wishlist button, teal Add to
   Cart) already comes from category_v2.css, which carries the design's global
   overrides. Two things it cannot win on this page:
   -------------------------------------------------------------------------- */

/* 1. The discount chip. offer-badge.css pins `.discount-badge` to the top-left
   of the image as a pink ticket and marks every declaration !important, so it
   beats the design's rule no matter the load order. The redesign wants it
   inline in the price row instead — dark teal with gold text. Same override
   the category grid already runs under #scProductGridWrap, scoped here to
   `.offers-page` so every other listing keeps the pink ticket. */
/* The rails carry `sc-favorites-carousel`, and home_v2.css:4038 styles
   `.sc-favorites-carousel .deal-card span.discount-badge` at 10px / 3px 6px.
   That selector is (0,3,1) against this rule's (0,2,1) and both are
   !important, so it won inside every rail while the category grid — not a
   carousel — kept this rule. One chip, two sizes, with no difference in the
   markup or in this file. Naming the rails lifts these to (0,4,1). */

/* Both halves inherit the parent's line-height rather than collapsing it to
   1: the chip's 26px height is 4 + 18 + 4, and an inline child with its own
   line-height sets the line box, not the parent. */
/*.offers-page span.discount-badge .percent {*/
/*  display: inline !important;*/
/*  color: inherit !important;*/
/*  font-size: inherit !important;*/
/*  font-weight: 600 !important;*/
/*  line-height: inherit !important;*/
/*  letter-spacing: normal !important;*/
/*  margin: 0 !important;*/
/*  padding: 0 !important;*/
/*  text-transform: none !important;*/
/*}*/

/* 600, matching `.percent`: the design draws "32% OFF" as one text node at
   SemiBold, so the two halves cannot differ in weight. */
/*.offers-page span.discount-badge .off {*/
/*  display: inline !important;*/
/*  color: inherit !important;*/
/*  font-size: inherit !important;*/
/*  font-weight: 600 !important;*/
/*  line-height: inherit !important;*/
/*  letter-spacing: normal !important;*/
/*  margin: 0 !important;*/
/*  padding: 0 !important;*/
/*  opacity: 1 !important;*/
/*  text-transform: uppercase !important;*/
/*}*/

/* 2. The FLASH ribbon. It sits at the card's top-left corner, exactly where
   offer-badge.css was stacking the pink ticket at z-index 10 — so it rendered
   underneath. Freed by the rule above; the z-index keeps it clear of the
   product image regardless. */
.offers-page span.corner-ribbon {
  z-index: 2;
  /* 10px/15px Bold, per node 1472-12153. category_v2.css draws it at 12px/500;
     the radius (0 0 12px 0) and padding (4px 12px) there already match the
     design's Background frame, so only the type changes. */
  font-size: 10px;
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   Card typography, from the design's Card 11 text nodes. Every one of these
   overrides a rule in main.css written for the older card, so each states
   what it is replacing rather than only what it sets.

   None of them name a family: the page's Be Vietnam Pro reaches them by
   inheritance — except where main.css pins "Public Sans" on the prices, which
   is why those two say `inherit` explicitly.
   -------------------------------------------------------------------------- */

/* Product name — 14px/21px Medium in #1B1C1C (node 1472-12171). main.css
   sizes this from `--prod-title` (16px, dropping to 14px under 1400px) with a
   1.5 line-height, so it was both larger and looser than the design at the
   widths that matter. The three-line clamp and its reserved height are set
   further down and are untouched. */
/*.offers-page .deal-card h6 {*/
/*  font-size: 14px;*/
/*  font-weight: 500;*/
/*  line-height: 21px;*/
/*  letter-spacing: 0;*/
/*  color: #1b1c1c;*/
/*}*/

/* Current price — 18px/18px Bold in pure black (node 1472-12172). main.css
   gives it `--para-size` (14px, 13px under 1400px) at weight 600 in Public
   Sans, which left it barely distinguishable from the struck-through price
   beside it. */
/*.offers-page .new_price {*/
/*  font-family: inherit;*/
/*  font-size: 18px;*/
/*  font-weight: 700;*/
/*  line-height: 18px;*/
/*  color: #000;*/
/*}*/

/* Struck-through price — 12px/18px Regular in #363636 (node 1472-12172).
   main.css sets 22px at weight 600 with `opacity: .4`; the design instead
   gets its recessive look from the smaller size and the grey, so the opacity
   has to be cancelled or the colour lands lighter than #363636. */
/*.offers-page .price-old {*/
/*  font-family: inherit;*/
/*  font-size: 12px;*/
/*  font-weight: 400;*/
/*  line-height: 18px;*/
/*  color: #363636;*/
/*  opacity: 1;*/
/*}*/

/* Add to Cart — Fill x 44 tall, 8px radius, a 2px #009DAB border on a #009DAB
   ground, with 16px/24px Bold white text (nodes 1472-12181 and 1472-12184).
   The height is the sum of its parts: 8 + 24 + 8 + two 2px borders = 44, so
   the padding, the line-height and the border width hold it together.
   category_v2.css gives the button a 4px radius and a 1px border; main.css
   and custom.css fight over its padding, which the min-width:768px rule
   below settles. */
/*.offers-page .deal-card .button_block .btn {*/
/*  border-radius: 8px;*/
/*  border-width: 2px;*/
/*  font-size: 16px;*/
/*  font-weight: 700;*/
/*  line-height: 24px;*/
/*  text-align: center;*/
  /* The label stays on one line, so the button is always the design's 44px.
     Left to wrap it was landing on both sides of the same boundary inside one
     rail: Owl hands each item a fractional width, the browser rounds those
     differently by sub-pixel position, and at a zoom where "Add to Cart" fits
     its button with nothing to spare, a 1px difference is the whole margin.
     The cards that lost the toss broke to two lines and stood 68px against
     their neighbours' 44. Bootstrap 5 dropped the `white-space: nowrap` its
     4.x `.btn` carried, which is why this has to be said again here. */
/*  white-space: nowrap;*/
/*}*/

/* The design's "Card 1" frame: 16px body padding, #BCC9CB hairline, and a
   0 4px 4px drop shadow at 10% black — main.css and home_v2.css between them
   give it 20px padding, an #e5e7eb border and a much tighter 0 1px 2px
   shadow. Height stays content-driven, as the design's Hug (422px) is.

   padding-bottom is the exception to the 16px: the Add to Cart block is
   absolutely positioned, so the card has to reserve room for it below the
   copy rather than flow around it. */
.offers-page .deal-card {
  --off-card-pad: 16px;
  --off-card-line: #bcc9cb;
  padding: var(--off-card-pad) var(--off-card-pad) 80px;
  border-color: var(--off-card-line);
  box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.1);
}

/* main.css pins this to the 20px padding it sets; it has to track ours or the
   button stops lining up with the copy above it. */
.offers-page .button_block {
  left: var(--off-card-pad, 16px);
  right: var(--off-card-pad, 16px);
  bottom: var(--off-card-pad, 16px);
}

@media (max-width: 767.98px) {
  /*.offers-page .sc-topdeals-carousel .deal-card span.discount-badge,*/
  /*.offers-page .sc-trending-carousel .deal-card span.discount-badge,*/
  /*.offers-page .sc-favorites-carousel .deal-card span.discount-badge,*/
  /*.offers-page span.discount-badge {*/
  /*  font-size: 9px !important;*/
  /*  line-height: 1 !important;*/
  /*  padding: 3px 5px !important;*/
  /*  gap: 3px !important;*/
  /*  !* The desktop rule fixes the chip at the design's 100px. That width is*/
  /*     measured against 16px text; at 9px it would leave the chip mostly*/
  /*     empty and crowd a phone's price line, so it goes back to hugging. *!*/
  /*  width: auto !important;*/
  /*}*/
  /*!* One value drives the body inset, the image bleed and the button, so they*/
  /*   cannot drift apart. *!*/
  /*.offers-page .deal-card {*/
  /*  --off-card-pad: 10px;*/
  /*  padding: var(--off-card-pad) var(--off-card-pad) 60px;*/
  /*}*/
}

/* Add to Cart height. custom.css lands a blanket
   `.btn-outline-secondary{padding:5px}` late in the cascade, which flattens
   the button to roughly half the design's height, so the figure has to be
   restated here — for this page only; every other page keeps the 5px.

   8px, per node 1472-12181. The earlier 12px came from main.css's
   `.btn-outline-secondary` and was taken as the design's own, but the node
   measures the button at 44px: 8 top + a 24px line box + 8 bottom + two 2px
   borders. At 12px it stands 52px.

   Desktop-only so the ≤768px / ≤400px steps in category_v2.css still win. */
@media (min-width: 768px) {
  .offers-page .deal-card .button_block .btn.btn-outline-secondary {
    padding: 8px 0;
    /* The same 44px, stated as a floor. `nowrap` above is what keeps the
       label from growing the button; this is what keeps a card whose CTA
       renders shorter — a bare "Notify Me" with no icon — level with the
       "Add to Cart" beside it. */
    min-height: 44px;
  }
}

/* Equal-height cards.
   With real products the content length varies — a variant product shows
   "Select Options" and no price row, an unrated one drops the stars — and
   `.deal-card` sizes to its own content, so a row ends at four different
   heights. The column already stretches (a Bootstrap `.row` is
   `align-items: stretch`), so the card only needs to be told to fill it.
   Same fix `.data_section_product_listing` uses on the category grid.

   `height: stretch` is what this used to say, and it only ever worked in
   Chrome — Safari knows that keyword as `-webkit-fill-available` and throws
   the declaration away, leaving the cards at content height on every iPhone.
   Flex sizing says the same thing in a spelling every browser has. */
.offers-page .product_item_listing {
  display: flex;
  flex-direction: column;
  height: auto;
}

.offers-page .deal-card {
  height: auto;
  flex: 1 1 auto;
}

/* Reserve the title's *maximum* height rather than its typical one, so cards
   match across rows and not just within one. A Bootstrap row stretches each
   wrapped line on its own, so a row holding a three-line product name ends
   up taller than a row of two-line names however the cards inside it are
   sized. main.css clamps `.deal-card h6` to three lines, so pinning three
   lines here (1.5 line-height x 3) makes the title block a constant. */
/*.offers-page .deal-card h6 {*/
/*  min-height: 4.5em;*/
/*}*/

/* Reserve the price row too, so a card that has none — a variant product
   showing "Select Options" — still occupies the same height as its
   neighbours instead of relying on a taller card in the same row. */
.offers-page .off-price-row {
  min-height: 46px;
  /* The reserved height above keeps every card the same height, but a flex
     row defaults to `align-items: stretch` — so whatever shares the line with
     the prices (the discount chip) was being stretched to fill all 46px. The
     design's row has no reserved height, so its chip is always its natural
     size; centring here reproduces that without giving up the equal heights.
     Only shows on cards whose chip fits on the price line — once it wraps to
     its own line the chip sets that line's height and never stretches. */
  align-items: center;
  /* The break below supplies the space above the chip instead, so the row gap
     is not counted twice. `!important` because Bootstrap's `gap-2` utility on
     the row is itself `!important`, and the shorthand sets both axes. */
  row-gap: 0 !important;
}

/* The chip starts its own line, always — at every width and whatever the
   prices measure.

   Left to wrap on its own it was doing both: "QR 7.20 QR 8.00" fit beside the
   chip while "QR 13.50 QR 15.00" one column over did not, so the chip sat on
   the price line in one card and under it in its neighbour. The break cannot
   be "always inline" instead: the design's chip is a fixed 100px (node
   1472-12172) and the price pair plus that chip needs ~244px inside a card
   whose interior is 198px at 1600 — it has to break somewhere, so it breaks
   in the same place every time.

   The mechanism is a zero-height full-width flex item ordered between the
   prices and the chip. A pseudo-element on the row is the only place CSS can
   put one — `::after` is the last flex item by default, so `order` is what
   moves it in front of the chip. */
.offers-page .off-price-row::after {
  content: "";
  order: 1;
  flex: 0 0 100%;
  height: 0;
}

/*.offers-page .off-price-row .discount-badge {*/
/*  order: 2;*/
/*  !* What the row's own gap used to give it, now that row-gap is zero. *!*/
/*  margin-top: 8px;*/
/*}*/

@media (max-width: 767.98px) {
  /* category_v2.css clamps the title to two lines below md, so the reserved
     height has to come down with it or every card grows a blank line. */
  /*.offers-page .deal-card h6 {*/
  /*  min-height: 2.7em;*/
  /*}*/
  .offers-page .off-price-row {
    min-height: 38px;
  }
}


/* --------------------------------------------------------------------------
   Typeface
   Be Vietnam Pro, matching both the current Figma (every text node on the
   offers frames reads "Be Vietnam Pro") and the sitewide default set on
   2026-08-24 (main.css `body`, category_v2.css `.sc-page` / `.sc-shell`).

   This reverses an earlier pin back to Poppins. The reason recorded for that
   pin still holds and is worth knowing: Be Vietnam Pro is the wider face, and
   at the hero's 40px it tips that headline from two lines to three. Sizes are
   not the cause — the mockup and this file both say 40px — so if the hero
   needs to come back to two lines, the lever is its font-size or width, not
   the family.

   `.sc-shell` declares its own stack *inside* `.offers-page`, so it stays
   named here — inheritance takes the nearest ancestor that declares a family,
   not the most specific one. --------------------------------------------- */
.offers-page,
.offers-page .sc-shell {
  font-family: "Be Vietnam Pro", "Public Sans", system-ui, -apple-system,
    "Segoe UI", sans-serif;
}
