/* ==========================================================================
   Offers page — page-scoped styles
   Figma: "offer page_Updated Final", node 4795:2976 (1920 artboard,
   1196–1280px content; earlier 4290:3753) and "Offer page mobile version",
   node 4323:2567 (390 artboard, section 12).

   Values are read off the Figma nodes, not eyeballed. Type uses
   `clamp(min, Npx/19.2 vw, max)` with `max` the literal design px, so the
   page is 1:1 with the artboard at 1920 and scales down from there — the
   same scheme as assets/text-ads/css/style.css.

   SCOPING: every selector sits under .offers-body. The shared header and
   footer (includes/) are used verbatim and nothing here reaches them.

   CONTENT IS DATA. Every string, image and icon on the page comes from the
   promotional-pages API (includes/offers-data.php), so nothing here may
   depend on a heading's exact length — no fixed line breaks, no widths that
   only fit the Halloween copy. Text wraps inside max-widths instead.

   THIS SHEET IS THE DEFAULT LOOK. The API's style_data can override fonts,
   sizes, colours, radii and background sizing per element; offers.php
   prints those overrides in a <style> AFTER this file, with selectors one
   level deeper than these, so they win. With style_data empty (as it
   ships), this sheet — the Figma design — is the whole story.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  --of-page:        #181719;
  --of-band:        #1E1E1E;
  --of-card:        #26272A;
  --of-voucher:     #211E25;
  --of-code-bg:     #0E0E0E;
  --of-violet:      #7E37BB;
  --of-violet-glow: #B661FF;
  --of-violet-deep: #500492;
  --of-lilac:       #DFB7FF;
  --of-lilac-soft:  #BC9BD9;
  --of-lilac-label: #E0B6FF;
  --of-ink:         #E3E2E8;
  --of-body:        #D9D9D9;
  --of-hairline:    rgba(88, 66, 53, 0.2);

  --of-f-display: 'Creepster', cursive;
  --of-f-heading: 'Plus Jakarta Sans', sans-serif;
  --of-f-body:    'Be Vietnam Pro', sans-serif;
  --of-f-ui:      'Montserrat', sans-serif;
  --of-f-strong:  'Inter', sans-serif;

  --of-fs-headline: clamp(64px, 9.063vw, 174px);
  --of-fs-eyebrow:  clamp(30px, 3.75vw,  72px);
  --of-fs-48:       clamp(30px, 2.5vw,   48px);
  --of-fs-44:       clamp(28px, 2.292vw, 44px);
  --of-fs-36:       clamp(26px, 1.875vw, 36px);
  --of-fs-28:       clamp(18px, 1.458vw, 28px);
  --of-fs-26:       clamp(18px, 1.354vw, 26px);
  --of-fs-24:       clamp(17px, 1.25vw,  24px);
  --of-fs-22:       clamp(19px, 1.146vw, 22px);
  --of-fs-20:       clamp(16px, 1.042vw, 20px);
  --of-fs-18:       clamp(15px, 0.938vw, 18px);

  --of-container: 1280px;
  --of-gutter:    24px;
}

/* --------------------------------------------------------------------------
   2. Page shell
   -------------------------------------------------------------------------- */
.offers-body {
  background: var(--of-page);
}

.offers-body .of-page {
  color: var(--of-body);
  font-family: var(--of-f-body);
  overflow: hidden;
  /* CRM copy can hold a word longer than a phone is wide (a long code, a
     URL): break it rather than let it push the layout sideways. */
  overflow-wrap: anywhere;
}

/* The sitewide sheet gives p/h* their own margins, colour and font, which
   beat inheritance — "20% Extra Credit" rendered near-black on the dark card.
   Reset them to inherit. `:where()` keeps this at (0,1,0): above the
   sitewide element rules, below every class rule in this file, so a section's
   own margin or colour still wins. */
.offers-body :where(.of-page h1, .of-page h2, .of-page h3, .of-page p) {
  margin: 0;
  color: inherit;
  font-family: inherit;
}

.offers-body .of-container {
  position: relative;
  max-width: calc(var(--of-container) + var(--of-gutter) * 2);
  margin: 0 auto;
  padding: 0 var(--of-gutter);
}

/* --------------------------------------------------------------------------
   3. Buttons — one violet pill, three uses (Figma "Component 177" sets
      3872:897, 3888:947, 3888:985)

   Each Figma button is TWO layers: the pill, and a "Link" ring the same size
   behind it. The ring is ::before here, coloured per use through
   --of-btn-ring.

   HOVER is the sets' Variant3, swapped in with NO transition — Figma's
   reaction is an instant change, so there is deliberately no `transition`
   on any of it: dark #2E0055 fill, a 1px #8A38F5 stroke, a #8A38F5 glow
   (r16), the ring gone, and the label one step heavier and larger
   (Montserrat Medium 24 -> SemiBold 26, icon 24 -> 26).
   -------------------------------------------------------------------------- */
.offers-body .of-btn {
  --of-btn-ring: transparent;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 30px;
  min-height: 65px;
  padding: 15px 26px;
  border: 0;
  border-radius: 14px;
  background: var(--of-violet);
  color: #fff;
  font-family: var(--of-f-ui);
  font-size: var(--of-fs-24);
  font-weight: 500;
  line-height: 1.07;
  text-decoration: none;
  cursor: pointer;
  /* assets/css/style.css gives every a/button `transition: all 0.4s`, which
     turned Figma's instant hover into a slow fade. */
  transition: none;
}

.offers-body .of-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 2px solid var(--of-btn-ring);
  border-radius: inherit;
  pointer-events: none;
}

.offers-body .of-btn svg {
  flex: none;
  width: 24px;
  height: 24px;
}

/* ICONS ARE INLINE SVG FROM THE CRM (button icons here, card icons in
   sections 6 and 7). Their paint is forced to currentColor, so an icon
   takes the colour of whatever holds it — the button label's white by
   default, or a CRM btn_icon / icon colour. Presentation attributes
   (fill="white") lose to any CSS rule; the CRM's glyphs also paint some
   paths with style="fill: var(--fillg)", which is inline and can't be
   beaten — so --fillg is pointed at currentColor too. */
.offers-body :is(.of-btn, .of-step__icon, .of-feature__icon) svg {
  --fillg: currentColor;
}

.offers-body :is(.of-btn, .of-step__icon, .of-feature__icon) svg [fill]:not([fill="none"]),
.offers-body :is(.of-btn, .of-step__icon, .of-feature__icon) svg[fill]:not([fill="none"]) {
  fill: currentColor;
}

.offers-body :is(.of-btn, .of-step__icon, .of-feature__icon) svg [stroke]:not([stroke="none"]) {
  stroke: currentColor;
}

