/* ============================================================================
   Home band 3 — markets.  Figma 930:99482 (1082 x 1370), the BOTTOM half of
   930:99202 "option 9". The top half is a competing pricing table and is not
   built. Full extraction in MARKETS-BAND-SPEC.md.

   Four rules this band lives or dies by:

   - fx.py's gradient angles are derived from Figma's handle vector WITHOUT
     correcting for the box aspect ratio. On the 1082x205 promo box that is
     71 degrees wrong. Every gradient here was re-derived AND then fitted
     against the reference export; where the two disagreed, the pixels won.
     See spec 2.

   - Eleven gradients, three blend modes and one GLASS effect are gone
     entirely: every static surface (4 card backgrounds, the promo chrome)
     ships as a flat 2x WebP rendered by Figma itself from a throwaway clone.
     Exact by construction, and it also disposes of ten CROP/STRETCH image
     transforms and a dozen visible:false art layers.

   - No element carries both backdrop-filter and mix-blend-mode. Chrome
     composites that pair as an opaque frosted plate. Every gradient border is
     drawn with the padding-box/content-box mask-composite technique, and the
     two paints that genuinely needed HARD_LIGHT / OVERLAY are pre-composited
     to solid colours instead (spec 2.3).

   - Figma y offsets are gaps or absolute positions, never padding. Fixed
     Figma widths are `width`, never `max-width`: 1082 / 457 / 423 / 400 all
     collapse to their content otherwise.

   The 50% discount is read from LAB.OFF (assets/pricing-table.js) at runtime
   by atlas-markets.js. It is never a literal. The promo code "NEW" IS drawn
   in this frame and is the CEO's confirmed code for it -- note that LAB.CODE
   is 'WC50', so the two intentionally disagree; do not "fix" one to the other
   without checkout sign-off.

   The Crypto card ships INERT: no crypto destination exists in this repo, so
   it has no href, carries aria-disabled, and gets no hover or press
   affordance. Do not invent a URL.
   ========================================================================= */

/* 930:99202 is padded 200/40/120/40 with a gap of 100 before this band, and
   the page gradient has already run out to a flat #0F0F0F by y 1400, so the
   band sits on flat shell-bottom rather than on any part of the ramp.
   isolation keeps the ribbon's plus-lighter blend off the band above. */
.afxm {
  position: relative; overflow: hidden; isolation: isolate;
  padding: 100px 0 120px;
  background: var(--af-shell-bottom);
}

/* ---- ambient art ---------------------------------------------------------
   Two siblings of 930:99482 in 930:99202 paint UNDER it and overlap the band.
   Rendering the band isolated and in situ and differencing the two showed
   peak deltas of 211/255 and 216/255, so they are in scope. Both hang off a
   centred 1512 box -- they are full-bleed against the frame, not the 1082
   content column (coin 2 sits entirely outside it). */
.afxm__art {
  position: absolute; left: 50%; top: 100px; margin-left: -756px;
  width: 1512px; height: 1370px; pointer-events: none;
}
/* 930:99203 -- group opacity .06 over a LINEAR_DODGE child, i.e. additive.
   Exported over black so the file IS the additive contribution; plus-lighter
   then adds it. Stored lossless: peak value is 15/255 and lossy WebP at that
   amplitude errs by 8/255, which bands visibly.
   DECLARED DEVIATION: the group actually starts 380px above this band and
   runs up through the out-of-scope pricing table. Clipping it flush would
   leave a visible horizontal seam, and the band above is already shipped, so
   it is faded in over the first 64px instead. */
.afxm__ribbon {
  position: absolute; left: 0; top: 0; width: 1512px; height: 740px;
  background: url('/assets/figma/markets-ribbon.webp') no-repeat 0 0 / 1512px 740px;
  mix-blend-mode: plus-lighter;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 64px);
          mask-image: linear-gradient(180deg, transparent 0, #000 64px);
}
/* 930:99276 / 77 / 78 -- three rotated CROP-filled coins. Cropped to their
   alpha bounds off the composited plate, so these offsets are measured, not
   the node AABBs. Coin 3 is deliberately half-hidden by the promo box. */
