/* Comparison page canon, synced from top-hebergeur 2026-07-05; bespoke
   overrides go in the page's own css. Copy to public/assets/{page-slug}/styles.css. */

:root {
  color-scheme: light;
  --ink: #101918;
  --muted: #5c6d68;
  --line: #dce6e2;
  --bg: #f6faf8;
  --panel: #ffffff;
  --soft: #edf5f1;
  --soft-2: #f9fcfb;
  --teal: #0b766f;
  --teal-dark: #075650;
  --teal-ink: #05443f;
  --coral: #d95f43;
  --gold: #d69b2d;
  --blue: #315c9a;
  --shadow: 0 20px 60px rgba(22, 33, 31, 0.12);
  --shadow-soft: 0 12px 34px rgba(22, 33, 31, 0.08);
  --shadow-card: 0 24px 70px rgba(22, 33, 31, 0.11);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background:
    linear-gradient(180deg, #ffffff 0%, var(--bg) 320px, #f4f8f6 100%);
  color: var(--ink);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  line-height: 1.5;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
}

img {
  display: block;
  max-width: 100%;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 74px;
  padding: 0 max(32px, calc((100vw - 1280px) / 2));
  background: rgba(255, 255, 255, 0.82);
  border-bottom: 1px solid rgba(217, 226, 223, 0.8);
  backdrop-filter: blur(22px) saturate(150%);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
  font-weight: 850;
  text-decoration: none;
}

.tool-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: var(--teal);
  color: #fff;
  font-size: 13px;
  font-weight: 800;
}

.brand-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
}

.nav {
  display: flex;
  gap: 6px;
  color: var(--muted);
  font-size: 14px;
  font-weight: 750;
}

.nav a {
  text-decoration: none;
}

.nav a {
  padding: 9px 12px;
  border-radius: 999px;
  transition: background 160ms ease, color 160ms ease;
}

.nav a:hover {
  color: var(--teal);
}

.nav a:hover {
  background: rgba(11, 118, 111, 0.08);
}

.hero {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(360px, 1.05fr);
  align-items: center;
  gap: 56px;
  min-height: 640px;
  padding: 56px 56px 44px;
  border-bottom: 1px solid var(--line);
}

.hero-copy,
.section {
  width: min(1180px, calc(100vw - 40px));
  margin: 0 auto;
}

.hero-copy {
  width: auto;
  margin: 0;
}

.eyebrow,
.card-kicker,
.fit-label {
  color: var(--teal);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: uppercase;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1 {
  max-width: 760px;
  margin-bottom: 20px;
  font-size: clamp(42px, 5.4vw, 70px);
  line-height: 0.96;
  letter-spacing: 0;
}

h2 {
  margin-bottom: 12px;
  font-size: 34px;
  line-height: 1.08;
  letter-spacing: 0;
}

h3 {
  margin-bottom: 10px;
  font-size: 22px;
  line-height: 1.18;
  letter-spacing: 0;
}

.hero-text {
  max-width: 690px;
  color: var(--muted);
  font-size: 20px;
}

.disclosure-inline {
  max-width: 720px;
  padding-left: 14px;
  border-left: 3px solid var(--gold);
  color: var(--muted);
  font-size: 14px;
}

.hero-actions,
.recommendation,
.tool-topline {
  display: flex;
  align-items: center;
}

.hero-actions {
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 28px;
}

.hero-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 22px;
}

.hero-strip a {
  display: block;
  min-height: 76px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  text-decoration: none;
}

.hero-strip strong,
.hero-strip span {
  display: block;
}

.hero-strip strong {
  margin-bottom: 4px;
  font-size: 13px;
}

.hero-strip span {
  color: var(--teal);
  font-weight: 900;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 0 18px;
  border: 1px solid transparent;
  border-radius: 8px;
  font-weight: 800;
  line-height: 1.15;
  text-align: center;
  text-decoration: none;
  box-shadow: 0 8px 18px rgba(22, 33, 31, 0.08);
  transition:
    transform 180ms ease,
    background 180ms ease,
    border 180ms ease,
    box-shadow 180ms ease,
    color 180ms ease;
}

.button:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 34px rgba(22, 33, 31, 0.16);
}

.button:active {
  transform: translateY(0);
  box-shadow: 0 6px 14px rgba(22, 33, 31, 0.12);
}

.button:focus-visible {
  outline: 3px solid rgba(11, 118, 111, 0.28);
  outline-offset: 3px;
}

.button.primary {
  background: var(--teal);
  color: #fff;
}