.offers-body .of-btn:hover {
  background: #2E0055;
  color: #fff;
  font-size: var(--of-fs-26);
  font-weight: 600;
  box-shadow: inset 0 0 0 1px #8A38F5, 0 0 16px #8A38F5;
}

.offers-body .of-btn:hover::before {
  opacity: 0;
  animation: none;
}

.offers-body .of-btn:hover svg {
  width: 26px;
  height: 26px;
}

.offers-body .of-btn:focus-visible {
  outline: 2px solid var(--of-lilac);
  outline-offset: 3px;
}

/* Hero "Claim My Offer" (4795:3111) and the banner's copy button: the
   instance zeroes its ring, so the hero one never pulses — only the pill's
   violet halo plus a soft drop. The component's drop is lime (#E9FD45, 18%)
   in its master, but the rendered frame shows a violet glow, so the drop
   uses the set's own violet (#510394, 30%). */
.offers-body .of-btn--copy,
.offers-body .of-btn--claim {
  width: 100%;
  box-shadow: 0 0 20px rgba(126, 55, 187, 0.3), 0 14px 40px rgba(81, 3, 148, 0.3);
}

/* Banner copy button (3888:985): a deep-violet ring and a wide glow. */
.offers-body .of-btn--dark-ring {
  --of-btn-ring: var(--of-violet-deep);
  box-shadow: 0 0 25px rgba(182, 97, 255, 0.55);
}

/* CTA (3888:947). */
.offers-body .of-btn--outline {
  --of-btn-ring: rgba(182, 97, 255, 0.6);
  gap: 24px;
  min-width: min(426px, 100%);
  box-shadow: 0 0 25px rgba(182, 97, 255, 0.55);
}

/* --------------------------------------------------------------------------
   4. S1 — Hero   (4188:3106, 1920 x 1081)
   -------------------------------------------------------------------------- */
.offers-body .of-hero {
  position: relative;
  isolation: isolate;
  /* The frame's 201px top is for a 1080px-tall screen. On a shorter one it
     pushed the bonus card and the countdown below the fold
     (references/site.png, 965px), so the top also gives way to the
     viewport's height: 900px is the 104px header plus the ~690px of title,
     copy and card, plus air under them. */
  padding: clamp(40px, min(10.47vw, 100vh - 900px), 201px) 0 clamp(48px, 4.84vw, 93px);
  background: #090010;
}

/* THE HERO FILLS THE FIRST SCREEN. Ending short of the window's foot left
   a strip of the next section showing under it, so from tablet up it is at
   least the window less the 100px sitewide header, and any spare height
   goes ABOVE the copy: the card's foot then always sits the bottom padding
   up from the window's foot, which is where the fixed countdown's foot is
   pinned (.of-timer). The mobile frame's hero is a short band, not a
   screen, so this stops at 768. */
@media (min-width: 768px) {
  .offers-body .of-hero {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: calc(100vh - 100px);
    min-height: calc(100svh - 100px);
  }

  .offers-body .of-hero__inner {
    width: 100%;
  }
}

.offers-body .of-hero__art,
.offers-body .of-hero__art > * {
  position: absolute;
  pointer-events: none;
}

.offers-body .of-hero__art {
  inset: 0;
  z-index: -1;
  overflow: hidden;
}

.offers-body .of-hero__bg {
  inset: 0;
  /* The CRM's hero image is set on this element as a background (the
     generated styles in offers.php), so its background_size/position can
     replace these. The design's composite carries the character at its
     right edge; when the hero is taller than the art (narrow desktops),
     keep her in frame. */
  background-repeat: no-repeat;
  background-size: cover;
  background-position: right center;
}

.offers-body .of-hero__shade {
  inset: 0;
  background: linear-gradient(to top, #090010, rgba(9, 0, 16, 0.5));
}

.offers-body .of-hero__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.offers-body .of-hero__title {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--of-f-display);
  font-weight: 400;
  letter-spacing: -1.6px;
  text-transform: uppercase;
}

