/* ══════════════════════════════════════════════════════════════════════════
   pages.css — layouts that belong to one template family.
   Home · hub (brand / category landing) · PDP · blog · content · contact ·
   search · 404.
   ══════════════════════════════════════════════════════════════════════════ */

/* ══ HOME ═════════════════════════════════════════════════════════════════ */
.tv-home-hero { padding-block: var(--tv-s-20); }
.tv-home-hero h1 {
  font-size: var(--tv-fs-h1-xl);
  font-weight: 800;
  line-height: var(--tv-lh-tight);
  letter-spacing: -0.03em;
  max-width: 16ch;
  margin: 14px 0 0;
}
/* The single italic word that breaks the headline's rhythm. */
.tv-home-hero h1 em { font-style: italic; color: var(--brand-ink); }
.tv-home-hero .tv-lede { max-width: 56ch; margin-top: 18px; }

.tv-home-search {
  display: flex; gap: 10px;
  max-width: 560px;
  margin-top: var(--tv-s-8);
}
.tv-home-search input {
  flex: 1; min-width: 0; height: 52px;
  border-radius: var(--tv-r-pill);
  border: 1px solid var(--tv-hair-2);
  background: var(--tv-glass);
  padding-inline: 22px;
  font: 500 15px var(--tv-font-body);
  color: var(--tv-ink);
}
.tv-home-search input::placeholder { color: var(--tv-ink-4); }
@media (max-width: 560px) {
  .tv-home-search { flex-direction: column; }
  .tv-home-search .tv-btn { width: 100%; }
}

.tv-home-hero .tv-chips { margin-top: var(--tv-s-6); }

/* ── Home carousel ───────────────────────────────────────────────────── */
.tv-home-slider {
  padding-top: var(--tv-s-4);
  padding-bottom: var(--tv-s-6);
  box-shadow: none;
}

/* The artwork is inset from the page edges rather than bleeding edge to edge. */
.tv-slider {
  position: relative;
  isolation: isolate;
  margin-inline: clamp(16px, 4vw, 48px);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: none;
}

.tv-slider-viewport {
  position: relative;
  height: clamp(300px, 40vw, 560px);
  overflow: hidden;
  border-radius: inherit;
  background: var(--tv-page-bg);
  box-shadow: none;
}

.tv-slide {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  opacity: 0;
  visibility: hidden;
}

.tv-slide.is-active { opacity: 1; visibility: visible; }

.tv-slide-media {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center center;
}

/* Whole-slide link. Sits above the artwork, below the controls. */
.tv-slide-hit {
  position: absolute;
  inset: 0;
  z-index: 2;
  cursor: pointer;
}

.tv-slide-hit:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -4px;
}

/* The copy lets clicks through to the link; only the button is a real target. */
.tv-slide-copy {
  position: relative;
  z-index: 3;
  width: 100%;
  padding-block: clamp(28px, 5vw, 72px);
  pointer-events: none;
}

/* The band is white; the copy that sits on the artwork keeps light ink. */
.tv-slide-copy,
.tv-slide-copy .tv-kicker { color: #fff; }
.tv-slide-copy .tv-lede { color: rgba(255, 255, 255, .9); }

.tv-slide-copy .tv-btn { pointer-events: auto; }

.tv-slide-title,
.tv-slide-copy .tv-lede { text-shadow: 0 1px 16px rgba(0,0,0,.45); }

.tv-slide-title {
  margin: 12px 0 0;
  font-family: var(--tv-font-display);
  font-size: clamp(28px, 4.4vw, 56px);
  font-weight: 800;
  line-height: var(--tv-lh-tight);
  letter-spacing: -0.03em;
  max-width: 22ch;
}

.tv-slide-title em { font-style: italic; color: var(--brand-ink); }

.tv-slide-copy .tv-lede { max-width: 52ch; margin-top: 14px; }
.tv-slide-copy .tv-btn { margin-top: var(--tv-s-6); }

/* Controls sit in the bottom band, clear of the copy on the left. */
.tv-slider-arrow {
  position: absolute;
  bottom: 18px;
  z-index: 4;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255,255,255,.35);
  border-radius: 50%;
  background: rgba(0,0,0,.32);
  color: #fff;
  cursor: pointer;
  transition: background .2s, border-color .2s;
}

.tv-slider-arrow:hover,
.tv-slider-arrow:focus-visible { background: rgba(0,0,0,.6); border-color: #fff; }

.tv-slider-arrow--prev { right: 76px; }
.tv-slider-arrow--next { right: 20px; }
.tv-slider-arrow--prev svg { transform: rotate(180deg); }

.tv-slider-dots {
  position: absolute;
  left: 20px;
  bottom: 30px;
  z-index: 4;
  display: flex;
  gap: 8px;
}

.tv-slider-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255,255,255,.45);
  cursor: pointer;
  transition: width .25s, background .25s;
}

.tv-slider-dot.is-active { width: 26px; border-radius: var(--tv-r-pill); background: var(--brand); }

@media (max-width: 720px) {
  .tv-slider-viewport { height: clamp(300px, 82vw, 440px); }
  /* Touch swipes, so the arrows would only eat the image. */
  .tv-slider-arrow { display: none; }
  .tv-slider-dots { bottom: 16px; }
  .tv-slide-copy { padding-bottom: 48px; }
}

@media (prefers-reduced-motion: reduce) {
  .tv-slide,
  .tv-slide-media { transition: none; }
  .tv-slide.is-active .tv-slide-media { transform: none; }
}

/* ── Home carousel — end ─────────────────────────────────────────────── */

.tv-home-sectop {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: var(--tv-s-6);
}
.tv-home-sectop h2 { margin: 0; }
.tv-home-sectop a { font-size: 14px; font-weight: 700; font-family: var(--tv-font-display); }

/* Loyalty / club call-out band. */
.tv-home-cta {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--tv-s-8); flex-wrap: wrap;
  padding: var(--tv-s-10);
  border-radius: var(--tv-r-xl);
  background: var(--brand-soft);
  border: 1px solid color-mix(in srgb, var(--brand) 24%, transparent);
}
/* The heading is set to land on exactly two lines: wide enough to hold
   "Get 15% off your first order", too narrow to hold the whole sentence.
   28ch does that at any font size, because ch scales with the type. */
.tv-home-cta h2 { font-size: var(--tv-fs-h2); max-width: 28ch; margin-top: 8px; }
.tv-home-cta p { font-size: 15px; color: var(--tv-ink-2); max-width: 52ch; margin-top: 10px; }