.button.primary:hover {
  background: var(--teal-dark);
  border-color: rgba(255, 255, 255, 0.2);
}

.button.secondary {
  border-color: var(--line);
  background: #fff;
  color: var(--ink);
}

.button.secondary:hover {
  border-color: rgba(11, 118, 111, 0.36);
  color: var(--teal);
}

.hero-visual {
  position: relative;
}

.hero-visual img {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.section {
  padding: 72px 0;
}

.article-layout {
  display: grid;
  grid-template-columns: 268px minmax(0, 936px);
  gap: 52px;
  width: min(1280px, calc(100vw - 48px));
  margin: 0 auto;
  padding: 62px 0 0;
}

.toc {
  position: sticky;
  top: 96px;
  align-self: start;
  max-height: calc(100vh - 120px);
  padding: 18px;
  overflow: auto;
  border: 1px solid rgba(217, 226, 223, 0.86);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.72);
  box-shadow: var(--shadow-soft);
  backdrop-filter: blur(18px);
}

.toc p {
  margin-bottom: 12px;
  color: var(--ink);
  font-size: 13px;
  font-weight: 900;
}

.toc a {
  display: block;
  padding: 9px 10px;
  border-bottom: 0;
  border-radius: 8px;
  color: var(--muted);
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  transition: background 150ms ease, color 150ms ease, transform 150ms ease;
}

/* is-active is the class the canon script actually sets (comparison-script.js,
   setupActiveToc). The stylesheet used to style .is-current, a name nothing ever
   emitted, so the scroll-following highlight was dead on every comparison page ever
   built, hand-written ones included. tests/canon-assets.test.ts now fails when a class
   the canon scripts toggle has no rule in the canon stylesheet. */
.toc a:hover,
.toc a.is-active,
.toc a.is-current {
  background: rgba(11, 118, 111, 0.08);
  color: var(--teal);
  transform: translateX(2px);
}

.toc a.is-active,
.toc a.is-current {
  background: var(--teal);
  color: #fff;
  box-shadow: 0 10px 24px rgba(11, 86, 80, 0.18);
}

.article {
  min-width: 0;
}

.article-hero {
  position: relative;
  padding: 30px 0 20px;
}

.article-hero + .product-entry {
  margin-top: 8px;
}

.article-hero h1 {
  max-width: 920px;
  margin-bottom: 16px;
  font-size: clamp(42px, 5.2vw, 68px);
  line-height: 0.98;
}

.article-hero .hero-text {
  max-width: 85%;
}

.intro-video {
  margin: -28px 0 76px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.intro-video-frame {
  overflow: hidden;
  border: 0;
  border-radius: 18px;
  background: transparent;
  box-shadow: none;
}

.intro-video-frame video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  clip-path: inset(2px 0 0 0 round 18px);
  background: #fff;
}

.product-entry {
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
  align-items: start;
  gap: 30px;
  margin: 26px 0;
  padding: 22px;
  border: 1px solid rgba(217, 226, 223, 0.9);
  border-radius: 18px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(250, 253, 252, 0.92));
  box-shadow: var(--shadow-soft);
  transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}

.product-entry:hover {
  transform: translateY(-2px);
  border-color: rgba(11, 118, 111, 0.28);
  box-shadow: var(--shadow-card);
}

.product-media {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 244px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background:
    linear-gradient(135deg, rgba(11, 118, 111, 0.12), rgba(217, 95, 67, 0.10)),
    #fff;
}

.product-media img,
.product-media video {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 244px;
  object-fit: cover;
  object-position: center;
  border-radius: 14px;
  transition: transform 240ms ease;
}
/* OPT-IN, default stays cover so existing full-bleed/lifestyle pages are UNTOUCHED.
   A page whose product-media are white-background product/tool renders (Amazon
   marketplace, hardware, logos) adds `is-contain` to its <main class="article-layout">.
   Then the whole render is CONTAINED, never cropped, identically at every breakpoint
   AND in the .test review carousel (.imgpick-shot mirrors it via review-images.js),
   so the picker is WYSIWYG with the shipped page. (D115) */
.is-contain .product-media img {
  object-fit: contain;
  padding: 14px;
  box-sizing: border-box;
}