.offers-body .of-hero__eyebrow {
  font-size: var(--of-fs-eyebrow);
  line-height: 1.03;
  background: linear-gradient(to right, var(--of-lilac), var(--of-ink));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.offers-body .of-hero__headline {
  margin-top: -3px;
  font-size: var(--of-fs-headline);
  line-height: 0.885;
  color: var(--of-violet-glow);
  text-shadow: 0 0 25px rgba(177, 108, 242, 0.25);
}

.offers-body .of-hero__desc {
  max-width: 860px;
  margin-top: clamp(16px, 1.15vw, 22px);
  font-size: var(--of-fs-24);
  font-weight: 500;
  line-height: 1.083;
  letter-spacing: -0.24px;
  color: #fff;
}

/* ---- Bonus card (4033:2363) ---- */
.offers-body .of-bonus {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 46px;
  width: 100%;
  max-width: 1196px;
  margin-top: clamp(32px, 3.39vw, 65px);
  /* The frame's 100px side padding leaves 994px for 364 + 46 + 626 —
     the artboard simply overflows it. 80px fits the columns as drawn. */
  padding: 50px clamp(24px, 4.17vw, 80px);
  border: 1px solid rgba(126, 55, 187, 0.2);
  border-radius: 10px;
  background: rgba(20, 18, 24, 0.8);
  text-align: left;
}

.offers-body .of-bonus__info {
  display: flex;
  flex-direction: column;
  /* Figma's 28px is cap-to-cap (text-box-trim, 4795:3096); with real line
     boxes the same rhythm — and the card's 323px height — is 12.7px, and
     the column starts 6px early so its first CAP, not its first line box,
     sits 50px in. */
  gap: 12.7px;
  margin-top: -6px;
  flex: 0 0 364px;
  line-height: 1.2;
  min-width: 0;
  font-family: var(--of-f-ui);
  font-weight: 500;
  color: #fff;
}

.offers-body .of-bonus__label {
  font-size: var(--of-fs-24);
  color: var(--of-lilac-soft);
  text-transform: uppercase;
}

.offers-body .of-bonus__title {
  font-size: var(--of-fs-36);
  font-weight: 700;
  line-height: 1.1;
  text-transform: uppercase;
}

.offers-body .of-bonus__note {
  font-size: 16px;
  text-transform: capitalize;
}

.offers-body .of-bonus__rule {
  margin: 0;
  border: 0;
  border-top: 1px solid #6B7280;
  opacity: 1;
}

.offers-body .of-hl {
  color: var(--of-violet-glow);
}

/* The hero copy's accent is bold white, not violet (4795:3112). */
.offers-body .of-hero__desc .of-hl {
  color: inherit;
  font-weight: 700;
}

/* ---- Code chip (4795:3102): the code and a copy glyph; the whole chip
   copies. offers.js swaps the code for "Copied!" for two seconds. ---- */
.offers-body .of-bonus__code {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 44px;
  min-height: 56px;
  padding: 8px 20px;
  border: 1px solid rgba(126, 55, 187, 0.4);
  border-radius: 8px;
  background: #130F19;
  color: #fff;
  cursor: pointer;
  transition: none;
}

.offers-body .of-bonus__code:hover {
  border-color: #8A38F5;
  box-shadow: 0 0 12px rgba(138, 56, 245, 0.4);
}

.offers-body .of-bonus__code:focus-visible {
  outline: 2px solid var(--of-lilac);
  outline-offset: 3px;
}

.offers-body .of-bonus__code svg {
  flex: none;
  width: 30px;
  height: 30px;
}

.offers-body .of-voucher__code {
  font-family: 'Righteous', sans-serif;
  font-size: var(--of-fs-36);
  line-height: 1;
  letter-spacing: 1.344px;
  color: #fff;
  overflow-wrap: anywhere;
}

/* ---- Countdown badge (4795:3186, 285 x 84): a tab fixed to the screen's
   left edge, in view the whole way down. Pinned the hero's bottom padding
   up, so as the page opens its foot is level with the bonus card's
   (references/hero.png) — the hero fills the first screen with the card
   at its foot (section 4). ---- */
.offers-body .of-timer {
  position: fixed;
  left: 0;
  bottom: clamp(48px, 4.84vw, 93px);
  z-index: 50;
  padding: 10px 17px 10px 30px;
  border-radius: 0 10px 10px 0;
  background: rgba(98, 45, 150, 0.55);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  font-family: var(--of-f-ui);
  color: #fff;
}

.offers-body .of-timer__label {
  margin: 0 0 8px;
  font-family: var(--of-f-ui);
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  color: #fff;
  text-transform: uppercase;
}

.offers-body .of-countdown {
  display: flex;
  align-items: flex-start;
  gap: 15px;
  color: var(--of-lilac);
  text-align: center;
}

.offers-body .of-countdown__part {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-width: 2.2ch;
}

.offers-body .of-countdown__value,
.offers-body .of-countdown__sep {
  font-size: 24px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.offers-body .of-countdown__sep {
  font-size: 18px;
  font-weight: 500;
  line-height: 24px;
  color: #C4C9D2;
}

.offers-body .of-countdown__unit {
  font-size: 10px;
  font-weight: 500;
  line-height: 1;
  color: #C4C9D2;
  text-transform: uppercase;
}

/* The hide/show handle is a mobile-only feature (section 12). */
.offers-body .of-timer__toggle {
  display: none;
}

/* ---- Voucher panel (4033:2386) ---- */
.offers-body .of-voucher {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex: 0 1 626px;
  min-width: 0;
  /* 50px to the label's CAP in the frame; at line-height 1 its cap sits
     3.25px inside the box, so 46.75px here (and below it). 38px under the
     button (4795:3108). */
  padding: 46.75px clamp(20px, 2.97vw, 57px) 38px;
  border: 1px solid rgba(169, 180, 202, 0.2);
  border-radius: 10px;
  background: var(--of-voucher);
  box-shadow: 0 0 10px rgba(169, 180, 202, 0.1);
}

.offers-body .of-voucher__label {
  margin-bottom: 46.75px;
  font-family: var(--of-f-ui);
  font-size: var(--of-fs-24);
  font-weight: 500;
  line-height: 1;
  color: #fff;
  text-align: center;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   5. Section heads — shared by S2 and S3 (S2 restyles its own in section 6)
   -------------------------------------------------------------------------- */
.offers-body .of-section {
  border-top: 1px solid var(--of-hairline);
}

.offers-body .of-head {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 900px;
  margin: 0 auto clamp(40px, 3.33vw, 64px);
  text-align: center;
}

.offers-body .of-head__title {
  max-width: 672px;
  margin: 0 auto;
  font-family: var(--of-f-heading);
  font-size: var(--of-fs-44);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -1.1px;
  color: var(--of-ink);
}

.offers-body .of-head--wide .of-head__title {
  max-width: 800px;
}

.offers-body .of-head__sub {
  font-size: var(--of-fs-28);
  line-height: 1.46;
  color: var(--of-body);
}

/* --------------------------------------------------------------------------
   6. S2 — How to claim: tags on a rope
      Desktop: Figma 4521:5070. Mobile: Figma 4323:2656 (section 12 has
      no S2 rules; its layout is the @media block at the end of this one).
      Motion: references/claim-steps-section.html, in offers.js.

   DESKTOP. One rope strung edge to edge across the section (Figma
   "Vector 652": 53px of sag over the width, #B661FF fading to #74658B).
   Each card hangs from a pin on it by a 90px string; offers.js drops each
   card (--drop) to where the rope passes over its centre, so the outer
   cards sit higher than the inner ones exactly as the frame draws them.

   MOBILE (<=767px). The rope turns vertical and runs down the left edge,
   bowing 20px right at its middle ("Vector 653"); each card hangs
   sideways off it on a horizontal string that ends in the card's hole.
   offers.js puts each pin on the curve (--pin).

   TABLET (768-1040px): two columns, each card on its own pin, no rope.

   The section is laid out for any number of cards (offers.php sets --cols
   from the CRM's count). style_data maps headline/description/icon/
   headline/description/step to .of-head__title, .of-head__sub,
   .of-step__icon, .of-step__title, .of-step__text and .of-step__label.
   -------------------------------------------------------------------------- */
.offers-body .of-steps {
  --of-rope:       #B661FF;
  --of-rope-end:   #74658B;
  --of-string:     90px;
  /* Read by offers.js: which rope, and how far a tag may swing (rad). */
  --of-rope-mode:  h;
  --of-swing-max:  0.17;

  padding: clamp(24px, 1.56vw, 30px) 0 clamp(48px, 4.27vw, 82px);
}

.offers-body .of-steps .of-head {
  gap: 4px;
  margin-bottom: clamp(32px, 2.6vw, 50px);
}

/* Head copy keeps the shared section-head look (section 5) — it is the
   frame's 44/52 Plus Jakarta and 28px Be Vietnam Pro — except that this
   frame sets the lede at the face's normal line height, not 1.46. */
.offers-body .of-steps .of-head__sub {
  line-height: 1.25;
}

.offers-body .of-steps__area {
  position: relative;
}

.offers-body .of-steps__list {
  position: relative;
  display: grid;
  /* 281px cards with 24px between them (Figma), as many as the CRM sends
     in a row (--cols), shrinking only when the row would not fit. */
  grid-template-columns: repeat(var(--cols, 4), minmax(0, 281px));
  justify-content: center;
  gap: 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A tag: its string and pin sit in the 90px above the card. --drop
   (offers.js) lowers it onto the rope; --a is its swing, about the pin. */
.offers-body .of-step {
  position: relative;
  margin-top: var(--drop, 0px);
  padding-top: var(--of-string);
  transform-origin: 50% 0;
  transform: rotate(var(--a, 0deg));
  will-change: transform;
}

/* The string: pin to the card's hole, behind the card (Figma "Line 1":
   2px, #B661FF fading to #74658B). */
.offers-body .of-step::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  width: 2px;
  height: calc(var(--of-string) + 20px);
  margin-left: -1px;
  background: linear-gradient(var(--of-rope), var(--of-rope-end));
}

/* The pin on the rope: a 10.67px dot. */
.offers-body .of-step::after {
  content: '';
  position: absolute;
  left: 50%;
  top: -5.33px;
  width: 10.67px;
  height: 10.67px;
  margin-left: -5.33px;
  border-radius: 50%;
  background: var(--of-rope);
}

.offers-body .of-step__card {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
  height: 100%;
  min-height: 338px;
  padding: 12px 13px 23px;
  border: 1px solid rgba(88, 66, 53, 0.5);
  border-radius: 16px;
  background: #26272A;
}

/* The punched hole the string runs into (Figma "Ellipse 38192"). */
.offers-body .of-step__hole {
  flex: none;
  width: 16px;
  height: 16px;
  border: 2px solid rgba(223, 183, 255, 0.4);
  border-radius: 50%;
  background: #1E1034;
}

.offers-body .of-step__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  width: 100%;
}

.offers-body .of-step__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
}

.offers-body .of-step__num {
  padding-top: 11px;
  font-family: var(--of-f-heading);
  font-size: var(--of-fs-36);
  font-weight: 800;
  line-height: 26px;
  font-variant-numeric: tabular-nums;
  color: var(--of-lilac);
  background: linear-gradient(122deg, #E0B6FF 2.41%, #B661FF 194.75%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* The CRM sends the glyph; the tile is drawn here. */
.offers-body .of-step__icon {
  display: grid;
  flex: none;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid rgba(109, 17, 173, 0.5);
  border-radius: 12px;
  background: rgba(109, 17, 173, 0.3);
  color: var(--of-lilac-label);
}

.offers-body .of-step__icon svg {
  width: 26px;
  height: 26px;
}

.offers-body .of-step__title {
  margin-bottom: 10px;
  font-family: var(--of-f-heading);
  font-size: var(--of-fs-22);
  font-weight: 700;
  line-height: 26px;
  color: var(--of-ink);
}

.offers-body .of-step__text {
  font-size: var(--of-fs-18);
  line-height: 1.356;
  color: #C4C9D2;
}

.offers-body .of-step__label {
  margin-top: auto;
  padding-top: 26px;
  font-family: var(--of-f-heading);
  font-size: 10px;
  font-weight: 600;
  line-height: 14px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--of-lilac-label);
}

/* The ropes. Hidden until offers.js decides one fits (.is-roped). The
   horizontal one is full-bleed; its depth is 2 x the sag, because a
   quadratic curve only reaches half its control point. */
.offers-body .of-steps__rope {
  display: none;
  position: absolute;
  overflow: visible;
  pointer-events: none;
}

.offers-body .of-steps__rope path {
  fill: none;
  stroke-width: 2;
}

.offers-body .of-steps__rope--h {
  top: 0;
  left: calc(50% - 50vw);
  width: 100vw;
  height: 106px;
}

.offers-body .of-steps__rope--v {
  top: -30px;
  bottom: -30px;
  left: 2px;
  width: 40px;
  height: calc(100% + 60px);
}

.offers-body .of-steps__list.is-roped ~ .of-steps__rope--h {
  display: block;
}

.offers-body .of-steps__list.is-roped-v ~ .of-steps__rope--v {
  display: block;
}

/* Reveal. Hidden only once offers.js has armed it (and only if the browser
   can tell it when to show them), so without JS the tags simply show. */
.offers-body .of-steps__list.is-armed .of-step {
  opacity: 0;
  transition: opacity 0.5s;
}

.offers-body .of-steps__list.is-armed .of-step.is-in {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .offers-body .of-steps__list.is-armed .of-step {
    transition-duration: 0.01ms;
  }
}

/* ---- Tablet: two columns, each tag on its own pin ---- */
@media (max-width: 1040px) {
  .offers-body .of-steps__list {
    grid-template-columns: repeat(2, minmax(0, 340px));
    gap: 32px 24px;
  }

  /* Wider than the frame's 281px, the copy wraps less: let the card fit
     it (each row still matches its tallest card) instead of padding out
     to the desktop's 338px. */
  .offers-body .of-step__card {
    min-height: 0;
  }
}

/* ---- Mobile: the vertical rope (Figma 4323:2656) ---- */
@media (max-width: 767px) {
  .offers-body .of-steps {
    --of-rope-mode: v;
    /* A sideways tag swinging as far as a hanging one would hit its
       neighbours 10px away. */
    --of-swing-max: 0.04;
    /* Figma 4795:3422 (revised): the heading sits 42px under the bonus
       card, and the last step ends 55px above section 3's heading (16 here
       + its 39). */
    padding: 42px 0 16px;
  }

  .offers-body .of-steps .of-head {
    gap: 6px;
    margin-bottom: 39px;
    /* The container drops its left gutter for the rope; the head keeps it. */
    padding-left: 16px;
  }

  .offers-body .of-steps .of-head__title {
    font-size: 20px;
    line-height: 30px;
    letter-spacing: -0.5px;
    color: #fff;
  }

  .offers-body .of-steps .of-head__sub {
    max-width: 320px;
    font-size: 12px;
    line-height: 19.5px;
  }

  .offers-body .of-steps .of-container {
    padding-right: 16px;
    padding-left: 0;
  }

  .offers-body .of-steps__list {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }

  /* The card starts 33px in; the string spans from the pin to its hole. */
  .offers-body .of-step {
    margin-top: 0;
    padding-top: 0;
    padding-left: 33px;
    transform-origin: var(--pin, 10px) 50%;
  }

  .offers-body .of-step::before {
    top: 50%;
    left: var(--pin, 10px);
    width: calc(33px - var(--pin, 10px) + 15px);
    height: 2px;
    margin: -1px 0 0;
    background: linear-gradient(to right, var(--of-rope), var(--of-rope-end));
  }

  .offers-body .of-step::after {
    top: 50%;
    left: var(--pin, 10px);
    margin: -5.33px 0 0 -5.33px;
  }

  .offers-body .of-step__card {
    flex-direction: row;
    gap: 10px;
    /* 148px cards on a 160px pitch (Figma 4795:3435, revised). */
    min-height: 148px;
    padding: 10.5px 14px 10.5px 7px;
    border-color: rgba(88, 66, 53, 0.3);
    border-radius: 12px;
  }

  .offers-body .of-step__body {
    gap: 1px;
  }

  .offers-body .of-step__top {
    align-items: flex-start;
    margin-bottom: 0;
  }

  .offers-body .of-step__num {
    padding-top: 0;
    font-size: 24px;
    background-image: linear-gradient(114deg, #E0B6FF 2.41%, #B661FF 194.75%);
  }

  .offers-body .of-step__icon {
    width: 30px;
    height: 30px;
    border-radius: 8px;
  }

  .offers-body .of-step__icon svg {
    width: 20px;
    height: 20px;
  }

  .offers-body .of-step__title {
    margin-bottom: 0;
    font-size: 13px;
    line-height: 26px;
  }

  /* Same grey as desktop (#C4C9D2) — the revised frame dropped the lilac. */
  .offers-body .of-step__text {
    font-size: 11px;
    line-height: 14.4px;
  }

  .offers-body .of-step__label {
    margin-top: 0;
    padding-top: 10px;
  }
}

/* --------------------------------------------------------------------------
   7. S3 — Value proposition   (4181:2743)
   -------------------------------------------------------------------------- */
.offers-body .of-features {
  padding: clamp(64px, 5.05vw, 97px) 0 96px;
}

.offers-body .of-features__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 52px 32px;
  max-width: 1216px;
  margin: 0 auto;
}

.offers-body .of-feature {
  display: flex;
  flex-direction: column;
  gap: 11px;
  min-height: 281px;
  padding: 32px;
  border-left: 8px solid var(--of-violet-glow);
  border-radius: 15px;
  background: var(--of-card);
}

/* Hover (4008:1276 Variant2–5, instant): the stroke moves from INSIDE to
   OUTSIDE and gains 1px on the other three sides, plus a #B661FF 20%
   drop shadow (4, 4, r4). Outside strokes take no room, so they are shadows
   here: the 8px bar is a -8px offset copy of the card, the 1px sides a ring.
   With the inside border gone the content steps 8px left (x 40 -> 32 in the
   variant) — that shift is the design, not a side effect. */
.offers-body .of-feature:hover {
  border-left-width: 0;
  box-shadow:
    0 0 0 1px var(--of-violet-glow),
    -8px 0 0 0 var(--of-violet-glow),
    4px 4px 4px rgba(182, 97, 255, 0.2);
}

/* The icon tile — the rounded violet square from the Figma tiles: #6D11AD
   at 30% with a 50% hairline, r12. The CRM only sends the glyph, so the
   tile is drawn here, tinted the design's lilac unless the CRM sets an
   icon colour. */
.offers-body .of-feature__icon {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border: 1px solid rgba(109, 17, 173, 0.5);
  border-radius: 12px;
  background: rgba(109, 17, 173, 0.3);
  color: var(--of-lilac-label);
}

.offers-body .of-feature__icon svg {
  width: 28px;
  height: 28px;
}

.offers-body .of-feature__title {
  padding-top: 13px;
  font-family: var(--of-f-heading);
  font-size: var(--of-fs-22);
  font-weight: 700;
  line-height: 1.27;
  letter-spacing: -0.22px;
  color: var(--of-ink);
}

.offers-body .of-feature__text {
  font-size: var(--of-fs-20);
  line-height: 1.22;
  color: var(--of-body);
}

/* --------------------------------------------------------------------------
   8. S4 — CTA band   (4181:2695)
   -------------------------------------------------------------------------- */
.offers-body .of-cta {
  padding: clamp(64px, 5.47vw, 105px) 0;
  background: var(--of-band);
  text-align: center;
}

.offers-body .of-cta__title {
  /* The section heads' face since 4795:3006 (was Inter 800). */
  font-family: var(--of-f-heading);
  font-size: var(--of-fs-48);
  font-weight: 700;
  line-height: 1.2;
  text-transform: capitalize;
  color: #fff;
}

.offers-body .of-cta__text {
  max-width: 900px;
  margin: 20px auto 52px;
  font-size: var(--of-fs-28);
  line-height: 1.43;
  color: var(--of-body);
}

/* No active offer: the CTA band on its own, given room to breathe. */
.offers-body .of-cta--empty {
  padding: clamp(96px, 10vw, 180px) 0;
}

/* --------------------------------------------------------------------------
   9. S5 — Closing banner   (4290:3760, 1920 x 820)
   -------------------------------------------------------------------------- */
.offers-body .of-banner {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  /* The composite's own 1920:820, so `cover` never crops it at desktop. */
  min-height: clamp(560px, 42.708vw, 820px);
  padding: 80px 0;
  background: #090010;
}

.offers-body .of-banner__art,
.offers-body .of-banner__art > * {
  position: absolute;
  pointer-events: none;
}

.offers-body .of-banner__art {
  inset: 0;
  z-index: -2;
  overflow: hidden;
}



.offers-body .of-banner__bg {
  inset: 0;
  /* A background, like the hero's — see .of-hero__bg. The design's figure
     stands at the composite's bottom-left. */
  background-repeat: no-repeat;
  background-size: cover;
  background-position: left bottom;
}

/* The two "Rectangle 5074" blends (4290:3793, 4290:3871): the CTA band's
   #1E1E1E bleeds into the top of the art, and the art sinks into the footer
   at the bottom — so neither seam is a hard edge. The frame fades into its
   own footer colour; this page keeps the sitewide footer, so it fades into
   that one's #1E1E1E (.footer-layout3) instead. */
.offers-body .of-banner::before,
.offers-body .of-banner::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  z-index: -1;
  pointer-events: none;
}

.offers-body .of-banner::before {
  top: 0;
  height: clamp(64px, 6.61vw, 127px);
  background: linear-gradient(to bottom, var(--of-band), rgba(30, 30, 30, 0));
}

.offers-body .of-banner::after {
  bottom: 0;
  height: clamp(64px, 6.93vw, 133px);
  background: linear-gradient(to top, var(--of-band), rgba(30, 30, 30, 0));
}

.offers-body .of-banner > .of-container {
  /* The section is a flex row (it centres the card vertically), which would
     otherwise shrink the container to its content and the card with it. */
  width: 100%;
}

.offers-body .of-banner__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 893 x 473, centred (4290:3764). The vampire moved into the art, so the
     old 154px left inset he stood in is gone and the padding is even.

     THE FRAME'S SPACING IS CAP-TO-CAP. Its 54.5px inset and 20px gaps are
     measured to text boxes trimmed to cap height (text-box-trim, which not
     every browser has yet), so they are converted here to real line boxes
     at line-height 1: the title's cap sits 6.5px inside its box and the
     subtitle's 3.9px — hence 48px on top, 9.6px between the two lines and
     16px down to the redeem block. Together they land the card on its drawn
     473px. */
  gap: 0;
  max-width: 893px;
  min-height: 473px;
  margin: 0 auto;
  padding: 48px 28px 54.5px;
  /* Sampled off the frame: #684881 over the art's #25143F. */
  border: 1px solid rgba(180, 140, 230, 0.4);
  border-radius: 20px;
  box-shadow: 0 0 20px rgba(126, 55, 187, 0.05);
  justify-content: center;
  text-align: center;
}