.afxm__coin { position: absolute; display: block; }
.afxm__coin--1 { left: 1137.5px; top: 28px;    width: 109.5px; height: 150px; }
.afxm__coin--2 { left: 107px;    top: 278.5px; width: 95.5px;  height: 135px; }
.afxm__coin--3 { left: 709.5px;  top: 1124px;  width: 89.5px;  height: 91.5px; }

/* ---- 930:99482 — band, 1082x1370, column, gap 60, align CENTER ---------- */
.afxm__inner { position: relative; width: 1082px; margin: 0 auto; }
.afxm__band { display: flex; flex-direction: column; align-items: center; gap: 60px; }
/* 930:99483 — 1082x1105, column, gap 40, align CENTER */
.afxm__markets { display: flex; flex-direction: column; align-items: center; gap: 40px; width: 100%; }

/* ---- 930:99484 — heading block, 457x209, column, gap 16 ----------------- */
.afxm__head { display: flex; flex-direction: column; align-items: center; gap: 16px; width: 457px; }

/* 930:99485 — 159x33, radius 57, padding 6 14, gap 7. Its fill, its OVERLAY
   gradient stroke and its BACKGROUND_BLUR are ALL visible:false, so it ships
   bare. Padding and radius stay so the box still measures 159x33. The hidden
   chrome is structurally identical to the visible chrome on 930:99573, so it
   is almost certainly a hover state -- but this is not a control, so no
   hover is wired up. */
.afxm__eyebrow { margin: 0; display: inline-flex; align-items: center; gap: 7px; padding: 6px 14px; border-radius: 57px; }
.afxm__eyebrow img { width: 16px; height: 16px; display: block; flex: none; }
/* 930:99494 — 14/21px, ls -3%, textCase TITLE */
.afxm__eyebrow span {
  font-family: var(--font-sans); font-weight: var(--w-medium);
  font-size: 14px; line-height: 21px; letter-spacing: -.42px;
  text-transform: capitalize; color: var(--af-white);
}

/* 930:99495 — 457x160, column, gap 0. Two 80px lines at 100% leading, so the
   pair is a solid 160 block with no gap between them. */
.afxm__h2 { margin: 0; display: flex; flex-direction: column; width: 457px; }
.afxm__h2 > span {
  display: block; width: 100%; text-align: center;
  font-family: var(--font-display); font-weight: var(--w-medium);
  font-size: 80px; line-height: 80px; letter-spacing: -2.4px;
}
/* 930:99496 — two stacked opaque gradient fills; fills[0] is the BOTTOM one,
   so only fills[1] (#F8F8F8 -> #636363) renders. Do not stack both.
   MEASURED off the reference export (7k glyph-interior pixels, fit rms 2.5).
   The handle projection says 118.7deg and fx.py says 162.2deg; both are
   wrong. 154.2/33.2/93.1 independently agrees with the already-shipped
   pricing band's identical treatment (atlas-pricing.css:98). */