/* PER-SITE OVERRIDES EXAMPLE (keep commented in the canon; the canon carries
   zero real product info). When one offer's image needs special treatment,
   add brand-scoped rules to the PAGE copy (public/assets/{page-slug}/styles.css)
   only, scoped by the offer slug id or image filename, e.g.:

#{offer-slug} .product-media {
  background:
    radial-gradient(circle at 50% 42%, rgba(255, 255, 255, 0.96), rgba(237, 245, 241, 0.88) 52%, rgba(11, 118, 111, 0.12));
}

#{offer-slug} .product-media img {
  object-position: center;
}

.recommendation-image[src$="{offer-slug}.webp"] {
  padding: 8px;
  background:
    radial-gradient(circle at 50% 42%, rgba(255, 255, 255, 0.96), rgba(237, 245, 241, 0.88) 52%, rgba(11, 118, 111, 0.12));
  object-fit: contain;
}
*/

.product-entry:hover .product-media img,
.product-entry:hover .product-media video {
  transform: scale(1.035);
}

/* Flex, not grid: the badge stays inline to the right of a short title, and
   auto-wraps to its own line below when the title is long enough that title +
   badge no longer fit on one row (content-driven, works for any title length,
   every site). */
.product-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 14px;
  row-gap: 14px;
  margin: 10px 0 16px;
}

.product-heading h2 {
  flex: 1 1 auto;
  margin-bottom: 0;
  font-size: 31px;
}

.product-copy {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

.product-copy p {
  color: var(--muted);
  font-size: 18px;
}

.best-for-badge {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  width: fit-content;
  min-height: 32px;
  margin: 0;
  padding: 0 12px;
  border: 1px solid rgba(11, 118, 111, 0.2);
  border-radius: 999px;
  background: rgba(11, 118, 111, 0.08);
  color: var(--teal-dark);
  font-size: 13px;
  font-weight: 900;
}

.feature-list {
  display: grid;
  gap: 10px;
  padding: 0;
  margin: 20px 0;
  list-style: none;
}

.feature-list li {
  position: relative;
  padding-left: 22px;
  color: var(--muted);
}

.feature-list li::before {
  content: "";
  position: absolute;
  top: 0.68em;
  left: 2px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 0 4px rgba(11, 118, 111, 0.1);
}

.feature-list strong {
  color: var(--ink);
}

.product-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  justify-content: flex-start;
  margin-top: 12px;
  padding-top: 8px;
  /* the note beside the button is a SENTENCE, and a real one runs long (a price, its
     size and the price it is down from). Held on one line it ran off the card and the
     reader lost the end of it: the row wraps, and the note wraps inside it. */
  flex-wrap: wrap;
}

.product-actions .button {
  min-width: 188px;
}

.incentive-note {
  color: var(--teal);
  font-size: 14px;
  font-weight: 650;
  text-decoration: none;
  /* Never nowrap: a long note must wrap inside the card, never overflow it. And the
     basis stays AUTO: on mobile the action row becomes a COLUMN, where a length basis
     is read as a HEIGHT, which padded 220px of dead space under every button. */
  flex: 1 1 auto;
  min-width: 0;
}

.incentive-note:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.article-section {
  padding: 64px 0;
  border-bottom: 1px solid var(--line);
}

.article-section > p {
  color: var(--muted);
}

.faq-section {
  border-bottom: 0;
}

.article-layout .disclosure-section {
  grid-column: 2;
  width: 100%;
}

.affiliate-note {
  grid-column: 2;
  padding: 22px 0;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 14px;
}

.affiliate-note p {
  margin-bottom: 0;
}

/* .plink is what OfferLinks::linkify() emits when it finds a merchant named in bare
   prose. It is the same thing as a hand-written product-name-link and must look like
   one, or a linked mention would read as body text on half the page. */
.product-name-link,
.plink {
  color: var(--teal);
  font-size: inherit;
  font-weight: 850;
  line-height: inherit;
  text-decoration: none;
  border-radius: 4px;
  box-shadow: inset 0 -2px 0 rgba(11, 118, 111, 0.18);
  transition: color 150ms ease, background 150ms ease, box-shadow 150ms ease;
}

.product-name-link:hover,
.plink:hover {
  color: var(--teal-dark);
  background: rgba(11, 118, 111, 0.08);
  box-shadow: inset 0 -2px 0 rgba(11, 118, 111, 0.36);
}

.product-heading h2 .product-name-link {
  display: inline-block;
  color: var(--teal);
  font-size: inherit;
  line-height: inherit;
}

.table-button {
  min-height: 38px;
  padding: 0 12px;
  background: var(--teal);
  color: #fff;
  font-size: 13px;
  min-width: max-content;
  white-space: nowrap;
  box-shadow: 0 6px 14px rgba(11, 86, 80, 0.12);
}