.offers-body .of-banner__title {
  font-family: var(--of-f-strong);
  font-size: var(--of-fs-48);
  font-weight: 700;
  line-height: 1;
  text-transform: capitalize;
  color: #fff;
}

.offers-body .of-banner__sub {
  margin-top: 9.6px;
  font-size: var(--of-fs-28);
  font-weight: 500;
  line-height: 1;
  color: var(--of-body);
}

.offers-body .of-banner__redeem {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  max-width: 481px;
  margin-top: 16px;
  /* 268px tall with its content centred — 13px each way, not the 27/28 its
     auto-layout lists. */
  padding: 13px 28px;
  border-radius: 22px;
  filter: drop-shadow(0 18px 25px rgba(0, 0, 0, 0.25));
}

.offers-body .of-banner__code {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 31px;
  min-height: 64px;
  padding: 4px 19px;
  border: 1px dashed #8EA1C1;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.2);
}

.offers-body .of-banner__code-label {
  font-family: 'DM Sans', sans-serif;
  font-size: var(--of-fs-20);
  letter-spacing: 1.581px;
  text-transform: uppercase;
  color: #BBC7DE;
}

.offers-body .of-banner__code strong {
  font-family: 'Manrope', sans-serif;
  font-size: var(--of-fs-36);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: 1.984px;
  color: #fff;
}