.afxm__h2l1 {
  background: linear-gradient(154.2deg, #F8F8F8 33.2%, #636363 93.1%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
/* 930:99497 — flat #FFFFFF */
.afxm__h2l2 { color: var(--af-white); }

/* ---- 930:99498 — card grid, 1082x856, column, gap 16 -------------------- */
.afxm__grid { display: flex; flex-direction: column; gap: 16px; width: 1082px; }
/* 930:99499 / 930:99531 — rows, gap 16, align CENTER. 400 + 16 + 666 = 1082 */
.afxm__row { display: flex; flex-direction: row; align-items: center; gap: 16px; width: 100%; }

/* ---- cards -------------------------------------------------------------
   layoutMode NONE, so the header row is absolutely positioned, not padded.
   The background is the baked 2x export of the whole card: fill, gradient,
   every art layer, and (Crypto) its three stacked strokes. background-size
   is 100% 100% because the transforms are already applied at export time --
   `cover` would zoom and darken the art. */
.afxm-card {
  position: relative; box-sizing: border-box; height: 420px;
  border-radius: var(--r-32); overflow: hidden;
  background-repeat: no-repeat; background-position: 0 0; background-size: 100% 100%;
}
/* FIXED 400 in Figma: `width`, never `max-width` */
.afxm-card--sm { width: 400px; flex: none; }
/* FILL / layoutGrow 1 -> 666 at 1512 */
.afxm-card--lg { flex: 1 1 auto; min-width: 0; }

.afxm-card--forex  { background-image: url('/assets/figma/markets-card-forex.webp'); }
.afxm-card--futures{ background-image: url('/assets/figma/markets-card-futures.webp'); }
.afxm-card--preds  { background-image: url('/assets/figma/markets-card-predictions.webp'); }
.afxm-card--crypto { background-image: url('/assets/figma/markets-card-crypto.webp'); }

/* 930:99508 / 21 / 50 / 66 — header row, inset 24 from the card's top-left,
   height 48, SPACE_BETWEEN, align CENTER. left+right 24 gives 352 on the
   400 cards and 618 on the 666 cards, which is what Figma reports. */
.afxm-card__head {
  position: absolute; left: 24px; top: 24px; right: 24px; height: 48px;
  display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: 24px;
}
/* 930:99509 / 22 / 51 / 67 — 32/38.4px, ls -3%. TWO-TONE: getStyledTextSegments
   splits every title into "Trade  " in #FFFFFF and the market name in
   #E1FFA0. Both spaces after "Trade" are real and the reference shows the
   wider gap, so white-space:pre keeps them -- HTML would collapse them. */
.afxm-card__title {
  margin: 0; white-space: pre;
  font-family: var(--font-display); font-weight: var(--w-semi);
  font-size: 32px; line-height: 38.4px; letter-spacing: -.96px;
  color: var(--af-white);
}
.afxm-card__title span { color: var(--af-lime); }

/* 930:99510 / 23 / 52 / 68 — 67.2x48, radius 100, padding 12 24, gap 8.
   The "Get Funded" label inside every one of these is visible:false, so the
   content is the 19.2x24 chevron slot alone and 24+19.2+24 = 67.2. They are
   icon-only; the label ships visually hidden so the control still has a name. */
.afxm-card__btn {
  position: relative; box-sizing: border-box; flex: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 67.2px; height: 48px; padding: 12px 24px;
  border: 0; border-radius: var(--r-pill); text-decoration: none;
  background: var(--w-04); color: var(--af-white);
  /* BACKGROUND_BLUR 74 -> Figma radius is ~2x the CSS value */
  -webkit-backdrop-filter: blur(37px); backdrop-filter: blur(37px);
}
/* 1.5px INSIDE gradient stroke. Its blendMode is HARD_LIGHT, but hard-light
   with a pure white source resolves to white, so a normal-blended white is
   exact here and no mix-blend-mode is needed -- which matters, because this
   element also carries backdrop-filter. */
.afxm-card__btn::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px;
  background: linear-gradient(155.1deg, rgba(255,255,255,.04) 15.5%, rgba(255,255,255,.011) 63.8%, rgba(255,255,255,.04) 109.4%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude; pointer-events: none;
}
/* 930:99512 — 19.2x24 slot holding a 24x24 chevron that overhangs it by 2.4
   each side. Both are centred on the same point, so centring reproduces it. */
.afxm-card__chev { position: relative; display: block; width: 19.2px; height: 24px; flex: none; }
.afxm-card__chev svg { position: absolute; left: 50%; top: 50%; width: 24px; height: 24px; margin: -12px 0 0 -12px; display: block; }

/* 930:99568 — Crypto only: the primary variant. Lime fill, ink label, and the
   drop shadow that is visible:false on the three ghost buttons.
   Ink is set explicitly: never inherit a link colour onto lime. Note
   --af-lime-ink in atlas-tokens.css is #17301F, a different colour used by an
   older band; the node JSON here says #001D21, which is --af-ink-teal. */
.afxm-card--crypto .afxm-card__btn {
  background: var(--af-lime); color: var(--af-ink-teal);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  box-shadow: 2px 14px 24.1px 0 rgba(38,63,66,.12);
}
/* HARD_LIGHT #053F3B over #E1FFA0 pre-composites to rgb(9,126,74); the paint
   opacity ramp .6 / .162 / .6 is kept. Solving the blend instead of applying
   it keeps mix-blend-mode off the element entirely. */
.afxm-card--crypto .afxm-card__btn::after {
  background: linear-gradient(155.1deg, rgba(9,126,74,.6) 15.5%, rgba(9,126,74,.162) 63.8%, rgba(9,126,74,.6) 109.4%);
}

/* ---- 930:99572 — promo box, 1082x205, column, gap 16, padding 24, r 32 ---
   Background is the baked export: the 187.8deg fill (MEASURED; fx.py says
   225.2 and the handle projection says 259.3, both wrong), all three stacked
   2px strokes, and the GLASS plate 930:99577 that highlights "Get 50% off".
   GLASS has no CSS equivalent, so baking is the only exact route. */
.afxm__promo {
  box-sizing: border-box; width: 1082px; padding: 24px;
  border-radius: var(--r-32); overflow: hidden;
  display: flex; flex-direction: column; align-items: flex-start; gap: 16px;
  background: url('/assets/figma/markets-promo-bg.webp') no-repeat 0 0 / 100% 100%;
}
/* 930:99573 — 128x32, r 57, padding 6 16, fill lime .12, 1px OVERLAY stroke,
   BACKGROUND_BLUR 16.7 -> blur(8.35px). This node carries a backdrop filter
   AND a blended stroke, so the stroke is pre-composited to a solid instead:
   OVERLAY #E1FFA0 over the 12% lime fill over the box resolves to
   rgb(113,135,70). */
.afxm__pill {
  position: relative; margin: 0; box-sizing: border-box;
  display: inline-flex; align-items: center; gap: 7px; height: 32px; padding: 6px 16px;
  border-radius: 57px; background: rgba(225,255,160,.12);
  -webkit-backdrop-filter: blur(8.35px); backdrop-filter: blur(8.35px);
}
.afxm__pill::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  background: linear-gradient(14.9deg, rgb(113,135,70) -175.3%, rgba(113,135,70,0) -63.9%, rgb(113,135,70) 29.5%, rgba(113,135,70,0) 198.3%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude; pointer-events: none;
}
/* 930:99574 — 14/20px, ls -1%, #E1FFA0 at node opacity .8 */
.afxm__pill span {
  font-family: var(--font-sans); font-weight: var(--w-medium);
  font-size: 14px; line-height: 20px; letter-spacing: -.14px;
  color: var(--af-lime); opacity: .8;
}

/* 930:99575 — 1034x109, row, gap 24, SPACE_BETWEEN, align CENTER */
.afxm__promorow {
  display: flex; flex-direction: row; align-items: center; justify-content: space-between;
  gap: 24px; width: 100%;
}
/* 930:99576 — 423x109, column, gap 12. Both text nodes are
   textAutoResize WIDTH_AND_HEIGHT, i.e. they HUG — 423 is the result of the
   longest line, not a constraint on it. So the column hugs too. */
.afxm__promoleft { display: flex; flex-direction: column; gap: 12px; width: auto; flex: none; }
/* 930:99578 — one TEXT node, hard newline, three runs: white / #E1FFA0 / white.
   nowrap because the only line break in the design is the explicit newline.
   DECLARED DEVIATION: line 2 measures 436.3px in the shipped SF Pro Display /
   Inter stack against Figma's 423 — 3.1% wider. Constrained to 423 it wraps
   to three lines and the promo box grows 39px. The extra width is invisible
   (the column is left-aligned and the row is SPACE_BETWEEN, so the CTA
   cluster does not move); a wrapped headline would not be. Letter-spacing is
   left at the design's -3% rather than being tightened to force the fit. */
.afxm__promohead {
  margin: 0; white-space: nowrap;
  font-family: var(--font-display); font-weight: var(--w-semi);
  font-size: 32px; line-height: 38.4px; letter-spacing: -.96px; color: var(--af-white);
}
.afxm__promohl { color: var(--af-lime); }
/* 930:99579 — 16/21.12px, rgba(255,255,255,.6) at node opacity .9. Hugs at
   286 in Figma; fit-content keeps the measured box on the text. */
.afxm__promosub {
  margin: 0; width: fit-content;
  font-family: var(--font-sans); font-weight: var(--w-regular);
  font-size: 16px; line-height: 21.12px; letter-spacing: -.48px;
  color: var(--w-60); opacity: .9;
}

/* 930:99580 — 342x48, row, gap 8.  159 + 8 + 175 = 342 */
.afxm__cta { display: flex; flex-direction: row; align-items: center; gap: 8px; flex: none; }

/* 930:99581 — 159x48, r 52, padding 12 16, gap 24, fill white .04, 1.5px
   OVERLAY stroke. No backdrop blur on this one.
   16 + (37 + 8 + 38) + 24 + 20 + 16 = 159.
   OVERLAY white over the promo background resolves to a 1.5x brightening of
   the backdrop; against the measured rgb(44) there that equals a normally
   blended white at .106 / .028. Solved rather than blended so the technique
   stays uniform across the band. */
.afxm__code {
  position: relative; box-sizing: border-box;
  display: inline-flex; align-items: center; gap: 24px;
  height: 48px; padding: 12px 16px; border: 0; border-radius: 52px;
  background: var(--w-04); cursor: pointer;
}
.afxm__code::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px;
  background: linear-gradient(132.3deg, rgba(255,255,255,.106) 36.6%, rgba(255,255,255,.028) 67.8%, rgba(255,255,255,.106) 97.2%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude; pointer-events: none;
}
/* 930:99582 — 83x24, row, gap 8 */
.afxm__codeinner { display: inline-flex; align-items: center; gap: 8px; }
/* 930:99583 — 14/24px, #FFFFFF at node opacity .5. The trailing space in
   "Code: " is part of the drawn string and carries its 37px width, so it is
   kept as an nbsp rather than being collapsed away. */
.afxm__codek {
  font-family: var(--font-sans); font-weight: var(--w-regular);
  font-size: 14px; line-height: 24px; letter-spacing: -.42px;
  color: var(--af-white); opacity: .5;
}
/* 930:99584 — 16/24px bold #E1FFA0 */
.afxm__codev {
  font-family: var(--font-sans); font-weight: var(--w-bold);
  font-size: 16px; line-height: 24px; letter-spacing: -.48px; color: var(--af-lime);
}
.afxm__code img { width: 20px; height: 20px; display: block; flex: none; }

/* 930:99591 — 175x48, r 100, padding 14 32, gap 8, lime, ink label, visible
   drop shadow. 32 + 87 + 8 + 16 + 32 = 175, held as a fixed width so font
   metrics cannot drift the box. */
.afxm__ctabtn {
  position: relative; box-sizing: border-box; flex: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 175px; height: 48px; padding: 14px 32px;
  border: 0; border-radius: var(--r-pill); text-decoration: none;
  background: var(--af-lime); color: var(--af-ink-teal);
  box-shadow: 2px 14px 24.1px 0 rgba(38,63,66,.12);
  font-family: var(--font-sans); font-weight: var(--w-semi);
  font-size: 16px; line-height: 19.09px; letter-spacing: -.48px; white-space: nowrap;
}
.afxm__ctabtn::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px;
  background: linear-gradient(129.6deg, rgba(9,126,74,.6) 38.3%, rgba(9,126,74,.162) 68.1%, rgba(9,126,74,.6) 96.3%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude; pointer-events: none;
}
/* I930:99591;194:75574 — 16x20 slot holding a 20x20 chevron */
.afxm__ctachev { position: relative; display: block; width: 16px; height: 20px; flex: none; }
.afxm__ctachev svg { position: absolute; left: 50%; top: 50%; width: 20px; height: 20px; margin: -10px 0 0 -10px; display: block; }

/* the card buttons are icon-only; their name lives here */
.afxm-vh {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}


/* ---- the whole card is the link ---------------------------------------
   Lucas, 5 Aug 2026: clicking anywhere on a market card should follow it,
   not just the 67px chevron button.

   TWO CSS-ONLY ATTEMPTS FAILED AND ARE WORTH RECORDING so nobody retries
   them. The "stretched link" pattern (absolute pseudo on the anchor, covering
   the card) resolves against the nearest POSITIONED ancestor, and there are
   two in the way:
     1. .afxm-card__btn was itself position:relative, to hang its 1.5px
        gradient stroke off ::after. Making it static fixes that, but then
     2. .afxm-card__head is position:absolute, straight from the Figma
        placement, so the overlay stretches to the HEAD instead of the card.
   Stretching the head to cover the card would move the drawn layout, which is
   not worth it for a hit area.

   So the anchor is left exactly as designed and the card forwards clicks to
   it in atlas-markets.js. That is pure ENHANCEMENT: the real link is still
   there, still focusable, still middle-clickable, still has its accessible
   name. Nothing is taken away if the JS never runs.
   ====================================================================== */
.afxm-card { cursor: pointer; }

/* Arrow nudges on hover, matching the 2px every other chevron on the site
   uses (.afxf__lime, .afxft__cta, .afxfm-cta and the rest). It triggers from
   the CARD, because the whole card is the target now. */
.afxm-card__chev { transition: transform var(--t-fast, .18s) var(--e-out, cubic-bezier(.22,.61,.36,1)); }

@media (prefers-reduced-motion: no-preference) {
  .afxm-card:hover .afxm-card__chev,
  .afxm-card__btn:focus-visible .afxm-card__chev { transform: translateX(2px); }
}

/* the focus ring belongs on the card now that the card is the hit area */
.afxm-card:focus-within { outline: 2px solid var(--af-lime); outline-offset: 3px; }


/* ============================================================================
   RESPONSIVE LAYER — added 18 Sep 2026.

   Everything above is the 1512 render and stays the source of truth. This file
   shipped with NO max-width query at all, and the band is built out of hard
   Figma widths: the 1082 column, the 400 Forex/Crypto cards, the 457 heading
   and the 1082 first-purchase box. Because .afxm is overflow:hidden, below
   ~1160 the band was silently CLIPPED rather than scrolled — on a 393 viewport
   the heading read "Tw", the Forex card ran off the right edge and the whole
   "First Purchase / Code: NEW" box was unreachable.

   930:99202 "option 9" has no mobile counterpart in Figma, so the 393 layout
   is not a port: it follows the idioms the why / steps / final bands already
   use on this page — 24px gutters, a 345 content column, the display face at
   42/42, and every fixed Figma box released to full width. If a mobile frame
   is ever drawn for this band, that frame wins over the numbers below.
   ========================================================================= */

/* ---- 1152: the 1082 column plus gutters no longer fits ------------------- */
@media (max-width: 1152px) {
  .afxm { padding: 88px 0 104px; }
  .afxm__inner {
    width: 100%; max-width: 1082px; margin: 0 auto;
    padding: 0 var(--gutter); box-sizing: border-box;
  }
  .afxm__head { width: 100%; max-width: 457px; }
  .afxm__h2 { width: 100%; }
  .afxm__grid { width: 100%; }
  /* the baked surface stretches horizontally only down to here, which the
     near-uniform fill absorbs; the GLASS highlight starts to drift below it
     and the box is rebuilt in CSS at 767. */
  .afxm__promo { width: 100%; }
}

/* ---- 860: 400 + 16 + 666 is gone; one card per row --------------------- */
@media (max-width: 860px) {
  .afxm__h2 > span { font-size: 56px; line-height: 58px; letter-spacing: -1.68px; }

  .afxm__row { flex-direction: column; align-items: stretch; }
  .afxm-card--sm { width: 100%; }
  .afxm-card--lg { flex: 0 0 auto; }
  .afxm-card { height: 380px; }

  /* 436 (headline) + 24 + 342 (cta cluster) = 802 exceeds the column here, so
     the SPACE_BETWEEN row becomes a stack and the drawn single line is
     released to wrap. */
  .afxm__promorow { flex-direction: column; align-items: flex-start; gap: 20px; }
  .afxm__promoleft { width: 100%; }
  .afxm__promohead { white-space: normal; }
}

/* ---- 767: mobile ------------------------------------------------------- */
@media (max-width: 767px) {
  .afxm { padding: 80px 0 96px; }
  .afxm__inner { max-width: none; padding: 0 24px; }

  /* The ribbon is full-bleed against the centred 1512 box and still reads at
     393, so it stays. The three coins are PLACED art at x 1137 / 107 / 709 in
     that same box: at 393 two of them land entirely outside the viewport and
     the third sits on top of the heading. Hidden rather than rescaled —
     scaling placed art moves it off its marks. */
  .afxm__coin { display: none; }

  .afxm__band { gap: 40px; }
  .afxm__markets { gap: 24px; }
  .afxm__head { width: 100%; gap: 12px; }
  .afxm__h2 > span { font-size: 42px; line-height: 42px; letter-spacing: -1.26px; }

  .afxm__grid { gap: 12px; }
  /* 420 is 43% of a 852 viewport; 300 keeps two cards visible at once. The
     card art is a baked 100% 100% background, so the aspect change squeezes
     it rather than cropping — intentional, it is an abstract render. */
  .afxm-card { height: 300px; border-radius: var(--r-24); }
  .afxm-card__head { left: 20px; top: 20px; right: 20px; height: 44px; gap: 12px; }
  .afxm-card__title { font-size: 24px; line-height: 28.8px; letter-spacing: -.72px; }
  .afxm-card__btn { width: 56px; height: 44px; padding: 10px 18px; }

  /* --- 930:99572, the first-purchase box -------------------------------
     DECLARED DEVIATION. The desktop surface is markets-promo-bg.webp, a
     baked 1082x205 export carrying the fill, all three stacked strokes and
     the GLASS plate that highlights "Get 50% off". Stretched to 345 x ~330
     (100% 100%, a 3.1x horizontal squeeze and a 1.6x vertical stretch) the
     GLASS smears into a bright band across the whole box and the strokes go
     anisotropic. So on mobile the image is dropped and the chrome is rebuilt:
     the measured fill ramp (rgb(29) at the edges to rgb(45) around 80%/30%)
     and the composited stroke colour rgb(66,68,60) sampled off that same
     export. No GLASS highlight — there is nowhere to put it once the
     headline wraps. */
  .afxm__promo {
    width: 100%; padding: 20px; gap: 14px; border-radius: var(--r-24);
    border: 1px solid #42443C;
    background:
      radial-gradient(130% 160% at 80% 30%, #2E2E2E 0%, #262626 52%, #1A1A1C 100%);
  }
  .afxm__promorow { flex-direction: column; align-items: stretch; gap: 18px; width: 100%; }
  .afxm__promoleft { width: 100%; gap: 8px; }
  .afxm__promohead { font-size: 26px; line-height: 31.2px; letter-spacing: -.78px; }
  .afxm__promosub { width: auto; font-size: 14px; line-height: 18.5px; letter-spacing: -.42px; }

  /* 159 + 8 + 175 = 342 against 305 of usable box width. Both children take
     an equal share of the row instead of their drawn widths, and both keep a
     48px height so the touch targets do not shrink. */
  .afxm__cta { width: 100%; gap: 8px; }
  .afxm__code {
    flex: 1 1 0; min-width: 0; justify-content: center;
    gap: 10px; padding: 12px 12px;
  }
  .afxm__codek { letter-spacing: -.3px; }
  .afxm__ctabtn { flex: 1 1 0; width: auto; min-width: 0; padding: 14px 16px; }
}

/* ---- 380 and below: the 345 column is gone too -------------------------- */
@media (max-width: 380px) {
  .afxm__inner { padding: 0 16px; }
  .afxm__h2 > span { font-size: 38px; line-height: 38px; letter-spacing: -1.14px; }
  .afxm__promohead { font-size: 24px; line-height: 29px; letter-spacing: -.72px; }
  /* below here the chip and the button genuinely cannot share a line */
  .afxm__cta { flex-direction: column; align-items: stretch; }
  .afxm__code, .afxm__ctabtn { flex: 0 0 auto; }
}
