/* Twelve South LP shared styles
   Tokens extracted from the live theme CSS (base.css / custom.css / :root block),
   documented in Reference/ts-design-tokens.md. Do not substitute approximations.
   Fonts are the brand's own KMR-Waldenburg woff2 files served from the client's
   Shopify CDN (access-control-allow-origin: *, verified 2026-07-24), so there is
   no font file to re-host and no license transfer question.
   Brand rules honored here: media corners are square (--media-radius 0), only
   interactive controls are pills (100px). That tension is the real brand look. */

/* ---------- Fonts ---------- */
@font-face {
  font-family: 'KMR-Waldenburg-Normal';
  src: url('https://www.twelvesouth.com/cdn/shop/files/KMR-Waldenburg-Normal_c02848b0-d786-46ea-bb17-dcaf81d99446.woff2?v=1740807499') format('woff2');
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: 'KMR-Waldenburg-Buch';
  src: url('https://www.twelvesouth.com/cdn/shop/files/KMR-Waldenburg-Buch.woff2?v=1731315129') format('woff2');
  font-weight: 375;
  font-display: swap;
}
@font-face {
  font-family: 'KMR-Waldenburg-600';
  src: url('https://www.twelvesouth.com/cdn/shop/files/KMR-Waldenburg-Halbfett_60d72eff-7726-4743-91d5-449eb43aa1a2.woff2?v=1741712058') format('woff2');
  font-weight: 600;
  font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  --display: 'KMR-Waldenburg-Normal', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --body: 'KMR-Waldenburg-Buch', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --emph: 'KMR-Waldenburg-600', 'Helvetica Neue', Helvetica, Arial, sans-serif;

  --ink: #121713;
  --paper: #ffffff;
  --cream: #faf1e9;
  --brand: #ff360a;          /* logo-mark orange */
  --brand-ui: #ff4127;       /* --brand-color in theme */
  --brand-dark: #c01600;     /* hover/active */
  --forest: #445958;
  --border: #e2e2e2;
  --img-bg: #f2f2f2;

  --muted: #6d6e70;          /* 4.9:1 on white */
  --muted-cream: #5c5d5f;    /* 6.0:1 on cream, small text there uses this */

  --media-radius: 0px;
  --pill: 100px;
  --wrap: 1120px;
  --prose: 700px;
}

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--body);
  font-weight: 375;
  font-size: 17px;
  line-height: 1.7;
  letter-spacing: -0.2px;
  color: var(--ink);
  background: var(--paper);
}
img { max-width: 100%; height: auto; display: block; border-radius: var(--media-radius); background: var(--img-bg); }
a { color: var(--brand-ui); text-decoration: none; }
a:hover { color: var(--brand-dark); text-decoration: underline; }
strong, b { font-family: var(--emph); font-weight: 600; }
:focus-visible { outline: 3px solid var(--brand-ui); outline-offset: 3px; }