.offers-body .of-banner__terms {
  /* One centred line in 4795:2998 — wider than the 425px column it sits
     in, so it borrows 100px each side of the card's 206px margin. */
  margin: 0 -100px;
  font-size: var(--of-fs-18);
  line-height: 1.97;
  color: var(--of-body);
  text-align: center;
}

.offers-body .of-banner__terms a {
  font: inherit;
  color: var(--of-lilac);
}

.offers-body .of-banner__terms a:hover {
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   10. Motion — the prototype's own timeline, read from its reactions

   HERO (component set 4033:2459). Six variants chained by after-delay
   Smart Animate. Every change between them is OPACITY ONLY — nothing in
   the hero slides — so each step is a fade, timed as the reactions are:

     delay  then  transition                       -> starts at / lasts
     0.1s         "Boo!" line                      0.1s / 0.5s ease-out
     0.3s         "20% Bigger!" (and its glow)     0.9s / 0.7s ease-out
     0.3s         description                      1.9s / 0.5s ease-out
     0.2s         bonus card                       2.6s / 0.6s ease-out

   The character used to fade in and float as a layer of its own. She is
   part of the hero composite now (hero.image), so the art is simply there
   from the first frame — fading or floating the whole image would move the
   smoke with her.

   `of-fade` has no `to`, so each element fades to its OWN opacity.

   BUTTON RING (3888:947 / 3888:985, Default <-> Variant2). After 0.8s the
   ring grows 16px on every side and fades out over 1s ease-out (its stroke
   2 -> 4px), holds 0.1s, then dissolves back in place over 1s. 2.9s a
   cycle. The hero voucher's instance has no visible ring, so it does not
   take part.

   A reduced-motion reader gets the finished state: everything visible,
   nothing moving.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .offers-body .of-hero__eyebrow  { animation: of-fade 0.5s ease-out 0.1s both; }
  .offers-body .of-hero__headline { animation: of-fade 0.7s ease-out 0.9s both; }
  .offers-body .of-hero__desc     { animation: of-fade 0.5s ease-out 1.9s both; }
  .offers-body .of-bonus,
  .offers-body .of-timer          { animation: of-fade 0.6s ease-out 2.6s both; }
  .offers-body .of-timer          { transition: transform 0.35s ease; }
  .offers-body .of-timer__toggle svg { transition: transform 0.35s ease; }

  .offers-body .of-btn--outline::before,
  .offers-body .of-btn--dark-ring::before {
    animation: of-ring 2.9s infinite;
  }
}