/* ══ HUB — brand & category landing pages ════════════════════════════════ */
.tv-hub-hero {
  position: relative;
  padding-block: var(--tv-s-16);
  overflow: hidden;
  border-bottom: 1px solid var(--tv-hair);
}
/* Giant ghosted brand word behind the hero copy. */
.tv-bigword {
  position: absolute;
  right: -2%;
  bottom: -14%;
  font-family: var(--tv-font-display);
  font-weight: 900;
  font-size: clamp(120px, 20vw, 280px);
  line-height: .8;
  letter-spacing: -0.05em;
  color: color-mix(in srgb, var(--brand) 8%, transparent);
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
  z-index: 0;
}
.tv-hub-hero > .tv-wrap { position: relative; z-index: 1; }
/* A long tag name (e.g. "Best Replacement Pod Vapes") is some 1800px wide at the
   120px floor, so on a phone this became a wall of clipped letters behind the
   heading. It stands down at that size. */
@media (max-width: 760px) {
  .tv-bigword { display: none; }
}
.tv-hub-hero h1 { font-size: var(--tv-fs-h1); margin: 12px 0 0; }
.tv-hub-lede { font-size: var(--tv-fs-lead); line-height: var(--tv-lh-loose); color: var(--tv-ink-2); margin-top: 16px; }
.tv-hub-chips { margin-top: var(--tv-s-6); }

/* In-page jump nav under a hub hero. */
.tv-hub-jump { display: flex; gap: 8px; flex-wrap: wrap; margin-top: var(--tv-s-8); }
.tv-hub-jump a {
  display: inline-flex; align-items: center; height: 34px; padding-inline: 15px;
  border-radius: var(--tv-r-pill);
  border: 1px solid var(--tv-hair);
  background: var(--tv-glass);
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; font-weight: 700;
  color: var(--tv-ink-2);
}
.tv-hub-jump a:hover { border-color: var(--brand); color: var(--brand-ink); }

/* Count line under the hub H1 — replaces the excerpt when a hub page has none. */
.tv-hub-meta {
  margin-top: 14px;
  color: var(--tv-ink-4);
}

/* ── BRAND INDEX — letter column + tile grid ─────────────────────────────
   The letter takes its own column so a group costs one row instead of a
   full-width heading stacked on top of a grid. */
.tv-brand-group {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: var(--tv-s-6);
  align-items: start;
  padding-block: 26px;
  border-top: 1px solid var(--tv-hair);
  scroll-margin-top: 96px;
}
.tv-brand-group:first-of-type { border-top: 0; padding-top: 10px; }

.tv-brand-group-head { display: flex; flex-direction: column; gap: 2px; }
.tv-brand-letter {
  font-family: var(--tv-font-display);
  font-weight: 900;
  font-size: 44px;
  line-height: .86;
  letter-spacing: -0.045em;
  color: var(--tv-ink);
}
.tv-brand-group-n {
  font-family: var(--tv-font-mono);
  font-size: 9.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tv-ink-4);
  white-space: nowrap;
}

@media (max-width: 720px) {
  .tv-brand-group { grid-template-columns: 1fr; gap: 12px; padding-block: 20px; }
  .tv-brand-group-head { flex-direction: row; align-items: baseline; gap: 10px; }
  .tv-brand-letter { font-size: 26px; }
  .tv-brand-group-n { font-size: 9px; }
}

.tv-hub-section { padding-block: var(--tv-s-12); border-top: 1px solid var(--tv-hair); }
.tv-hub-section:first-of-type { border-top: 0; }

/* Shop toolbar — result count + sorting. */
.tv-shop-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: var(--tv-s-6);
  padding-bottom: var(--tv-s-4);
  border-bottom: 1px solid var(--tv-hair);
}
.tv-shop-count { font-family: var(--tv-font-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--tv-ink-3); }
.tv-shop-bar select {
  height: 40px; padding-inline: 14px;
  border-radius: var(--tv-r-pill);
  border: 1px solid var(--tv-hair-2);
  background: var(--tv-glass);
  font: 600 13.5px var(--tv-font-body);
  color: var(--tv-ink);
  cursor: pointer;
}

/* Sub-category pills on a brand hub. */
.tv-subcats { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: var(--tv-s-6); }
.tv-subcats a {
  display: inline-flex; align-items: center; gap: 7px;
  height: 34px; padding-inline: 15px;
  border-radius: var(--tv-r-pill);
  border: 1px solid var(--tv-hair);
  background: var(--tv-glass);
  font-size: 13px; font-weight: 600; color: var(--tv-ink-2);
}
.tv-subcats a:hover, .tv-subcats a.is-active { border-color: var(--brand); color: var(--brand-ink); background: var(--brand-soft); }
.tv-subcats .tv-num { font-family: var(--tv-font-mono); font-size: 10px; color: var(--tv-ink-3); }

/* ══ PDP — single product ════════════════════════════════════════════════ */
.tv-pdp-crumb {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding-block: var(--tv-s-5);
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--tv-ink-3);
}
.tv-pdp-crumb a { color: var(--tv-ink-3); }
.tv-pdp-crumb a:hover { color: var(--tv-ink); }
.tv-crumb-sep { color: var(--tv-ink-4); }

.tv-pdp-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: var(--tv-s-12);
  align-items: start;
  padding-bottom: var(--tv-s-12);
}
@media (max-width: 900px) { .tv-pdp-layout { grid-template-columns: 1fr; gap: var(--tv-s-8); } }

/* Gallery. */
.tv-pdp-gallery { position: sticky; top: 90px; }
@media (max-width: 900px) { .tv-pdp-gallery { position: static; } }
.tv-pdp-gallery-main {
  border-radius: var(--tv-r-lg);
  border: 1px solid var(--tv-hair);
  background: #fff;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
}
.tv-pdp-gallery-main img { width: 100%; height: 100%; object-fit: contain; padding: 24px; border-radius: 0; }
.tv-pdp-thumbs { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.tv-pdp-thumb {
  width: 72px; height: 72px;
  border-radius: var(--tv-r-sm);
  border: 1px solid var(--tv-hair);
  background: #fff;
  overflow: hidden; cursor: pointer;
  transition: border-color var(--tv-dur-fast);
}
.tv-pdp-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 6px; border-radius: 0; }
.tv-pdp-thumb.is-active, .tv-pdp-thumb:hover { border-color: var(--brand); }

/* Buy column. `min-width:0` stops a long product name or a wide Woo form
   from blowing out the grid track. */