h1, h2, h3, h4 { font-family: var(--display); font-weight: 700; line-height: 1.2; letter-spacing: -0.6px; margin: 0 0 .5em; }
h1 { font-size: clamp(30px, 5.4vw, 52px); }
h2 { font-size: clamp(24px, 3.4vw, 34px); }
h3 { font-size: clamp(18px, 2.1vw, 22px); }
p { margin: 0 0 1.1em; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }
.prose { max-width: var(--prose); margin-left: auto; margin-right: auto; }
.section { padding: clamp(48px, 7vw, 88px) 0; }
.section--cream { background: var(--cream); }
.section--cream .small, .section--cream .muted { color: var(--muted-cream); }
.section--ink { background: var(--ink); color: #fff; }
.section--ink h2, .section--ink h3 { color: #fff; }
.section--tight { padding: clamp(32px, 4vw, 52px) 0; }
.muted { color: var(--muted); }
.small { font-size: 14px; line-height: 1.6; }
.center { text-align: center; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Small uppercase text cannot carry #FF360A: measured 3.63:1 on white and
   3.25:1 on cream, under the 4.5:1 floor (contract rule 13). --brand-dark is
   the theme's own darker red and passes at 6.2:1 / 5.6:1. */
.eyebrow {
  display: inline-block; font-family: var(--emph); font-weight: 600;
  font-size: 12px; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--brand-dark); margin-bottom: 14px;
}
.section--ink .eyebrow { color: #ff7a5e; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 56px; padding: 12px 30px; border-radius: var(--pill);
  background: #000; color: #fff; border: 1px solid #000;
  font-family: var(--body); font-weight: 375; font-size: 16px; letter-spacing: -0.3px;
  cursor: pointer; text-align: center; transition: background .18s, color .18s;
}
.btn:hover { background: #fff; color: #000; text-decoration: none; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
/* White 16px label on #FF360A measured 3.63:1. The darker theme red passes
   at 6.2:1 and keeps the accent alive on the dark final-CTA band. */
.btn--brand { background: var(--brand-dark); border-color: var(--brand-dark); }
.btn--brand:hover { background: #fff; color: var(--brand-dark); border-color: var(--brand-dark); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn--ghost:hover { background: var(--ink); color: #fff; }
.btn--block { width: 100%; }
.btn--inline { min-height: 46px; padding: 8px 22px; font-size: 15px; }

/* ---------- Promo bar / header ---------- */
/* Flex-wrap, not a single inline run. Adjacent white-space:nowrap spans with no
   whitespace between the tags give the browser no break opportunity and were a
   measured 41px horizontal overflow at a 500px viewport. Each item stays nowrap
   so phrases never break mid-phrase; the bar wraps between items instead. */
.promo-bar {
  background: var(--ink); color: #fff; font-size: 13px; letter-spacing: .2px;
  padding: 9px 16px;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  row-gap: 2px;
}
.promo-bar span { white-space: nowrap; }
.promo-bar .dot { opacity: .45; margin: 0 8px; }
.promo-bar .promo-m { display: none; }
@media (max-width: 540px) {
  .promo-bar .dot, .promo-bar .promo-d { display: none; }
  .promo-bar .promo-m { display: inline; font-size: 12px; }
}

.site-header {
  position: sticky; top: 0; z-index: 40; background: rgba(255,255,255,.94);
  backdrop-filter: saturate(160%) blur(8px); border-bottom: 1px solid var(--border);
}
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 64px; }
/* Tap targets: 44px minimum (contract rule 13). The visual size of these links
   is unchanged; only the hit area grows via padding. */
.site-header .logo { display: flex; align-items: center; min-height: 44px; }
.site-header .logo img, .site-header .logo svg { height: 24px; width: auto; background: none; }
.site-nav { display: flex; align-items: center; gap: 6px; }
/* 0 2px padding left "FAQ" and "Shop" at 33-40px wide on iPad-size viewports
   (measured 2026-08-24, 1024px probe). 8px sides widens the hit area toward
   the 44px target; the gap shrinks by the same amount so the row reads the
   same. iPad is ~10% of AirFly spend at the account's highest device CTR. */
.site-nav a {
  color: var(--ink); font-size: 15px;
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 8px;
}
.site-nav a:hover { color: var(--brand-ui); text-decoration: none; }
.cart-btn {
  background: none; border: 1px solid var(--ink); border-radius: var(--pill);
  padding: 8px 18px; min-height: 44px; font-family: var(--body); font-size: 15px;
  color: var(--ink); cursor: pointer;
}
.cart-btn:hover { background: var(--ink); color: #fff; }
@media (max-width: 860px) { .site-nav a { display: none; } }

/* ---------- Article hero ---------- */
.article-hero { padding: clamp(36px, 5vw, 64px) 0 0; }
/* 15ch was too tight a measure for a 52px display face: it wrapped the H1 to
   four lines and pushed the hero CTA past an 844px-tall desktop fold. 21ch
   gives three lines and a more natural headline measure. */
.article-hero h1 { max-width: 21ch; }
.byline {
  font-size: 14px; color: var(--muted); display: flex; flex-wrap: wrap;
  align-items: center; gap: 8px; margin: 0 0 18px;
}
.byline .dot { opacity: .5; }
@media (max-width: 480px) { .byline span:nth-last-child(-n+2) { display: none; } }
.lede { font-size: clamp(18px, 2.1vw, 21px); line-height: 1.62; }
/* The hero shot is 1289x1200, near square. Forcing it into a 16/10 box left big
   empty cream margins either side. Constrain the plate instead and let the image
   keep its own ratio: reads as a deliberate centered product plate. */
.hero-media {
  margin: 28px auto 0; background: var(--cream);
  max-width: 660px; width: 100%;
}
.hero-media img { width: 100%; height: auto; background: var(--cream); }

/* Two kinds of in-article image, each framed on its own terms.
   --photo  = lifestyle, safe to crop, fills a 4/3 frame.
   --product = studio silo on white, must never crop, capped so a square shot
               does not become a 700px-tall block in the prose column. */
.reason-media--photo img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
/* --square keeps a 1:1 lifestyle plate uncropped where a 4/3 crop would cut
   the subject (the PremiumAudioAllDay seat-back shot, 2026-08-24). */
.reason-media--square img { aspect-ratio: 1 / 1; }
/* White, not cream: these are studio silos shot on white, so a cream frame
   showed mismatched bars either side of the capped image. */
.reason-media--product { background: #fff; }
.reason-media--product img {
  width: 100%; max-height: 460px; object-fit: contain; background: #fff;
}

/* stars */
.stars { display: inline-flex; gap: 2px; vertical-align: middle; }
.stars svg { width: 15px; height: 15px; fill: var(--brand); }
.rating-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 14px; color: var(--muted); }

/* trust pills = this page's key-facts line.
   The pre-CTA list is hidden under 560px so the primary CTA lands fully inside
   the first viewport (contract rule 14). Measured: at a true 375x844 viewport
   the pills above the CTA push it to top=851, 7px past the fold.
   2026-08-24: a second copy (.trust-pills--after) sits AFTER the hero CTA in
   the markup and shows ONLY under 560px, so the facts stay visible on phones
   (iPhone is 82% of AirFly ad spend) without costing the fold: the CTA bottom
   measured ~546px at 375x844 with the pills below it. Each viewport exposes
   exactly one of the two lists to the accessibility tree. */
.trust-pills { display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 0; padding: 0; list-style: none; }
.trust-pills--after { display: none; }
@media (max-width: 560px) {
  .trust-pills { display: none; }
  .trust-pills.trust-pills--after { display: flex; gap: 8px; margin: 16px 0 0; }
}
.trust-pills li {
  border: 1px solid var(--border); border-radius: var(--pill);
  padding: 7px 16px; font-size: 13px; color: var(--ink);
}

/* ---------- Press strip: REMOVED 2026-08-24 ---------- */
/* The 2026-08-04 pass had already cut the six quote cards to one unattributed
   line at the client's PR direction; the operator removed that last line on
   2026-08-24, so .press-bar and .press-line went with it. If press citation
   is ever cleared, the V1 markup backup and git history hold everything. */

/* ---------- Article body ---------- */
.article-body { padding: clamp(40px, 6vw, 72px) 0; }
.article-body h2 { margin-top: 0; }
.skip-ahead {
  margin: 28px 0; padding: 20px 22px; background: var(--cream);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px;
}
.skip-ahead p { margin: 0; font-size: 15px; }

/* padding-block, NOT the two-value shorthand: this element also carries .wrap,
   and 'padding: X 0' was silently zeroing .wrap's 20px side padding, running
   every reason's text edge-to-edge on phones. */
.reason { padding-block: clamp(34px, 5vw, 56px); border-top: 1px solid var(--border); }
.reason-head { display: flex; align-items: baseline; gap: 16px; margin-bottom: 6px; }
.reason-num {
  font-family: var(--display); font-weight: 700; font-size: clamp(38px, 6vw, 62px);
  line-height: 1; color: var(--brand); flex: none;
}
.reason-head h2 { margin: 0; }
.reason-media { margin: 22px 0; background: var(--cream); }
.pull-quote {
  margin: 24px 0; padding-left: 20px; border-left: 3px solid var(--brand);
  font-family: var(--display); font-weight: 700; font-size: clamp(19px, 2.4vw, 25px);
  line-height: 1.3; letter-spacing: -0.5px;
}
.steps { counter-reset: step; list-style: none; padding: 0; margin: 22px 0; }
.steps li {
  counter-increment: step; position: relative; padding: 0 0 14px 44px; font-size: 16px;
}
.steps li::before {
  content: counter(step); position: absolute; left: 0; top: 0;
  width: 28px; height: 28px; border-radius: 50%; background: var(--ink); color: #fff;
  font-family: var(--emph); font-weight: 600; font-size: 13px;
  display: flex; align-items: center; justify-content: center;
}
/* 2026-08-24, operator direction (second pass): the three steps render as a
   visual strip, one ICON tile per step with the oversized numeral. The first
   pass used product photos, but none of them actually depicted the steps, so
   icons replaced them: jack plug, Bluetooth pairing, play. Same list markup,
   same verbatim step text. Icons are aria-hidden; the words carry meaning.
   Stacks to one column under 560px so panels stay large for the 55+ reader. */
.steps--visual { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.steps--visual li { padding: 0; }
.steps--visual li::before {
  left: 10px; top: 10px; z-index: 1;
  width: 40px; height: 40px; font-size: 18px;
  background: var(--brand-dark);
}
.steps--visual .step-icon {
  position: relative; display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1; background: var(--cream); color: var(--ink);
}
.steps--visual .step-icon svg { width: 38%; height: 38%; max-width: 96px; }
.steps--visual .step-text { display: block; padding: 10px 2px 0; line-height: 1.5; }
@media (max-width: 560px) {
  .steps--visual { grid-template-columns: 1fr; gap: 20px; }
  .steps--visual .step-icon { aspect-ratio: 21 / 9; }
  .steps--visual .step-icon svg { height: 62%; }
}

/* what's in the box */
.box-grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: clamp(20px, 4vw, 44px); align-items: center; }
.box-list { list-style: none; padding: 0; margin: 0; }
.box-list li { padding: 12px 0; border-bottom: 1px solid var(--border); font-size: 16px; }
.box-list li:last-child { border-bottom: 0; }
@media (max-width: 760px) { .box-grid { grid-template-columns: 1fr; } }

/* ---------- Buy block ---------- */
.buy-block { background: var(--cream); }
.buy-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(24px, 4vw, 52px); align-items: start; }
@media (max-width: 860px) { .buy-grid { grid-template-columns: 1fr; } }
/* Must be pure white, not cream and not the default grey: the colorway PNGs are
   transparent and composite onto whatever sits behind them, while Black Ice is
   a JPEG with its own white background. White is the only fill where all eight
   look identical. */
.gallery-main { background: #fff; }
.gallery-main img { width: 100%; aspect-ratio: 1 / 1; object-fit: contain; background: #fff; }
.gallery-thumbs img { background: #fff; }
.gallery-thumbs { display: flex; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.gallery-thumbs button {
  padding: 0; border: 1px solid var(--border); background: #fff; cursor: pointer;
  width: 66px; height: 66px; border-radius: 0;
}
.gallery-thumbs button[aria-current="true"] { border-color: var(--ink); border-width: 2px; }
.gallery-thumbs img { width: 100%; height: 100%; object-fit: contain; }

.buy-panel h2 { margin-bottom: 4px; }
.buy-price { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 12px 0 4px; }
.buy-price .now { font-family: var(--display); font-weight: 700; font-size: 30px; letter-spacing: -0.6px; }
.buy-price .frame { font-size: 13px; color: var(--muted-cream); }
.selector { margin: 22px 0 8px; }
.selector-label { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.selector-label .lbl { font-family: var(--emph); font-weight: 600; font-size: 13px; letter-spacing: .6px; text-transform: uppercase; }
.selector-label .hint { font-size: 13px; color: var(--muted-cream); }
/* ---------- Colorway swatches (buy panel) ----------
   2026-08-04: replaced the name pills with PDP-style dots at the client's
   request. The old .pill / .pills rules went with them; nothing else used them.

   The dot carries no visible text, so the colorway name is exposed three other
   ways: the "Color: X" legend above, a title attribute for hover, and
   visually-hidden text inside each button. Never let this become colour-only. */
#colorWrap .lbl { text-transform: none; letter-spacing: 0; font-size: 15px; }
.swatches { display: flex; flex-wrap: wrap; gap: 2px; }
/* 44px button around a 28px dot. The padding is the tap target, which keeps the
   dots reading as the PDP's tight row while staying reachable on a phone. */
.swatch-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  border: 0; background: none; cursor: pointer; border-radius: 50%;
}
/* The border is what keeps White and Glacial White visible against cream. */
.swatch-dot {
  display: block; width: 28px; height: 28px; border-radius: 50%;
  background-size: cover; background-position: center;
  border: 1px solid rgba(0, 0, 0, .22);
}
/* Ring with a cream gap, because the buy block sits on --cream, not white. */
.swatch-btn[aria-checked="true"] .swatch-dot {
  box-shadow: 0 0 0 2px var(--cream), 0 0 0 4px var(--brand);
}
.swatch-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.swatch-btn[aria-disabled="true"] { opacity: .4; cursor: not-allowed; }

.tier-cards { display: grid; gap: 12px; margin: 20px 0; }
.tier-card {
  text-align: left; background: #fff; border: 1px solid #cfc4ba; border-radius: 0;
  padding: 16px 18px; cursor: pointer; font-family: var(--body); color: var(--ink);
  display: flex; justify-content: space-between; gap: 14px; align-items: flex-start;
}
.tier-card[aria-checked="true"] { border-color: var(--ink); border-width: 2px; }
.tier-card .tc-title { font-family: var(--emph); font-weight: 600; font-size: 16px; display: block; }
.tier-card .tc-sub { font-size: 13px; color: var(--muted-cream); display: block; margin-top: 3px; }
.tier-card .tc-price { font-family: var(--display); font-weight: 700; font-size: 18px; white-space: nowrap; }

.included { list-style: none; padding: 0; margin: 18px 0; font-size: 15px; }
.included li { padding: 7px 0 7px 26px; position: relative; }
.included li::before {
  content: ""; position: absolute; left: 0; top: 14px; width: 12px; height: 7px;
  border-left: 2px solid var(--brand); border-bottom: 2px solid var(--brand);
  transform: rotate(-45deg);
}
.atc-micro { font-size: 13px; color: var(--muted-cream); margin: 10px 0 0; text-align: center; }
.cross-sell { font-size: 14px; margin: 16px 0 0; padding-top: 16px; border-top: 1px solid var(--border); }

/* ---------- Stats ---------- */
.stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 28px; text-align: center; }
.stat .num { font-family: var(--display); font-weight: 700; font-size: clamp(28px, 4vw, 40px); line-height: 1.05; }
.stat .lbl { font-size: 13px; color: rgba(255,255,255,.78); margin-top: 6px; }

/* ---------- Reviews ---------- */
.reviews-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; }
/* Second grid of reviews behind the Read-more button (2026-08-24). [hidden]
   must win over display:grid or the attribute does nothing. */
.reviews-more { margin-top: 20px; }
.reviews-more[hidden] { display: none; }
.reviews-toggle { text-align: center; margin: 26px 0 0; }
.review-card { border: 1px solid var(--border); padding: 22px; background: #fff; }
.review-card p { font-size: 15px; }
.review-card .who { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--muted); margin-top: 14px; }
.avatar {
  width: 34px; height: 34px; border-radius: 50%; background: var(--cream); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--emph); font-weight: 600; font-size: 12px; flex: none;
}

/* ---------- Recap / FAQ ---------- */
.recap { background: var(--cream); padding: 26px 28px; }
.recap ul { margin: 0; padding-left: 20px; }
.recap li { margin-bottom: 8px; font-size: 16px; }
/* The 2026-07-30 content pass compressed the recap from five bullets to one
   paragraph, so the box has to hold a <p> as cleanly as it held a <ul>. */
.recap p { margin: 0; font-size: 16px; line-height: 1.7; }

.faq details { border-bottom: 1px solid var(--border); padding: 4px 0; }
.faq summary {
  cursor: pointer; padding: 18px 40px 18px 0; position: relative; list-style: none;
  font-family: var(--emph); font-weight: 600; font-size: 17px; min-height: 44px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 8px; top: 26px; width: 9px; height: 9px;
  border-right: 2px solid var(--ink); border-bottom: 2px solid var(--ink);
  transform: rotate(45deg); transition: transform .2s;
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq .answer { padding: 0 0 18px; font-size: 16px; }
.faq .answer p:last-child { margin-bottom: 0; }

/* ---------- Final CTA / footer ---------- */
.final-cta { background: var(--ink); color: #fff; text-align: center; }
.final-cta .lede { color: rgba(255,255,255,.82); }
.final-cta .rating-line { color: rgba(255,255,255,.78); justify-content: center; }

.site-footer { background: #fff; border-top: 1px solid var(--border); padding: 40px 0; font-size: 14px; color: var(--muted); }
.site-footer .cols { display: flex; flex-wrap: wrap; gap: 18px 40px; justify-content: space-between; }
.site-footer a { color: var(--muted); display: inline-flex; align-items: center; min-height: 44px; text-decoration: underline; }
.site-footer a:hover { color: var(--brand-dark); }

/* Hero CTA row (contract rule 14: primary CTA inside the first viewport) */
.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin: 24px 0 0; }
.cta-row .btn { flex: 0 1 auto; }
@media (max-width: 420px) { .cta-row .btn { width: 100%; } }

/* ---------- Sticky mobile CTA ---------- */
.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  background: rgba(255,255,255,.97); border-top: 1px solid var(--border);
  padding: 10px 16px; display: flex; align-items: center; gap: 12px;
  transform: translateY(110%); transition: transform .25s;
}
.sticky-cta.show { transform: translateY(0); }
.sticky-cta .st-copy { flex: 1; min-width: 0; }
.sticky-cta .st-title { font-size: 13px; line-height: 1.3; }
.sticky-cta .st-price { font-family: var(--emph); font-weight: 600; font-size: 15px; }
.sticky-cta .btn { min-height: 46px; padding: 8px 20px; font-size: 15px; }
@media (min-width: 861px) { .sticky-cta { display: none; } }

/* ---------- Cart drawer ---------- */
.cart-overlay {
  position: fixed; inset: 0; background: rgba(18,23,19,.5); z-index: 60;
  opacity: 0; visibility: hidden; transition: opacity .2s, visibility .2s;
}
/* visibility must flip to visible IMMEDIATELY on open, otherwise the drawer is
   not focusable when open() runs and focus silently stays on <body>, breaking
   the focus trap (contract rule 12). Verified by probe. So: no duration on
   visibility when opening, and a delay equal to the slide when closing, which
   keeps the slide-out animation while still removing it from the a11y tree. */
.cart-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(420px, 100%);
  background: #fff; z-index: 61; display: flex; flex-direction: column;
  transform: translateX(100%); visibility: hidden;
  transition: transform .26s, visibility 0s linear .26s;
}
body.cart-open .cart-overlay { opacity: 1; visibility: visible; transition: opacity .2s, visibility 0s; }
body.cart-open .cart-drawer {
  transform: translateX(0); visibility: visible;
  transition: transform .26s, visibility 0s;
}
body.cart-open { overflow: hidden; }
.cart-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px; border-bottom: 1px solid var(--border); }
.cart-head h2 { margin: 0; font-size: 20px; }
.cart-close { background: none; border: 0; font-size: 26px; line-height: 1; cursor: pointer; color: var(--ink); min-width: 44px; min-height: 44px; }
.cart-items { flex: 1; overflow-y: auto; padding: 8px 20px; }
.cart-item { display: flex; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--border); }
.cart-item img { width: 70px; height: 70px; object-fit: contain; background: var(--cream); flex: none; }
.ci-title { font-family: var(--emph); font-weight: 600; font-size: 15px; }
.ci-sub { font-size: 13px; color: var(--muted); }
.ci-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; }
.qty { display: inline-flex; align-items: center; border: 1px solid var(--border); border-radius: var(--pill); }
.qty button { background: none; border: 0; width: 34px; height: 34px; font-size: 16px; cursor: pointer; color: var(--ink); }
.qty span { min-width: 22px; text-align: center; font-size: 14px; }
.ci-remove { background: none; border: 0; padding: 0; font-size: 13px; color: var(--muted); text-decoration: underline; cursor: pointer; }
.cart-empty { color: var(--muted); font-size: 15px; padding: 28px 0; }
.cart-foot { border-top: 1px solid var(--border); padding: 18px 20px; }
.cart-total-row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.cart-total-row .t { font-family: var(--emph); font-weight: 600; }
.cart-note { font-size: 12px; color: var(--muted); margin: 0 0 14px; }
.cart-trust { font-size: 12px; color: var(--muted); text-align: center; margin: 10px 0 0; }

/* ---------- UGC showcase (2026-08-24) ---------- */
/* Top UGC ad videos, self-hosted 9:16. preload=none + posters keep the page
   light: ~50KB of posters up front, video bytes only on tap. Square corners
   per the brand's media-radius rule. Native controls, sound on, no autoplay:
   these are testimonials, not ambience. */
.ugc-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 14px; margin-top: 28px;
}
.ugc-grid video {
  width: 100%; height: auto; aspect-ratio: 9 / 16; object-fit: cover;
  display: block; background: var(--ink); border-radius: var(--media-radius);
}