@keyframes of-fade {
  from { opacity: 0; }
}

/* 0.8 / 1.0 / 0.1 / 1.0 s of a 2.9s cycle, as percentages. */
@keyframes of-ring {
  0%, 27.59% { inset: 0;     opacity: 1; border-width: 2px; animation-timing-function: ease-out; }
  62.07%,
  65.52%     { inset: -16px; opacity: 0; border-width: 4px; }
  65.53%     { inset: 0;     opacity: 0; border-width: 2px; animation-timing-function: ease-out; }
  100%       { inset: 0;     opacity: 1; border-width: 2px; }
}

/* The frame sets the description as a left-aligned block under a centred
   headline. Only on desktop — once it wraps to 3+ lines a ragged left edge
   under centred type looks like a mistake. */
@media (min-width: 1200px) {
  .offers-body .of-hero__desc {
    text-align: left;
  }
}

/* --------------------------------------------------------------------------
   11. Tablet — between the two frames: the desktop layout, stacked.
   -------------------------------------------------------------------------- */
@media (max-width: 1199px) {
  .offers-body .of-bonus {
    flex-direction: column;
    align-items: stretch;
    max-width: 680px;
  }

  .offers-body .of-bonus__info,
  .offers-body .of-voucher {
    flex: 0 1 auto;
  }

  .offers-body .of-banner__terms {
    margin: 0;
  }

  .offers-body .of-banner__card {
    padding: 48px 32px;
  }
}