.table-button:hover {
  background: var(--teal-dark);
  box-shadow: 0 12px 22px rgba(11, 86, 80, 0.2);
}

.selected-recommendation {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr) auto;
  align-items: center;
  gap: 22px;
  margin-top: 22px;
  padding: 26px;
  border: 1px solid rgba(11, 118, 111, 0.32);
  border-radius: 18px;
  background:
    linear-gradient(180deg, rgba(237, 247, 244, 0.96), #ffffff);
  box-shadow: 0 18px 48px rgba(11, 86, 80, 0.14);
}

.selected-recommendation[hidden],
.selected-recommendation.is-hidden {
  display: none !important;
}

.recommendation-image {
  width: 100%;
  height: 132px;
  border: 1px solid var(--line);
  border-radius: 8px;
  object-fit: cover;
  object-position: center;
}

.recommendation-copy h3 {
  margin-bottom: 8px;
}

.selected-recommendation .button {
  min-width: 190px;
}

.section-heading {
  max-width: 740px;
  margin-bottom: 28px;
}

.section-heading p {
  color: var(--muted);
}

.selector-grid,
.tool-grid,
.note-grid,
.pick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

.selector-card,
.tool-card,
.pick-card,
.note,
.recommendation,
details {
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  box-shadow: 0 10px 30px rgba(22, 33, 31, 0.06);
}

.quick-picks {
  padding-top: 54px;
}

.pick-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 282px;
  padding: 24px;
}