/* ---------- Trust marquee ---------- */
.marquee { overflow: hidden; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); padding: 16px 0; background: #fff; }
.marquee-track { display: flex; gap: 44px; width: max-content; animation: slide 34s linear infinite; }
.marquee-track span { font-size: 13px; letter-spacing: 1.1px; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
  .marquee-track { animation: none; }
}

/* ---------- Draft banner (review build only, remove before launch) ---------- */
.draft-bar {
  background: var(--brand-dark); color: #fff; text-align: center;
  padding: 10px 18px; font-size: 13px; line-height: 1.45;
}
.draft-bar strong { font-family: var(--emph); font-weight: 600; letter-spacing: .3px; }
.draft-bar .draft-sub { opacity: 1; }
@media (max-width: 620px) { .draft-bar { font-size: 12px; } }
@media (max-width: 540px) { .draft-bar .draft-mid { display: none; } }

/* ---------- Colorway showcase: REMOVED 2026-08-06 ----------
   The whole "See what's inside" section came out at the client's request, so
   .color-grid, .color-swatch, .cs-name, .cs-tag and .color-note went with it.

   One rule here was NOT just showcase styling and has been deleted on purpose:
       .buy-block { padding-bottom: clamp(26px, 3vw, 40px); }
   It trimmed the buy block's bottom padding because the showcase sat directly
   under it and was also cream, so the two stacked paddings read as one void.
   The buy block now meets the white article body instead, so it needs its full
   section padding back. Do not reinstate that override unless a cream section
   is put back immediately below the buy block. */