.tv-pdp-buy { min-width: 0; }
.tv-pdp-brandkick { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
/* Product titles run long ("Geek Bar Pulse 2 Disposable Vape") and this one
   sits in the buy column, not across a full-width hero, so it steps down from
   the page-title token to the h2 rung. Uses the existing scale rather than a
   fixed size, so the 1024px and 640px breakpoints keep working untouched. */
.tv-pdp-h1 { font-size: var(--tv-fs-h2); letter-spacing: -0.025em; margin: 10px 0 0; }
.tv-pdp-lede { font-size: 16px; color: var(--tv-ink-2); line-height: var(--tv-lh-body); margin-top: 14px; max-width: 54ch; }

.tv-pdp-price-row { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-top: var(--tv-s-6); }
.tv-pdp-price { font-family: var(--tv-font-display); font-weight: 800; font-size: 38px; letter-spacing: -0.03em; color: var(--brand-ink); }
.tv-pdp-price-was { font-size: 19px; color: var(--tv-ink-4); text-decoration: line-through; }
.tv-pdp-pertag {
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--tv-ink-3);
}

/* Related links under the price. Text-only on purpose — the buy column is
   being scanned, and the full card grid already sits at the foot of the page. */
.tv-pdp-rel { margin-top: var(--tv-s-5); display: flex; flex-direction: column; gap: 7px; }
.tv-pdp-rel-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.tv-pdp-rel-label {
  flex: 0 0 auto;
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--tv-ink-3);
}
.tv-pdp-rel-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 14px; }
.tv-pdp-rel-list a { font-size: 13.5px; font-weight: 600; color: var(--tv-ink-2); }
.tv-pdp-rel-list a:hover { color: var(--brand-ink); }

.tv-pdp-specs { margin-top: var(--tv-s-6); }

/* Variation chips (flavour / colour). */
.tv-pdp-opt { margin-top: var(--tv-s-6); }
.tv-pdp-opt-label {
  display: flex; align-items: baseline; gap: 8px;
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--tv-ink-3);
  margin-bottom: 10px;
}
.tv-pdp-opt-selected { color: var(--tv-ink); font-family: var(--tv-font-body); font-size: 13px; letter-spacing: 0; text-transform: none; font-weight: 600; }
.tv-pdp-chip-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.tv-pdp-chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 36px; padding-inline: 14px;
  border-radius: var(--tv-r-pill);
  border: 1px solid var(--tv-hair-2);
  background: var(--tv-glass);
  font-size: 13.5px; font-weight: 600; color: var(--tv-ink-2);
  cursor: pointer;
  transition: border-color var(--tv-dur-fast), color var(--tv-dur-fast), background-color var(--tv-dur-fast);
}
button.tv-pdp-chip:hover { border-color: var(--tv-ink); color: var(--tv-ink); }
.tv-pdp-chip.is-active { border-color: var(--brand); background: var(--brand-soft); color: var(--brand-ink); }
.tv-pdp-chip[disabled], .tv-pdp-chip.is-out { opacity: .38; cursor: not-allowed; text-decoration: line-through; }
/* The flavour catalogue lower down lists chips as plain spans, not controls. */
span.tv-pdp-chip { cursor: default; }

/* Where chips are rendered, Woo's own <select> stays in the DOM so the form
   still submits, but the chips are the visible control. Scoped to
   .tv-has-chips so a product without chips keeps its normal dropdown. */
.tv-has-chips .variations,
.tv-has-chips .reset_variations { display: none; }

/* WPLoyalty prints its points message as the first child of #buy, which lands
   it directly under the flavour chips — .tv-pdp-opt carries a top margin only,
   so nothing was separating the two. Spaced here rather than on the chip block
   so the gap belongs to the message and disappears with it. The plugin's own
   inline padding and border are left alone. */
#buy .wlr-product-message { margin-top: var(--tv-s-6); }

/* Numbered section headings and jump-nav items (01, 02, …).
   base.css greys every .tv-mono inside a .tv-section-h, so the number needs
   the same two-class weight to keep the brand colour. */
.tv-section-h .tv-section-n { color: var(--brand-ink); font-weight: 700; }
.tv-pdp-nav-n { color: var(--tv-ink-4); margin-right: 6px; }
.tv-pdp-nav-links a:hover .tv-pdp-nav-n { color: var(--brand-ink); }

/* Quantity + add to cart. */
.tv-pdp-cta-row { display: flex; gap: 12px; margin-top: var(--tv-s-8); flex-wrap: wrap; }
.tv-pdp-qty {
  display: inline-flex; align-items: center;
  height: 52px;
  border: 1px solid var(--tv-hair-2);
  border-radius: var(--tv-r-pill);
  background: var(--tv-glass);
  overflow: hidden;
  flex: 0 0 auto;
}
.tv-pdp-qty button { width: 42px; height: 100%; font-size: 17px; color: var(--tv-ink-2); }
.tv-pdp-qty button:hover { background: var(--tv-paper-deep); color: var(--tv-ink); }
.tv-pdp-qty input {
  width: 44px; height: 100%; border: 0; background: none; text-align: center;
  font-family: var(--tv-font-display); font-weight: 700; font-size: 15px; color: var(--tv-ink);
  -moz-appearance: textfield;
}
.tv-pdp-qty input::-webkit-outer-spin-button,
.tv-pdp-qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.tv-pdp-add { flex: 1; min-width: 200px; }