@media (max-width: 991px) {
  .offers-body .of-features__grid {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  .offers-body .of-feature {
    min-height: 0;
  }
}

/* --------------------------------------------------------------------------
   12. Mobile — "Offer page mobile version" (4323:2567, 390 artboard)

   Its own design, not the desktop shrunk: the hero copy goes left-aligned
   over a short band of the art, the bonus card drops out of the hero into a
   single centred column, the steps sit two-up, the feature cards turn into
   icon-beside-text rows, and the CTA and closing banner each become a card.

   Every value here is measured off a 2x render of the frame (the MCP export
   was rate-limited when this was built), and font sizes were fitted by
   setting each line in the real face until its width matched the frame's
   to the pixel — which is why a few are half-pixel sizes.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
  .offers-body {
    --of-gutter: 16px;
    background: #121214;
  }

  /* ---- Hero: copy over a 1920:1081 band of the art ---- */
  .offers-body .of-hero {
    padding: 0;
    background: #121214;
  }

  .offers-body .of-hero__art {
    inset: 0 0 auto;
    height: calc(100vw * 1081 / 1920);
  }

  .offers-body .of-hero__inner {
    align-items: flex-start;
    text-align: left;
  }

  /* Figma 4795:3332 (revised): the title is centred over the art and
     smaller; the copy under it stays left-aligned, set in 28px. */
  .offers-body .of-hero__title {
    align-self: stretch;
    align-items: center;
    padding-top: 35px;
    letter-spacing: -0.65px;
    text-align: center;
  }

  .offers-body .of-hero__eyebrow {
    max-width: 190px;
    font-size: 28px;
    line-height: 24px;
  }

  .offers-body .of-hero__headline {
    margin-top: 2px;
    font-size: 49px;
    line-height: 42px;
    letter-spacing: -0.35px;
  }

  .offers-body .of-hero__desc {
    /* Sits 10px right of centre under the title (by request); the lines
       stay left-aligned. */
    align-self: flex-start;
    max-width: 314px;
    margin-top: 7px;
    margin-left: calc((100% - 314px) / 2 + 10px);
    font-family: 'Inter', sans-serif;
    font-size: 13px;
    font-weight: 400;
    line-height: 19px;
    letter-spacing: 0;
  }

  /* ---- Bonus card: one centred column ---- */
  .offers-body .of-bonus {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    max-width: none;
    /* 15px clear of the art band's foot in the frame. */
    margin-top: 43px;
    padding: 26px 16px 16px;
    border-color: rgba(126, 55, 187, 0.25);
    border-radius: 12px;
    background: #161619;
    text-align: center;
  }

  .offers-body .of-bonus__info {
    flex: 0 1 auto;
    align-items: center;
    gap: 0;
    margin-top: 0;
  }

  .offers-body .of-bonus__label {
    font-size: 10.5px;
    font-weight: 600;
    line-height: 13px;
    letter-spacing: 1.45px;
  }

  .offers-body .of-bonus__title {
    margin-top: 7px;
    font-size: 22px;
    line-height: 26px;
    letter-spacing: -0.33px;
  }

  .offers-body .of-bonus__note {
    margin-top: 5px;
    font-size: 11px;
    font-weight: 400;
    line-height: 14px;
    letter-spacing: -0.1px;
  }

  /* The mobile frame has no rule between the note and the code. */
  .offers-body .of-bonus__rule {
    display: none;
  }

  /* Code chip and voucher panel: two 324px blocks, 17px apart
     (references/mobile.png). */
  .offers-body .of-bonus__code {
    align-self: stretch;
    gap: 64px;
    min-height: 42px;
    margin-top: 18px;
    padding: 6px 12px;
    border-color: rgba(126, 55, 187, 0.5);
    background: #170F20;
    box-shadow: 0 0 8px rgba(126, 55, 187, 0.35);
  }

  .offers-body .of-bonus__code svg {
    width: 18px;
    height: 18px;
  }

  .offers-body .of-voucher__code {
    font-size: 16.5px;
  }

  /* The badge: 125 x 35, square, with a lighter handle down its right
     edge — low on the left, clear of the chat button on the right. */
  .offers-body .of-timer {
    bottom: 16px;
    /* 6px of breathing room plus the 4px handle. */
    padding: 4px 10px 3px 6px;
    border-radius: 0;
    background: #3A2155;
    box-shadow: none;
  }

  /* Collapsed: slide everything but the handle off the left edge. */
  .offers-body .of-timer.is-collapsed {
    transform: translateX(calc(-100% + 4px));
  }

  /* The handle (Figma 4844:1305): a 4px lilac strip, rounded on its outer
     corners, with a small faded arrow drawn inside it. Pointing left =
     "push me away"; flipped once the badge is tucked away. */
  .offers-body .of-timer__toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 4px;
    padding: 0;
    border: 0;
    border-radius: 0 3px 3px 0;
    background: #6F4A92;
    color: #DEB6FF;
    cursor: pointer;
  }

  /* 4px is too thin to tap: widen the hit area without widening the strip. */
  .offers-body .of-timer__toggle::after {
    content: '';
    position: absolute;
    top: -6px;
    right: -20px;
    bottom: -6px;
    left: -10px;
  }

  .offers-body .of-timer__toggle svg {
    flex: none;
    opacity: 0.8;
  }

  .offers-body .of-timer.is-collapsed .of-timer__toggle svg {
    transform: scaleX(-1);
  }

  .offers-body .of-timer__toggle:focus-visible {
    outline: 2px solid #D9B8FF;
    outline-offset: 2px;
  }

  .offers-body .of-timer__label {
    margin-bottom: 2px;
    font-size: 8.5px;
  }

  .offers-body .of-countdown {
    gap: 3px;
  }

  .offers-body .of-countdown__part {
    gap: 2px;
  }

  .offers-body .of-countdown__value {
    font-size: 15px;
  }

  .offers-body .of-countdown__sep {
    font-size: 12px;
    line-height: 15px;
  }

  .offers-body .of-countdown__unit {
    font-size: 6px;
  }

  .offers-body .of-voucher {
    flex: 0 1 auto;
    margin-top: 17px;
    padding: 16px 8px;
    border: 0;
    border-radius: 8px;
    background: #26252B;
    box-shadow: none;
  }

  .offers-body .of-voucher__label {
    margin-bottom: 10px;
    font-size: 9.5px;
    font-weight: 700;
    line-height: 12px;
  }

  /* Every mobile button label is set regular, a touch larger than desktop's
     semibold (Figma 4795:3414 / 3557 / 3584). */
  .offers-body .of-btn {
    gap: 10px;
    min-height: 42px;
    padding: 10px 16px;
    border-radius: 8px;
    font-size: 15px;
    font-weight: 400;
  }

  .offers-body .of-btn svg {
    width: 16px;
    height: 16px;
  }

  /* The mobile frame keeps every button's violet glow but drops the
     pulsing ring. */
  .offers-body .of-btn,
  .offers-body .of-btn--copy,
  .offers-body .of-btn--claim,
  .offers-body .of-btn--dark-ring,
  .offers-body .of-btn--outline {
    --of-btn-ring: transparent;
    box-shadow: 0 0 12px rgba(182, 97, 255, 0.5);
  }

  .offers-body .of-btn::before {
    animation: none;
  }

  /* Touch screens have no hover: keep the buttons as drawn. */
  .offers-body .of-btn:hover {
    font-size: 15px;
  }

  .offers-body .of-btn:hover svg {
    width: 16px;
    height: 16px;
  }

  /* ---- Section heads ---- */
  .offers-body .of-section {
    border-top: 0;
  }

  .offers-body .of-head {
    gap: 8px;
    margin-bottom: 14px;
  }

  .offers-body .of-head__title {
    font-size: 19px;
    line-height: 24px;
    letter-spacing: 0;
  }

  .offers-body .of-head__sub {
    max-width: 310px;
    margin: 0 auto;
    font-size: 12px;
    line-height: 20px;
  }

  /* ---- Steps: section 6 carries its own mobile layout ---- */

  /* The frame's mobile feature tiles are 30px with the glyph drawn ~1.3x
     larger relative to the tile than on desktop (measured: 17.5px of glyph
     in the globe) — an 18px glyph box gives that. */
  .offers-body .of-feature__icon {
    width: 30px;
    height: 30px;
    border-radius: 7px;
  }

  .offers-body .of-feature__icon svg {
    width: 18px;
    height: 18px;
  }

  /* ---- Features: icon beside text ---- */
  .offers-body .of-features {
    padding: 39px 0 39px;
  }

  /* Figma 4795:3496 (revised): 5px from heading to sub, 24px from sub to
     the cards. */
  .offers-body .of-features .of-head {
    gap: 5px;
    margin-bottom: 24px;
  }

  .offers-body .of-features .of-head__title {
    max-width: 300px;
    font-size: 19px;
    line-height: 26.5px;
    letter-spacing: -0.45px;
  }

  .offers-body .of-features .of-head__sub {
    max-width: 350px;
    font-size: 11.5px;
    line-height: 17px;
  }

  .offers-body .of-features__grid {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  .offers-body .of-feature {
    display: grid;
    grid-template-columns: 30px 1fr;
    grid-template-rows: auto 1fr;
    column-gap: 14.5px;
    row-gap: 4px;
    min-height: 0;
    padding: 15px 24px 14px 14px;
    border: 1px solid #26262C;
    border-left: 3px solid #833DF0;
    border-radius: 10px;
    /* The same fill as the step cards (#2A2B2E in the frame). */
    background: #2A2B2E;
  }

  .offers-body .of-feature:hover {
    border-left-width: 3px;
    box-shadow: none;
  }

  .offers-body .of-feature__icon {
    grid-row: 1 / span 2;
  }

  .offers-body .of-feature__title {
    padding-top: 0;
    font-family: 'Inter', sans-serif;
    font-size: 13px;
    font-weight: 600;
    line-height: 16px;
    letter-spacing: -0.1px;
    color: #fff;
  }

  .offers-body .of-feature__text {
    font-size: 11px;
    line-height: 18px;
    letter-spacing: -0.14px;
  }

  /* ---- CTA: straight on the band, no card (references/mobile.png) ---- */
  /* Figma 4795:3549: content 38px down the band, 33px side gutters; the
     36px below plus the banner's 64px top is the frame's 100px to the card. */
  .offers-body .of-cta {
    padding: 38px 0 36px;
    background: #1E1E1E;
  }

  .offers-body .of-cta .of-container > * {
    max-width: none;
  }

  .offers-body .of-cta .of-container {
    padding: 0 33px;
  }

  .offers-body .of-cta__title {
    font-size: 17px;
    font-weight: 700;
    line-height: 24px;
  }

  .offers-body .of-cta__text {
    /* A touch wider than the button's padding, as in the frame — it is
       what puts the break after "6 ad formats". */
    margin: 3px -5px 14px;
    font-size: 11px;
    line-height: 15px;
  }

  .offers-body .of-btn--outline {
    display: flex;
    width: 100%;
    min-height: 40px;
  }

  /* ---- Closing banner: the card, then the art underneath ---- */
  .offers-body .of-banner {
    display: block;
    min-height: 0;
    padding: 64px 0 calc(100vw * 820 / 1920 - 52px);
    overflow: hidden;
    background:
      radial-gradient(120% 60% at 0% 25%, rgba(70, 30, 110, 0.55), rgba(70, 30, 110, 0) 70%),
      linear-gradient(to bottom, #1E1E1E 0, #1A1426 18%, #160B21 55%, #13091C 100%);
  }

  .offers-body .of-banner::before,
  .offers-body .of-banner::after {
    display: none;
  }

  /* No art from the CRM: no room kept under the card for it. */
  .offers-body .of-banner--no-art {
    padding-bottom: 48px;
  }

  /* The frame lets the art run ~12px past the section's foot, cropping
     the bottom of the figure. */
  .offers-body .of-banner__art {
    inset: auto 0 -12px;
    height: calc(100vw * 820 / 1920);
  }

  .offers-body .of-banner__bg {
    /* Fade the art's top edge into the glow above it. */
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 30%);
    mask-image: linear-gradient(to bottom, transparent, #000 30%);
  }

  .offers-body .of-banner__card {
    gap: 0;
    min-height: 0;
    padding: 18px 16px 23px;
    border-color: rgba(187, 160, 230, 0.35);
    border-radius: 12px;
    background: rgba(18, 8, 28, 0.25);
  }

  .offers-body .of-banner__title {
    font-size: 14px;
    line-height: 18px;
    letter-spacing: -0.35px;
  }

  .offers-body .of-banner__sub {
    margin-top: 4px;
    font-size: 11px;
    line-height: 14px;
    letter-spacing: -0.1px;
  }

  .offers-body .of-banner__redeem {
    gap: 8px;
    max-width: none;
    margin-top: 11px;
    padding: 0;
    filter: none;
  }

  .offers-body .of-banner__code {
    min-height: 38px;
    gap: 8px;
    padding: 4px 12px;
    border: 1px solid #3A3B45;
    border-radius: 8px;
    background: #292A32;
  }

  .offers-body .of-banner__code-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1px;
    color: #D8D8D8;
  }

  /* The revised frame sets the code in the hero chip's face (Righteous),
     not Manrope. */
  .offers-body .of-banner__code strong {
    font-family: 'Righteous', sans-serif;
    font-size: 14px;
    font-weight: 400;
    letter-spacing: 0.6px;
  }

  .offers-body .of-banner .of-btn {
    min-height: 32px;
    padding: 6px 16px;
    font-size: 13px;
  }

  .offers-body .of-banner__terms {
    width: auto;
    max-width: none;
    font-family: 'Inter', sans-serif;
    font-size: 10px;
    line-height: 14px;
    text-align: center;
  }
}