/* ---------- Mini comparison table (reason 4) ---------- */
/* The ARMRA-style consolidation block, done in Twelve South's register: an
   honest, observational comparison, no fear column, no red X marks.
   Three columns as of the 2026-07-30 content pass: the wired headset, seat-back
   Bluetooth, and yours with AirFly. Both alternatives read muted; only the
   product column carries full ink and the cream field. */
.mini-compare-wrap { margin: 26px 0 0; overflow-x: auto; }
.mini-compare { width: 100%; border-collapse: collapse; font-size: 15px; }
.mini-compare caption {
  caption-side: top; text-align: left; padding: 0 0 12px;
  font-family: var(--emph); font-weight: 600; font-size: 12px;
  letter-spacing: 1.1px; text-transform: uppercase; color: var(--muted);
}
.mini-compare th, .mini-compare td { padding: 12px 14px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
/* Check/cross emoji before each value (2026-08-24, operator direction).
   aria-hidden in the markup; screen readers get the words alone. */
.mini-compare .mark { margin-right: 7px; font-size: 13px; }
.mini-compare thead th {
  font-family: var(--emph); font-weight: 600; font-size: 12px;
  letter-spacing: .8px; text-transform: uppercase; border-bottom: 2px solid var(--ink);
}
.mini-compare tbody th { font-family: var(--emph); font-weight: 600; white-space: nowrap; }
.mini-compare td:last-child { color: var(--ink); }
.mini-compare tbody td:not(:last-child) { color: var(--muted); }
/* Under 560px the three-column grid measured 13px type in 81px columns with
   109px-tall cells (375px probe, 2026-08-24): legal, but too dense for the
   55+ reader who is 68% of AirFly purchases. Each feature row becomes its own
   card; the column headers repeat inside every cell via data-col (set in the
   page markup) so no value loses its label, and nothing drops below 14px.
   The thead is clip-hidden, not display:none, so its text stays available to
   assistive tech while the visual layout is the cards. */
@media (max-width: 560px) {
  .mini-compare thead {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); border: 0;
  }
  .mini-compare, .mini-compare caption, .mini-compare tbody,
  .mini-compare tr, .mini-compare tbody th, .mini-compare td { display: block; }
  .mini-compare tr { border: 1px solid var(--border); background: #fff; margin: 0 0 14px; padding: 2px 16px 0; }
  .mini-compare tbody th { white-space: normal; font-size: 16px; padding: 12px 0 10px; border-bottom: 1px solid var(--border); }
  .mini-compare td { border-bottom: 0; padding: 10px 0 0; font-size: 15px; }
  .mini-compare td::before {
    content: attr(data-col); display: block;
    font-family: var(--emph); font-weight: 600; font-size: 11px;
    letter-spacing: .8px; text-transform: uppercase; color: var(--muted);
  }
  .mini-compare td:last-child { margin: 12px -16px 0; padding: 10px 16px 12px; }
}

/* ---------- Deluxe band ---------- */
/* Two prongs were a full numbered reason in V1 and got demoted to a compact
   band in the 2026-07-30 pass. Headline beside the paragraph, not above a
   section: it has to read as an aside, not as a sixth reason. */
.deluxe-band { display: grid; grid-template-columns: minmax(0, 22ch) minmax(0, 1fr); gap: 12px 40px; align-items: start; }
.deluxe-band h2 { margin: 0; font-size: clamp(20px, 2.4vw, 26px); }
.deluxe-band p { margin: 0; max-width: 62ch; }
@media (max-width: 700px) { .deluxe-band { grid-template-columns: 1fr; } }

/* Product column emphasis on the mini comparison (the reference page highlights
   its product column; ours gets a quiet cream field, not a hype treatment) */
.mini-compare td:last-child, .mini-compare thead th:last-child { background: var(--cream); }