/* Multi-buy price ladder. */
.tv-pdp-multibuy { margin-top: var(--tv-s-8); }
.tv-pdp-multibuy-h {
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--tv-ink-3);
  margin-bottom: 10px;
}
.tv-pdp-tiers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
@media (max-width: 480px) { .tv-pdp-tiers { grid-template-columns: 1fr; } }
.tv-pdp-tier {
  position: relative;
  display: flex; flex-direction: column; gap: 4px;
  padding: 14px;
  border-radius: var(--tv-r-md);
  border: 1px solid var(--tv-hair-2);
  background: var(--tv-glass);
  text-align: left;
  transition: border-color var(--tv-dur-fast), background-color var(--tv-dur-fast);
}
.tv-pdp-tier:hover, .tv-pdp-tier.is-active { border-color: var(--brand); background: var(--brand-soft); }
.tv-pdp-tier-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tv-pdp-tier-qty { font-family: var(--tv-font-display); font-weight: 800; font-size: 15px; color: var(--tv-ink); }
.tv-pdp-tier-flag {
  font-family: var(--tv-font-mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 7px; border-radius: var(--tv-r-pill);
  background: var(--brand); color: #fff;
}
.tv-pdp-tier-total { font-family: var(--tv-font-display); font-weight: 800; font-size: 19px; color: var(--brand-ink); }
.tv-pdp-tier-sub { font-size: 11.5px; color: var(--tv-ink-3); }

/* Trust bullets under the buy box. */
.tv-pdp-trust { list-style: none; margin: var(--tv-s-8) 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.tv-pdp-trust li { display: flex; align-items: flex-start; gap: 10px; font-size: 13.5px; color: var(--tv-ink-2); margin: 0; }
.tv-pdp-trust svg { flex: 0 0 auto; margin-top: 2px; color: var(--brand-ink); }

/* Sticky in-page section nav. */
.tv-pdp-nav {
  position: sticky; top: 68px;
  z-index: calc(var(--tv-z-sticky) - 1);
  background: var(--tv-paper);
  border-block: 1px solid var(--tv-hair);
}
.tv-pdp-nav-inner {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  height: 54px;
  overflow-x: auto;
}
.tv-pdp-nav-links { display: flex; gap: var(--tv-s-6); }
.tv-pdp-nav-links a {
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; font-weight: 700;
  color: var(--tv-ink-3); white-space: nowrap;
}
.tv-pdp-nav-links a:hover { color: var(--tv-ink); }

.tv-pdp-section { padding-block: var(--tv-s-12); border-top: 1px solid var(--tv-hair); }

/* Flavour catalogue on a PDP / flavour page. */
.tv-flavor-group { margin-bottom: var(--tv-s-8); }
.tv-flavor-group-label {
  display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 12px;
}
.tv-flavor-group-n { font-family: var(--tv-font-mono); font-size: 10px; color: var(--tv-ink-4); }
/* On the flavour catalogue the device name is a heading, not an inline label. */
h3.tv-flavor-group-label { font-size: var(--tv-fs-h4); }
h3.tv-flavor-group-label a { color: var(--tv-ink); }
h3.tv-flavor-group-label a:hover { color: var(--brand-ink); }

/* Flavour catalogue — the "flavors in stock" card grid. */
.tv-flavorgrid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
.tv-flavorcard {
  display: block;
  border-radius: var(--tv-r-md);
  border: 1px solid var(--tv-hair);
  background: var(--tv-glass);
  overflow: hidden;
  color: var(--tv-ink);
  transition: transform var(--tv-dur-base) var(--tv-ease),
              box-shadow var(--tv-dur-base) var(--tv-ease);
}
.tv-flavorcard:hover { transform: translateY(-3px); box-shadow: var(--tv-elev-2); color: var(--tv-ink); }
.tv-flavorcard-tile {
  position: relative;
  height: 96px;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  background:
    repeating-linear-gradient(135deg, color-mix(in srgb, var(--tv-ink) 5%, transparent) 0 1px, transparent 1px 9px),
    var(--brand-soft);
}
.tv-flavorcard-cap {
  position: absolute; bottom: 10px; left: 12px;
  font-family: var(--tv-font-mono); font-size: 10px;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--brand-ink); opacity: .5;
}
.tv-flavorcard-body { padding: 12px 13px 13px; }
.tv-flavorcard-body b {
  display: block;
  font-family: var(--tv-font-display); font-weight: 700;
  font-size: 13.5px; line-height: 1.15;
}
.tv-flavorcard-meta {
  margin-top: 5px;
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .04em; text-transform: uppercase; color: var(--tv-ink-3);
}
@media (max-width: 1024px) { .tv-flavorgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 640px) { .tv-flavorgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ══ BLOG & CONTENT ══════════════════════════════════════════════════════ */
.tv-page-hero { padding-block: var(--tv-s-16) var(--tv-s-10); border-bottom: 1px solid var(--tv-hair); }
.tv-page-hero h1 { max-width: 22ch; margin-top: 12px; }
.tv-page-hero .tv-lede { max-width: 62ch; margin-top: 16px; }

.tv-postgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--tv-s-6);
}
@media (max-width: 900px) { .tv-postgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .tv-postgrid { grid-template-columns: 1fr; } }

.tv-postcard {
  display: flex; flex-direction: column;
  border-radius: var(--tv-r-lg);
  border: 1px solid var(--tv-hair);
  background: var(--tv-glass);
  overflow: hidden;
  transition: transform var(--tv-dur-base) var(--tv-ease), box-shadow var(--tv-dur-base);
}
.tv-postcard:hover { transform: translateY(-3px); box-shadow: var(--tv-elev-2); }
.tv-postcard-media { aspect-ratio: 16 / 9; background: var(--tv-glass-deep); overflow: hidden; }
.tv-postcard-media img { width: 100%; height: 100%; object-fit: cover; border-radius: 0; }
.tv-postcard-body { padding: 20px 20px 22px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.tv-postcard h3 { font-size: 18px; line-height: 1.3; }
.tv-postcard h3 a { color: var(--tv-ink); }
.tv-postcard h3 a:hover { color: var(--brand-ink); }
.tv-postcard p { font-size: 14px; color: var(--tv-ink-3); line-height: 1.55; }
/* The link sits in the card's bottom-right corner: `margin-top: auto` pins it to
   the foot of the column, so it lines up across a row whatever the excerpts
   wrapped to. Sentence case, so the shared rule's uppercase and the wide
   tracking that exists to space uppercase mono glyphs are both turned off. */
.tv-postcard-cta {
  margin-top: auto;
  align-self: flex-end;
  text-transform: none;
  letter-spacing: 0;
}
.tv-post-meta {
  font-family: var(--tv-font-mono); font-size: 10px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--tv-ink-4);
  display: flex; gap: 10px; flex-wrap: wrap;
}

/* Single post. */
.tv-single-hero { padding-block: var(--tv-s-12) var(--tv-s-8); }
.tv-single-hero h1 { max-width: 24ch; margin-block: 14px; }
.tv-single-featured { margin-bottom: var(--tv-s-10); }
.tv-single-featured img { width: 100%; border-radius: var(--tv-r-lg); }
.tv-single-body { padding-bottom: var(--tv-s-16); }

.tv-share { display: flex; align-items: center; gap: 10px; margin-top: var(--tv-s-10); padding-top: var(--tv-s-6); border-top: 1px solid var(--tv-hair); }
.tv-share span { font-family: var(--tv-font-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--tv-ink-3); }