.pick-card.featured {
  border-color: rgba(11, 118, 111, 0.5);
  background: linear-gradient(180deg, #ffffff 0%, #edf7f4 100%);
}

.rank {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  width: fit-content;
  min-height: 30px;
  padding: 0 10px;
  border-radius: 999px;
  background: var(--teal);
  color: #fff;
  font-size: 12px;
  font-weight: 900;
  box-shadow: 0 8px 18px rgba(11, 86, 80, 0.16);
}

.pick-card p {
  margin-bottom: auto;
  color: var(--muted);
}

.pick-card .button {
  width: 100%;
}

.selector-card {
  min-height: 164px;
  padding: 22px;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform 160ms ease, border-color 160ms ease, box-shadow 160ms ease, background 160ms ease;
}

.selector-card:hover {
  transform: translateY(-2px);
  border-color: rgba(11, 118, 111, 0.28);
  background: var(--soft-2);
  box-shadow: var(--shadow-soft);
}

.selector-card strong,
.selector-card span {
  display: block;
}

.selector-card strong {
  margin: 10px 0 8px;
  font-size: 20px;
  line-height: 1.2;
}

.selector-card span:last-child {
  color: var(--muted);
}

.selector-card.is-active {
  border-color: var(--teal);
  outline: 3px solid rgba(11, 118, 111, 0.12);
  background: linear-gradient(180deg, #ffffff, #f1f8f5);
}

.recommendation {
  justify-content: space-between;
  gap: 24px;
  margin-top: 16px;
  padding: 24px;
}

.recommendation p {
  max-width: 760px;
  margin-bottom: 0;
  color: var(--muted);
}

.table-wrap {
  overflow-x: auto;
  border: 1px solid rgba(217, 226, 223, 0.9);
  border-radius: 18px;
  background: #fff;
  box-shadow: var(--shadow-soft);
}

table {
  width: 100%;
  min-width: 760px;
  border-collapse: collapse;
}

th,
td {
  padding: 18px 20px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

th {
  background: #f1f7f4;
  font-size: 13px;
  color: var(--teal-ink);
  text-transform: uppercase;
}

tbody tr {
  transition: background 140ms ease;
}

tbody tr:hover {
  background: #fbfdfc;
}

tr:last-child td {
  border-bottom: 0;
}

.tool-card {
  padding: 24px;
}

.tool-topline {
  justify-content: space-between;
  margin-bottom: 18px;
}

.tool-card p,
.note p,
.faq-list p,
.disclosure-section p,
.step p {
  color: var(--muted);
}

.tool-card ul {
  padding-left: 18px;
  margin-bottom: 22px;
}

.tool-card li {
  margin-bottom: 8px;
}

.split-section,
.disclosure-section {
  display: grid;
  grid-template-columns: 0.7fr 1.3fr;
  gap: 40px;
  border-top: 1px solid var(--line);
}

.steps {
  display: grid;
  gap: 12px;
}

.step {
  display: grid;
  grid-template-columns: 42px 1fr;
  gap: 14px;
  align-items: start;
}

.step span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: var(--coral);
  color: #fff;
  font-weight: 900;
}

.note {
  padding: 22px;
}

.faq-list {
  display: grid;
  gap: 10px;
}

details {
  padding: 18px 20px;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}

details[open] {
  border-color: rgba(11, 118, 111, 0.26);
  box-shadow: var(--shadow-soft);
}

summary {
  cursor: pointer;
  font-weight: 800;
}

details p {
  margin: 12px 0 0;
}

.disclosure-section {
  border-bottom: 1px solid var(--line);
}

@media (max-width: 1180px) {
  .article-layout {
    grid-template-columns: 210px minmax(0, 1fr);
    gap: 32px;
    width: min(100% - 32px, 1080px);
  }

  .product-entry {
    grid-template-columns: 1fr;
    gap: 0;
    padding: 0;
    overflow: hidden;
  }

  .product-media {
    min-height: 0;
    /* stacked full-width: a portrait product shot in a 16/9 box crops the
       product badly, so use a moderate 4/3 box and CONTAIN the whole product
       (no crop) at a sane height instead of the natural, page-filling height. */
    aspect-ratio: 4 / 3;
    border-width: 0 0 1px;
    border-radius: 18px 18px 0 0;
  }

  .product-media img,
  .product-media video {
    min-height: 0;
    aspect-ratio: 4 / 3;
    object-fit: contain;
    border-radius: 18px 18px 0 0;
  }

  .product-copy {
    padding: 22px;
  }

  .product-heading {
    gap: 12px;
  }

  .best-for-badge {
    max-width: 34vw;
    text-align: center;
    white-space: normal;
  }

  .selected-recommendation {
    grid-template-columns: 220px minmax(0, 1fr);
    align-items: center;
    gap: 18px;
    grid-column: 1 / -1;
    border-left: 0;
    border-color: var(--line);
  }

  .selected-recommendation .button {
    grid-column: 2;
    width: fit-content;
  }

  .recommendation-image {
    height: auto;
    aspect-ratio: 16 / 9;
  }

  .table-wrap {
    overflow: visible;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  table,
  thead,
  tbody,
  tr,
  th,
  td {
    display: block;
    width: 100%;
    min-width: 0;
  }

  thead {
    display: none;
  }

  tbody {
    display: grid;
    gap: 12px;
  }

  tr {
    padding: 16px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: #fff;
    box-shadow: var(--shadow-soft);
  }

  /* The stacked cell keeps its label on the left and its value on the right, but the
     value must stay ONE inline flow: as a grid, every inline child of the cell became
     its own grid item, so a product name linked inside a sentence (the page script
     links them at runtime) was torn out of that sentence and dropped into the label
     column. The label is positioned instead, and the cell is a plain block. */
  td {
    display: block;
    position: relative;
    padding: 9px 0 9px 140px;
    border-bottom: 1px solid rgba(217, 226, 223, 0.72);
  }

  td::before {
    content: attr(data-label);
    position: absolute;
    top: 9px;
    left: 0;
    width: 128px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 850;
    text-transform: uppercase;
  }

  td:last-child {
    display: block;
    padding-left: 0;
    border-bottom: 0;
  }

  td:last-child::before {
    display: none;
  }

  .table-button {
    width: 100%;
  }
}

@media (max-width: 920px) {
  .site-header {
    position: static;
    min-height: 66px;
    padding: 0 20px;
  }

  .nav {
    display: none;
  }

  .article-layout {
    display: block;
    width: min(100% - 32px, 760px);
    padding-top: 24px;
  }

  .toc {
    display: none;
  }

  .product-entry {
    grid-template-columns: 1fr;
    gap: 0;
    margin: 18px 0;
    padding: 0;
    overflow: hidden;
    border-radius: 18px;
  }

  .intro-video {
    margin: -11px 0 49px;
    padding: 0;
  }

  .product-media {
    min-height: 0;
    aspect-ratio: 4 / 3;
    border-width: 0 0 1px;
    border-radius: 18px 18px 0 0;
  }

  .product-media img {
    min-height: 0;
    aspect-ratio: 4 / 3;
    object-fit: contain;
    border-radius: 18px 18px 0 0;
  }

  .product-media video {
    min-height: 0;
    aspect-ratio: 16 / 9;
    border-radius: 18px 18px 0 0;
  }

  .product-copy {
    padding: 18px 16px 16px;
  }

  .product-heading {
    gap: 10px;
  }

  .best-for-badge {
    max-width: 42vw;
    min-height: 30px;
    padding: 0 9px;
    font-size: 12px;
    font-weight: 750;
    line-height: 1.08;
    text-align: center;
    white-space: normal;
  }

  .product-actions {
    align-items: flex-start;
    flex-direction: column;
    gap: 8px;
  }

  .product-actions .button {
    width: 100%;
  }

  .incentive-note {
    align-self: center;
    margin-top: 4px;
    padding-left: 0;
    text-align: center;
  }

  .affiliate-note,
  .article-layout .disclosure-section {
    grid-column: auto;
  }

  .hero {
    grid-template-columns: 1fr;
    min-height: auto;
    padding: 52px 20px 36px;
  }

  .hero-visual {
    order: -1;
  }

  h1 {
    font-size: 42px;
    line-height: 1;
  }

  h2 {
    font-size: 29px;
  }

  .selector-grid,
  .tool-grid,
  .note-grid,
  .pick-grid,
  .split-section,
  .disclosure-section {
    grid-template-columns: 1fr;
  }

  .hero-strip {
    grid-template-columns: 1fr;
  }

  .recommendation {
    align-items: stretch;
    flex-direction: column;
  }

  /* The recommendation stacks: image, copy, button. The wider breakpoint pins the
     button to `grid-column: 2`, and that declaration does NOT stop applying here: the
     button kept demanding a second column, an implicit one was created beside the
     single 1fr track, and the image was squeezed into an 18px slice of it. A one-column
     grid has one column, so the button is placed automatically like everything else. */
  .selected-recommendation {
    grid-template-columns: 1fr;
    gap: 16px;
    border-left: 0;
    border-color: var(--line);
    padding: 18px;
  }

  .selected-recommendation .button {
    grid-column: auto;
    width: 100%;
  }

  .recommendation-image {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
  }
}

@media (max-width: 640px) {
  .brand span {
    font-size: 15px;
  }

  .brand-icon {
    width: 34px;
    height: 34px;
  }

  .article-layout {
    width: min(100% - 24px, 520px);
    padding-top: 18px;
  }

  .article-hero {
    padding: 20px 0 14px;
  }

  .article-hero h1 {
    font-size: 38px;
  }

  .article-hero .hero-text {
    max-width: none;
  }

  .hero-text {
    font-size: 17px;
  }

  .product-heading h2 {
    font-size: 28px;
  }

  .product-copy p {
    font-size: 16px;
  }

  .incentive-note {
    align-self: center;
    margin-top: 4px;
    padding-left: 0;
    text-align: center;
  }

  .affiliate-note {
    border-bottom: 0;
  }

  .article-section {
    padding: 42px 0;
  }

  .hero-actions .button,
  .recommendation .button,
  .tool-card .button,
  .pick-card .button,
  .table-button {
    width: 100%;
  }

  .section {
    padding: 54px 0;
  }

  .table-wrap {
    overflow: visible;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  table,
  thead,
  tbody,
  tr,
  th,
  td {
    display: block;
    width: 100%;
    min-width: 0;
  }

  thead {
    display: none;
  }

  tbody {
    display: grid;
    gap: 12px;
  }

  tr {
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: #fff;
    box-shadow: var(--shadow-soft);
  }

  /* Narrowest breakpoint: the label goes ABOVE its value, so the sentence gets the
     full width. The cell stays a plain block for the same reason as above: as a grid
     it tore an inline product link out of its sentence. */
  td {
    display: block;
    padding: 9px 0;
    border-bottom: 1px solid rgba(217, 226, 223, 0.72);
  }

  td::before {
    content: attr(data-label);
    /* resets the positioned label of the wider breakpoint: left as absolute it would
       print on top of the value */
    position: static;
    display: block;
    width: auto;
    margin-bottom: 4px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 850;
    text-transform: uppercase;
  }

  td:last-child {
    display: block;
    padding-bottom: 0;
    border-bottom: 0;
  }

  td:last-child::before {
    display: none;
  }

  .selector-grid {
    gap: 10px;
  }

  .selected-recommendation {
    margin-top: 10px;
    padding: 16px;
  }

  .selector-card {
    min-height: 0;
    padding: 16px;
  }

  .selector-card strong {
    font-size: 17px;
  }

}

/* --- Hosting: brand logo tiles in the product media slot --- */
.product-media {
  background: #fff;
}

.product-media img {
  object-fit: contain;
  padding: 16px;
}

.recommendation-image {
  object-fit: contain;
  background: #fff;
  padding: 8px;
}