.tv-postnav { display: grid; grid-template-columns: 1fr 1fr; gap: var(--tv-s-4); margin-top: var(--tv-s-10); }
@media (max-width: 600px) { .tv-postnav { grid-template-columns: 1fr; } }
.tv-postnav a {
  padding: 18px 20px;
  border: 1px solid var(--tv-hair);
  border-radius: var(--tv-r-md);
  background: var(--tv-glass);
  display: flex; flex-direction: column; gap: 6px;
}
.tv-postnav a:hover { border-color: var(--tv-hair-2); }
.tv-postnav .tv-mono { color: var(--tv-ink-4); }
.tv-postnav strong { font-family: var(--tv-font-display); font-size: 15px; color: var(--tv-ink); line-height: 1.3; }
.tv-postnav .is-next { text-align: right; align-items: flex-end; }

/* ══ CONTACT ═════════════════════════════════════════════════════════════ */
.tv-contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  gap: var(--tv-s-12);
  align-items: start;
}
@media (max-width: 860px) { .tv-contact-layout { grid-template-columns: 1fr; gap: var(--tv-s-8); } }

.tv-form-row { margin-bottom: var(--tv-s-4); }
.tv-form-row label {
  display: block;
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--tv-ink-3);
  margin-bottom: 7px;
}
.tv-form-row input,
.tv-form-row select,
.tv-form-row textarea {
  width: 100%; height: 48px;
  border: 1px solid var(--tv-hair-2);
  border-radius: var(--tv-r-sm);
  background: var(--tv-paper);
  padding-inline: 14px;
  font: 500 15px var(--tv-font-body);
  color: var(--tv-ink);
}
.tv-form-row textarea { height: auto; padding: 12px 14px; line-height: 1.5; resize: vertical; min-height: 140px; }
.tv-form-row input:focus,
.tv-form-row select:focus,
.tv-form-row textarea:focus { outline: 2px solid var(--brand); outline-offset: -1px; border-color: transparent; }

.tv-infocard {
  padding: 24px;
  border: 1px solid var(--tv-hair);
  border-radius: var(--tv-r-lg);
  background: var(--tv-glass);
}
.tv-infocard + .tv-infocard { margin-top: var(--tv-s-4); }
.tv-infocard h3 { font-size: 16px; margin-bottom: 10px; }
.tv-infocard p, .tv-infocard address {
  font-size: 14px; color: var(--tv-ink-2); font-style: normal; line-height: 1.65;
}

/* ══ ORDER TRACKING ══════════════════════════════════════════════════════ */
.tv-trackcard {
  max-width: 780px;
  padding: clamp(24px, 4vw, 40px);
  border: 1px solid var(--tv-hair);
  border-radius: var(--tv-r-lg);
  background: var(--tv-glass);
}

/*
 * The lookup form is Woo's own markup. Only the arrangement is ours — the
 * fields, labels and Track button are styled by woocommerce.css, which the
 * shortcode's own `.woocommerce` wrapper already puts in scope.
 */
.tv-trackcard .woocommerce-form-track-order {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: var(--tv-s-4);
  margin: 0;
}
.tv-trackcard .woocommerce-form-track-order > p:first-of-type {
  grid-column: 1 / -1;
  font-size: 15px; color: var(--tv-ink-3); line-height: 1.6;
  max-width: 62ch; margin: 0 0 var(--tv-s-6);
}
.tv-trackcard .woocommerce-form-track-order > .form-row:not(.form-row-first):not(.form-row-last) { grid-column: 1 / -1; }
.tv-trackcard .woocommerce-form-track-order .form-row-first,
.tv-trackcard .woocommerce-form-track-order .form-row-last { float: none; width: 100%; }
.tv-trackcard .woocommerce-form-track-order .clear { display: none; }
@media (max-width: 620px) { .tv-trackcard .woocommerce-form-track-order { grid-template-columns: 1fr; } }

/* The lookup result arrives as Woo's info notice; its <mark>s would otherwise
   paint as highlighter yellow. */
.tv-trackcard .woocommerce-info { margin: var(--tv-s-6) 0 0; }
.tv-trackcard mark { background: none; color: var(--brand-ink); font-weight: 700; }
.tv-trackcard table { width: 100%; border-collapse: collapse; font-size: 14px; }

/* Six states as a two-column definition list. */
.tv-states { display: grid; gap: var(--tv-s-5) var(--tv-s-8); }
@media (min-width: 760px) { .tv-states { grid-template-columns: 1fr 1fr; } }
.tv-state { padding-top: var(--tv-s-3); border-top: 1px solid var(--tv-hair); }
.tv-state dt { font-family: var(--tv-font-display); font-weight: 700; font-size: 15.5px; letter-spacing: -0.01em; }
.tv-state dd { margin-top: 6px; font-size: 14.5px; color: var(--tv-ink-3); line-height: 1.6; }

.tv-track-help { padding-block: var(--tv-s-12); border-top: 1px solid var(--tv-hair); }
.tv-trackhelp {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--tv-s-4); flex-wrap: wrap;
  padding: var(--tv-s-6);
  border: 1px solid var(--tv-hair);
  border-radius: var(--tv-r-lg);
  background: var(--tv-glass);
}
.tv-trackhelp p { font-size: 15px; color: var(--tv-ink-2); max-width: 56ch; line-height: 1.55; }

/* ══ SEARCH & 404 ════════════════════════════════════════════════════════ */
.tv-searchform { display: flex; gap: 10px; max-width: 520px; }
.tv-searchform input[type="search"] {
  flex: 1; min-width: 0; height: 48px;
  border-radius: var(--tv-r-pill);
  border: 1px solid var(--tv-hair-2);
  background: var(--tv-glass);
  padding-inline: 20px;
  font: 500 15px var(--tv-font-body);
  color: var(--tv-ink);
}

.tv-empty { padding-block: var(--tv-s-16); text-align: center; }
.tv-empty h2 { margin-bottom: 12px; }
.tv-empty p { color: var(--tv-ink-3); max-width: 46ch; margin-inline: auto; margin-bottom: var(--tv-s-6); }

.tv-404 { padding-block: var(--tv-s-20); text-align: center; }
.tv-404-code {
  font-family: var(--tv-font-display); font-weight: 900;
  font-size: clamp(90px, 18vw, 200px); line-height: .85;
  letter-spacing: -0.05em;
  color: color-mix(in srgb, var(--brand) 16%, transparent);
}
.tv-404 h1 { margin-top: -12px; }
.tv-404 p { color: var(--tv-ink-3); max-width: 46ch; margin: 16px auto var(--tv-s-8); }

/* ══ ARCHIVE — breadcrumb, filter rail, editorial tail ════════════════════ */
.tv-crumbs {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-family: var(--tv-font-mono);
  font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--tv-ink-4);
}
.tv-crumbs a { color: var(--tv-ink-3); }
.tv-crumbs a:hover { color: var(--brand-ink); }
.tv-crumbs [aria-current] { color: var(--tv-ink-2); font-weight: 700; }
.tv-crumb-sep { opacity: .5; }

/* Rail + grid. The rail is a fixed column so card widths stay predictable
   from page to page; below 1024px it becomes a disclosure above the grid. */
.tv-shop-layout {
  display: grid;
  grid-template-columns: 236px minmax(0, 1fr);
  gap: var(--tv-s-8);
  align-items: start;
}
.tv-shop-layout--bare { grid-template-columns: minmax(0, 1fr); }
.tv-shop-main { min-width: 0; }

/* A rail narrows the cards, so step the grid down a breakpoint earlier than
   a full-width shop does. */
/* Upper bound only: below 760px the phone rule in components.css owns the
   grid, and this selector is specific enough to beat it if left unbounded. */
@media (min-width: 761px) and (max-width: 1440px) {
  .tv-shop-layout:not(.tv-shop-layout--bare) .tv-prod-grid {
    grid-template-columns: repeat(var(--tv-cols-md, 3), minmax(0, 1fr));
  }
}

.tv-shop-rail { position: sticky; top: 84px; /* 68px sticky header + 16px breathing room */ }
.tv-rail-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
  padding-bottom: var(--tv-s-4);
  border-bottom: 1px solid var(--tv-hair);
}
.tv-rail-head h2 {
  font-family: var(--tv-font-mono);
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--tv-ink-3); margin: 0;
}
.tv-rail-clear { font-size: 12px; color: var(--brand-ink); text-decoration: underline; }
.tv-rail-close {
  display: none;
  appearance: none; border: 0; background: none;
  padding: 4px; margin: -4px -4px -4px 0;
  color: var(--tv-ink-3); cursor: pointer;
}
.tv-rail-close:hover { color: var(--tv-ink); }

/* Each group is headed by a solid brand band. The hairline rules the groups
   used to be separated by are gone — two separators competing for the same
   job just adds noise. */
.tv-facet { margin-top: 10px; }
.tv-facet-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  padding: 11px 13px;
  border-radius: var(--tv-r-sm);
  background: var(--brand);
  color: #fff;
  cursor: pointer;
  list-style: none;
  font-family: var(--tv-font-display);
  font-weight: 700; font-size: 13.5px; letter-spacing: -0.005em;
}
.tv-facet-head::-webkit-details-marker { display: none; }
.tv-facet-head:hover { background: color-mix(in srgb, var(--brand) 88%, #000); }
/* --brand loses its footing on the Kiosk ground; --brand-2 is the pair that
   carries it there, the same swap .tv-btn--brand already makes. */
[data-theme="dark"] .tv-facet-head,
.tv-invert .tv-facet-head { background: var(--brand-2); color: var(--tv-on-accent); }
[data-theme="dark"] .tv-facet-head:hover,
.tv-invert .tv-facet-head:hover { background: color-mix(in srgb, var(--brand-2) 88%, #fff); }

/* + when closed, − when open. Two bars sharing a centre; the upright one
   collapses on its own axis, so the horizontal bar never moves. */
.tv-facet-sign {
  position: relative;
  flex: 0 0 11px; width: 11px; height: 11px;
}
.tv-facet-sign::before,
.tv-facet-sign::after {
  content: "";
  position: absolute;
  background: currentColor;
  border-radius: 1px;
  transition: transform var(--tv-dur-base) var(--tv-ease);
}
.tv-facet-sign::before { left: 0; top: 4.5px; width: 11px; height: 2px; }
.tv-facet-sign::after  { top: 0; left: 4.5px; width: 2px; height: 11px; }
.tv-facet[open] .tv-facet-sign::after { transform: scaleY(0); }

/* Options line up under the heading text, not under its padding edge. */
.tv-facet-list { list-style: none; margin: 0; padding: 10px 0 6px 13px; display: grid; gap: 2px; }
.tv-facet-opt {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 8px 6px 0;
  border-radius: var(--tv-r-sm);
  font-size: 13.5px; line-height: 1.3;
  color: var(--tv-ink-2);
}
.tv-facet-opt:hover { color: var(--brand-ink); }
.tv-facet-box {
  flex: 0 0 15px; width: 15px; height: 15px;
  border: 1px solid var(--tv-hair-2);
  border-radius: 4px;
  background: var(--tv-glass);
  position: relative;
  transition: background var(--tv-dur-fast), border-color var(--tv-dur-fast);
}
.tv-facet-opt:hover .tv-facet-box { border-color: var(--brand); }
.tv-facet-opt.is-on { color: var(--tv-ink); font-weight: 600; }
.tv-facet-opt.is-on .tv-facet-box { background: var(--brand); border-color: var(--brand); }
/* The tick is drawn rather than loaded — it is two borders on a rotated box. */
.tv-facet-opt.is-on .tv-facet-box::after {
  content: ""; position: absolute; left: 4.5px; top: 1px;
  width: 4px; height: 8px;
  border: solid #fff; border-width: 0 1.8px 1.8px 0;
  transform: rotate(43deg);
}
.tv-facet-label .amount { font-family: var(--tv-font-display); font-weight: 700; }

.tv-facet-toggle {
  appearance: none; background: none; border: 0;
  padding: 0 0 12px 13px; margin: -4px 0 0;
  font-family: var(--tv-font-mono);
  font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  font-weight: 700; color: var(--brand-ink);
  cursor: pointer;
}
.tv-facet-toggle:hover { text-decoration: underline; }

/* Applied filters, each one its own removal control. */
.tv-active-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: var(--tv-s-5); }
.tv-active-chip {
  display: inline-flex; align-items: center; gap: 7px;
  height: 30px; padding-inline: 12px;
  border-radius: var(--tv-r-pill);
  border: 1px solid color-mix(in srgb, var(--brand) 34%, transparent);
  background: var(--brand-soft);
  font-size: 12.5px; font-weight: 600;
  color: var(--brand-ink);
}
.tv-active-chip:hover { border-color: var(--brand); }
.tv-active-chip svg { opacity: .7; }

/* Mobile: the rail folds away behind the toolbar button. */
.tv-filter-btn { display: none; }
.tv-filter-n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding-inline: 5px; margin-left: 2px;
  border-radius: var(--tv-r-pill);
  background: var(--brand); color: #fff;
  font-family: var(--tv-font-mono); font-size: 10px; font-weight: 700;
}
@media (max-width: 1024px) {
  .tv-shop-layout { grid-template-columns: minmax(0, 1fr); gap: var(--tv-s-5); }

  /* In flow the rail can only sit before the toolbar or after the whole
     grid, and neither is where a panel opened from a button belongs. So on a
     phone it leaves the flow entirely and becomes a sheet, the same pattern
     the mini-cart already uses. */
  .tv-shop-rail { display: none; }
  .tv-shop-layout.is-filters-open .tv-shop-rail {
    display: block;
    position: fixed;
    inset: 0;
    z-index: var(--tv-z-modal, 90);
    margin: 0;
    padding: 16px var(--tv-pad-x) 40px;
    background: var(--tv-paper);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .tv-rail-close { display: inline-flex; }
  .tv-shop-layout.is-filters-open .tv-rail-head { position: sticky; top: 0; background: var(--tv-paper); padding-top: 4px; }
  .tv-filter-btn {
    display: inline-flex; align-items: center; gap: 7px;
    height: 40px; padding-inline: 16px;
    border-radius: var(--tv-r-pill);
    border: 1px solid var(--tv-hair-2);
    background: var(--tv-glass);
    font: 700 13px var(--tv-font-body);
    color: var(--tv-ink);
    cursor: pointer;
  }
  .tv-filter-btn[aria-expanded="true"] { border-color: var(--brand); color: var(--brand-ink); }
}

/* Long-form brand/category copy, moved below the grid. */
.tv-hub-about, .tv-hub-faq { padding-block: var(--tv-s-12); border-top: 1px solid var(--tv-hair); }
.tv-hub-about h2, .tv-hub-faq h2 { font-size: var(--tv-fs-h3); margin-bottom: var(--tv-s-4); }
.tv-hub-about .tv-prose > * + * { margin-top: 14px; }

/* ══ BRAND INDEX — the compliance note under the wall ═════════════════════ */
/* Full width, matching the brand grid above rather than the narrow prose
   band. The treatment is deliberately static: this is a nicotine warning, and
   animating it would trade legibility for decoration. */
.tv-brand-note { border-top: 0; padding-block: var(--tv-s-8) var(--tv-s-16); }

.tv-brand-note .tv-prose {
  position: relative;
  isolation: isolate;
  padding: var(--tv-s-8) var(--tv-s-10);
  border-radius: var(--tv-r-xl);
  border: 1px solid color-mix(in srgb, var(--brand) 26%, transparent);
  background:
    radial-gradient(120% 140% at 6% 0%, color-mix(in srgb, var(--brand) 15%, transparent) 0%, transparent 60%),
    linear-gradient(180deg, var(--brand-soft) 0%, color-mix(in srgb, var(--brand-soft) 40%, var(--tv-paper)) 100%);
  overflow: hidden;
}

/* Hazard stripes, barely there — a compliance notice earns the reference.
   Painted at z-index -1 inside the card's own stacking context, so it sits
   above the gradient and below the text. */
.tv-brand-note .tv-prose::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: repeating-linear-gradient(
    -45deg,
    color-mix(in srgb, var(--brand) 8%, transparent) 0 10px,
    transparent 10px 26px
  );
  /* Fades out across the card so the stripes never sit under the sentence. */
  -webkit-mask-image: linear-gradient(100deg, #000 0%, transparent 55%);
          mask-image: linear-gradient(100deg, #000 0%, transparent 55%);
}

.tv-brand-note .tv-prose > *:first-child { margin-top: 0; }
.tv-brand-note .tv-prose > *:last-child  { margin-bottom: 0; }
.tv-brand-note .tv-prose p { max-width: 92ch; }
.tv-brand-note .tv-prose strong { color: var(--brand-ink); }

@media (max-width: 640px) {
  .tv-brand-note .tv-prose { padding: var(--tv-s-6); border-radius: var(--tv-r-lg); }
}

/* The block editor happily saves an empty heading block; it rendered here as a
   blank line with full heading margins above the warning. */
.tv-prose :is(h1, h2, h3, h4, h5, h6):empty { display: none; }

/* --brand goes muddy on the Kiosk ground; --brand-2 is the pair that carries
   it there, the same swap .tv-btn--brand and .tv-facet-head already make. */
[data-theme="dark"] .tv-brand-note .tv-prose,
.tv-invert .tv-brand-note .tv-prose {
  border-color: color-mix(in srgb, var(--brand-2) 30%, transparent);
  background:
    radial-gradient(120% 140% at 6% 0%, color-mix(in srgb, var(--brand-2) 13%, transparent) 0%, transparent 60%),
    linear-gradient(180deg, var(--brand-soft) 0%, color-mix(in srgb, var(--brand-soft) 40%, var(--tv-paper)) 100%);
}
[data-theme="dark"] .tv-brand-note .tv-prose::before,
.tv-invert .tv-brand-note .tv-prose::before {
  background: repeating-linear-gradient(
    -45deg,
    color-mix(in srgb, var(--brand-2) 9%, transparent) 0 10px,
    transparent 10px 26px
  );
}

/* ── Best Vapes ranked list (/best-vapes/{slug}/) ───────────────────── */
.tv-best-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.tv-best-row {
  position: relative;
  display: grid;
  grid-template-columns: 56px 168px 1fr;
  align-items: center;
  gap: 22px;
  padding: 20px 24px;
  border-radius: var(--tv-r-lg);
  border: 1px solid var(--tv-hair);
  background: var(--tv-glass);
  transition: transform var(--tv-dur-base) var(--tv-ease),
              box-shadow var(--tv-dur-base) var(--tv-ease),
              border-color var(--tv-dur-base);
}
.tv-best-row:hover {
  transform: translateY(-2px);
  box-shadow: var(--tv-elev-2);
  border-color: var(--tv-hair-2);
}

.tv-best-rank {
  font-family: var(--tv-font-display);
  font-weight: 800;
  font-size: 30px;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--brand-ink);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.tv-best-media {
  display: block;
  width: 168px;
  aspect-ratio: 4 / 3;
  border-radius: var(--tv-r-md, 12px);
  background: #fff;
  overflow: hidden;
}
.tv-best-media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 10px;
  transition: transform var(--tv-dur-slow) var(--tv-ease);
}
.tv-best-row:hover .tv-best-media img { transform: scale(1.04); }

.tv-best-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.tv-best-brand {
  font-family: var(--tv-font-mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--brand-ink);
}

.tv-best-name {
  margin: 0;
  font-family: var(--tv-font-display);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.3;
  letter-spacing: -0.01em;
}
.tv-best-name a { color: var(--tv-ink); }
.tv-best-name a:hover { color: var(--brand-ink); }

.tv-best-pitch {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--tv-ink-3);
}

.tv-best-meta {
  font-family: var(--tv-font-mono);
  font-size: 12px;
  letter-spacing: .02em;
  color: var(--tv-ink-3);
}

.tv-best-foot {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 6px;
}

.tv-best-prices {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}
.tv-best-price {
  font-family: var(--tv-font-display);
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -0.02em;
  color: var(--brand-ink);
}
.tv-best-listprice {
  font-size: 13px;
  color: var(--tv-ink-3);
  text-decoration: line-through;
}

.tv-best-stock {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--tv-ink-3);
  white-space: nowrap;
}

.tv-best-cta {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  border-radius: var(--tv-r-pill);
  background: var(--brand);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}
.tv-best-cta svg { transition: transform var(--tv-dur-base) var(--tv-ease); }
.tv-best-cta:hover { color: #fff; }
.tv-best-cta:hover svg { transform: translateX(3px); }

@media (max-width: 760px) {
  /* The image used to share the rank's column, which is only 34px wide — a
     132px image overflowed it and collided with the copy beside it. It now owns
     its own row and the copy runs full width underneath. */
  .tv-best-row {
    grid-template-columns: 34px 1fr;
    grid-template-areas:
      "rank  media"
      "body  body";
    gap: 12px 14px;
    padding: 16px;
  }
  .tv-best-rank { grid-area: rank; font-size: 22px; text-align: left; }
  .tv-best-media { grid-area: media; width: 100%; max-width: 160px; }
  .tv-best-body { grid-area: body; }
  .tv-best-foot { flex-wrap: wrap; gap: 10px 14px; }
  .tv-best-cta { margin-left: 0; width: 100%; justify-content: center; }
}

/* ══ BRAND HUB — How to choose · Prices · Compare ════════════════════════ */
.tv-bh .tv-section-h { margin-bottom: var(--tv-s-6); }

/* How to choose: one card per recommendation. */
.tv-bh-choose {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--tv-s-4);
}
.tv-bh-pick {
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--tv-s-5);
  border-radius: var(--tv-r-lg);
  border: 1px solid var(--tv-hair);
  background: var(--tv-glass);
}
.tv-bh-want-k {
  font-family: var(--tv-font-mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--tv-ink-3);
}
.tv-bh-want { font-size: 15px; color: var(--tv-ink-2); line-height: 1.45; }
.tv-bh-arrow { color: var(--brand-ink); margin-top: 4px; }
.tv-bh-arrow svg { width: 16px; height: 16px; transform: rotate(90deg); }
.tv-bh-pick-name {
  font-family: var(--tv-font-display); font-weight: 800; font-size: 18px;
  letter-spacing: -0.01em; color: var(--tv-ink); line-height: 1.2;
}
.tv-bh-why { font-size: 13.5px; color: var(--tv-ink-3); line-height: 1.5; }
.tv-bh-note { grid-column: 1 / -1; color: var(--tv-ink-2); max-width: 72ch; margin: 0; }

.tv-bh-lede { color: var(--tv-ink-2); margin: calc(var(--tv-s-6) * -0.5) 0 var(--tv-s-5); max-width: 72ch; }
.tv-bh-lede .amount { font-family: var(--tv-font-display); font-weight: 700; color: var(--tv-ink); }

/* Tables scroll inside their own box on a narrow screen rather than widening
   the page; below 640px they reflow into stacked rows instead. */
.tv-bh-tablewrap {
  overflow-x: auto;
  border: 1px solid var(--tv-hair);
  border-radius: var(--tv-r-lg);
  background: var(--tv-glass);
}
.tv-bh-table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.tv-bh-table th, .tv-bh-table td {
  padding: 14px 18px;
  text-align: left;
  border-bottom: 1px solid var(--tv-hair);
  vertical-align: middle;
}
.tv-bh-table tbody tr:last-child > * { border-bottom: 0; }
.tv-bh-table thead th {
  font-family: var(--tv-font-mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--tv-ink-3);
  background: var(--tv-paper-deep);
  white-space: nowrap;
}
.tv-bh-table tbody th { font-weight: 600; }
.tv-bh-table tbody th a { color: var(--tv-ink); }
.tv-bh-table tbody th a:hover { color: var(--brand-ink); }
.tv-bh-table tbody tr:hover > * { background: var(--tv-paper-deep); }
.tv-bh-num { text-align: right !important; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tv-bh-price { font-family: var(--tv-font-display); font-weight: 800; color: var(--brand-ink); }
.tv-bh-was { margin-left: 6px; font-size: 12.5px; color: var(--tv-ink-4); }
.tv-bh-stock { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; color: var(--tv-ink-3); }
.tv-bh-stock.is-in { color: var(--tv-ink-2); }
.tv-bh-na { color: var(--tv-ink-4); }
.tv-bh-foot { margin-top: var(--tv-s-3); font-size: 12.5px; color: var(--tv-ink-3); }

@media (max-width: 640px) {
  .tv-bh-tablewrap { overflow: visible; border: 0; background: none; }
  .tv-bh-table thead { display: none; }
  .tv-bh-table, .tv-bh-table tbody { display: block; }
  .tv-bh-table tr {
    display: grid; grid-template-columns: 1fr auto; gap: 6px 12px;
    padding: 14px 16px; margin-bottom: 10px;
    border: 1px solid var(--tv-hair); border-radius: var(--tv-r-md);
    background: var(--tv-glass);
  }
  .tv-bh-table th, .tv-bh-table td { padding: 0; border: 0; text-align: left !important; }
  .tv-bh-table tbody th { grid-column: 1 / -1; }
  /* Each cell names itself once the header row is gone. */
  .tv-bh-table td::before {
    content: attr(data-label) ": ";
    font-family: var(--tv-font-mono); font-size: 10px;
    letter-spacing: .08em; text-transform: uppercase; color: var(--tv-ink-4);
  }
  .tv-bh-table tbody tr:hover > * { background: none; }
}

