/* ==================================================================
   Features Table — kwizzbit/features-table (whole-file segment)
   Full plan-by-plan comparison for the Features page.
   Design language inherited from comparison.css (sand table on cream,
   coral accents, animated conic highlight). Structure follows a Suno-style
   plan-comparison matrix: plans as columns, features as rows, grouped
   into sections. All selectors scoped under .features-table.
   ================================================================== */

/* Surface tokens. Declared for BOTH roots because the Modes page's tier snippet
   (.modes-tiers, styled in modes.css) reuses this table's leaf classes verbatim,
   and those classes reference these vars — a var declared only on .features-table
   would resolve to nothing inside the snippet. Shared here, in one place, so the
   two surfaces can never drift apart on colour.
   Exact match to comparison.css's design system — the earlier "white backdrop"
   bug was a paint-through/compositing issue (see FEATURE ROWS comment below), not
   a contrast problem, so these stay faithful to the signed-off comparison table on
   the pricing page rather than a custom tone. */
.features-table,
.modes-tiers {
  --ft-table-bg: #F4E6D9;                       /* sand table surface (matches comparison) */
  --ft-section-bg: #E9DCCF;                     /* subtle deeper shelf, same family, for category bands */
  --ft-border: rgba(182, 156, 146, 0.45);       /* hairline dividers (matches comparison) */
}
.features-table {
  /* Fluid columns: label + 3 plan columns share whatever width the hero/header
     content above gets (.features-table__inner), rather than a hardcoded px total.
     LABEL now carries the 1fr (takes any leftover width) — measured the widest
     real row ("National, regional & venue rankings" + tip icon + Soon pill) at
     380px needed including icon+padding, so 420px min is a safe no-wrap floor
     even when the grid is squeezed to its min-width. Tier columns are CAPPED
     (not 1fr) at a small fixed range — they only ever need a check/short value. */
  --ft-cols: minmax(420px, 1fr) repeat(3, minmax(108px, 158px));
  background: var(--wp--preset--color--cream);
  padding-block: 5rem 6rem;
}
.features-table__inner {
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 3rem);
}

/* ---------- HEADER ----------
   Title treatment lifted verbatim from the pricing page (.pricing__title):
   same Roobert Semimono face, size, line-height and tracking, a coral accent
   word, and the floating handshake anchored at the end via a zero-width
   anchor. Reuses the global hs-float keyframe defined in pricing.css. */
.features-table__header { text-align: left; margin-bottom: 2rem; }
.features-table__title {
  position: relative;
  font-family: 'Roobert Semimono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-weight: 400;
  font-size: 4.95rem;   /* 4.5rem * 1.1 */
  line-height: 0.889;
  letter-spacing: -0.10764em;
  color: var(--wp--preset--color--ink);
  margin: 0 0 0.875rem;
}
.features-table__title-accent { color: var(--wp--preset--color--coral); }
@keyframes features-table-cursor-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0; }
}
.features-table__title-cursor {
  color: var(--wp--preset--color--coral);
  animation: features-table-cursor-blink 1.1s step-end infinite;
}
/* Bottom line 10% smaller — em is relative to the title's font-size, so this
   holds at every breakpoint automatically. */
.features-table__title-line2 { font-size: 0.9em; }
/* Floating hand — anchored right after "live" (not the end of the
   second line), sitting beside the word rather than hanging off the
   bottom-right of the whole headline. Sized 20% down from the original
   pricing-page asset. Vertical centering uses margin-top (not
   transform:translateY) because the shared hs-float keyframe (defined in
   pricing.css, enqueued site-wide) already owns `transform` for its float —
   a second static transform would just overwrite it, not combine. */
.features-table__title-anchor {
  position: relative;
  display: inline-block;
  width: 0;
  overflow: visible;
}
.features-table__title-handshake {
  display: block;
  position: absolute;
  top: 50%;
  left: calc(-0.05em - 6px);
  width: 88px;   /* 104 * 0.85 */
  height: 88px;
  margin-top: -60px; /* half height (-44) plus a further nudge up */
  animation: hs-float 4s ease-in-out infinite;
  will-change: transform;
  pointer-events: none;
}
.features-table__title-handshake img { display: block; width: 100%; height: 100%; object-fit: contain; }
@media (prefers-reduced-motion: reduce) {
  .features-table__title-handshake { animation: none; }
  .features-table__title-cursor { animation: none; }
}
.features-table__lead {
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.6;
  color: var(--wp--custom--color--subcopy);
  margin: 0;
  max-width: 420px;
}

/* ---------- CONTROLS (toggle + legend) ---------- */
.features-table__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  margin-bottom: 1.5rem;
}
/* Toggle — matches the pricing page's billing switch exactly: sharp (0-radius)
   44x24 track, 18x18 square thumb, grey off / coral-gradient on. */
.features-table__toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-family: 'Roobert', system-ui, sans-serif;
  font-size: 0.9375rem;
  font-weight: 700; /* bold per Max (pricing toggle label is 500) */
  color: #1D0B09;
  -webkit-tap-highlight-color: transparent;
}
.features-table__toggle-track {
  position: relative;
  width: 44px;
  height: 24px;
  border-radius: 0;
  background: rgba(71,56,51,0.18);
  transition: background 180ms ease;
  flex-shrink: 0;
}
.features-table__toggle-thumb {
  position: absolute;
  top: 3px; left: 3px;
  width: 18px; height: 18px;
  border-radius: 0;
  background: #fff;
  transition: transform 200ms cubic-bezier(0.22,1,0.36,1);
}
.features-table__toggle[aria-pressed="true"] .features-table__toggle-track {
  background: linear-gradient(to right, #FF6F5F, #FF3623);
}
.features-table__toggle[aria-pressed="true"] .features-table__toggle-thumb { transform: translateX(20px); }

.features-table__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  list-style: none;
  margin: 0; padding: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--wp--custom--color--subcopy);
}
.features-table__legend li { display: inline-flex; align-items: center; gap: 0.4rem; }
.features-table__legend-check { display: block; color: var(--wp--preset--color--ink); }
.features-table__legend-dash { width: 12px; height: 2px; background: #C6B4A8; }
.features-table__legend-ai { color: var(--wp--preset--color--coral); font-weight: 700; -webkit-text-stroke: 0.6px currentColor; }

/* ---------- SCROLL HINT (mobile) ----------
   Visibility is JS-driven (features-table.js toggles .is-visible-hint based on
   whether the table actually overflows its wrap) since the table is now fluid —
   a fixed breakpoint can't know in advance when scrolling starts. Styling
   matches .comparison__scroll-hint on the pricing page (peach pill) exactly —
   left-aligned (no margin-inline:auto) since the header above is also
   left-aligned, mirroring comparison's own mobile override. */
.features-table__scroll-hint {
  display: none;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--wp--custom--color--subcopy);
  margin: 0 0 1.5rem;
  padding: 0.5rem 0.875rem;
  background: rgba(255, 54, 35, 0.07);
  border-radius: 0;
  width: fit-content;
}
.features-table__scroll-hint.is-visible-hint { display: inline-flex; }
@keyframes scroll-nudge { 0%,100% { transform: translateX(0); } 50% { transform: translateX(5px); } }
.features-table__scroll-hint svg { animation: scroll-nudge 1.6s ease-in-out infinite; }

/* ---------- TABLE WRAP + GRID ---------- */
.features-table__wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Small bleed so the Pro-column shadow/border isn't clipped by the scroll
     container — kept tight so the table still reads as matching the header's
     content width above, just with breathing room for the glow. */
  padding: 6px 12px 2px;
  margin-inline: -12px;
}
.features-table__grid {
  position: relative;
  display: grid;
  grid-template-columns: var(--ft-cols);
  /* Fills the wrap (== the same content width as the header/lead block above),
     growing/shrinking with the viewport; only drops to horizontal scroll once
     the column minimums (420 + 3x108 = 744px) no longer fit. */
  width: 100%;
  min-width: 744px;
  background: var(--ft-table-bg);
}

/* ---------- GAME-SHOW COLUMN HIGHLIGHT (animated conic border) ----------
   A separate overlay grid, sharing the exact same --ft-cols track list as
   the real table grid (inset:0 makes its box match the grid's box exactly,
   so the two column sets line up pixel-for-pixel at any width). The
   highlight itself is a plain in-flow grid item — it stretches to fill its
   track by default (well-supported), rather than relying on an absolutely
   positioned grid item auto-sizing to an implicit span, which browsers
   handle inconsistently (collapses to content-size in testing). Spans the
   full height of however many rows are currently in flow, so the
   coming-soon toggle can't disturb it. */
.features-table__pop-layer {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: var(--ft-cols);
  pointer-events: none;
  /* ABOVE the category-divider bands (z-index 1) AND every cell (z-index 1),
     so the frame stays continuous through section bands. Safe to sit on top
     of cell content because .features-table__pop below is HOLLOW (border-image
     only paints the 2px ring — its own content area is transparent, so
     checkmarks/text/section-band fills underneath remain fully visible). */
  z-index: 2;
}
@keyframes ft-border-spin { to { --border-angle: -360deg; } }
.features-table__pop {
  grid-column: 3 / 4; /* label=1, Pro=2, Game-show=3 (highlighted), Enterprise=4 */
  grid-row: 1 / -1;
  align-self: stretch;
  /* border-image (not background+padding+white-pseudo) so only the ring
     itself carries paint — the content area stays genuinely transparent,
     letting the Game-show column's own cell fills/checkmarks show through
     normally underneath this frame. */
  border: 2px solid transparent;
  border-image: conic-gradient(from var(--border-angle), #FD4631 0% 60%, #FFCB2B 75%, #FD4631 90% 100%) 1;
  animation: ft-border-spin 5s linear infinite;
  box-shadow: 0 18px 45px rgba(255, 54, 35, 0.12);
}
@media (prefers-reduced-motion: reduce) { .features-table__pop { animation: none; } }

/* ---------- HEADER (plan) ROW ----------
   Explicit background on every header cell (not "transparent" relying on
   paint-through to the grid's own background) — the animated conic-gradient
   overlay behind it (.features-table__pop-layer) forces GPU layer promotion
   for its animation, and in testing that layer rasterized as an OPAQUE WHITE
   backing instead of staying transparent, blocking anything relying on
   pass-through paint. Painting each cell's fill directly (same convention as
   comparison.css) sidesteps that entirely. */
/* Deliberately position:relative WITHOUT a z-index here — giving the header
   cell its own explicit z-index (tried z-index:3 above pop-layer's 2) fixed
   the badge but broke the frame's TOP CAP: with the whole cell elevated, its
   own opaque background then paints above the frame everywhere the cell is,
   not just where the badge sits, hiding the ring across the entire header
   width. Leaving z-index:auto means the cell's background stays correctly
   BELOW the frame (so the cap shows), while position:relative still gives
   the badge a containing block. Only the badge itself gets an explicit
   z-index below — since its ancestor here creates no stacking context, the
   badge's z-index escapes to compare directly against the frame at the grid
   level, without dragging the rest of the cell's background up with it. */
.features-table__grid .ft-head { position: relative; }
.features-table__corner { background: var(--ft-table-bg); }
.features-table__plan {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  padding: 1.5rem 0.75rem 1.25rem;
  text-align: center;
  background: var(--ft-table-bg);
}
.features-table__plan--pop { background: var(--wp--preset--color--white); }
.features-table__plan-badge {
  position: absolute;
  z-index: 4; /* above .features-table__pop-layer's 2 — see the HEADER ROW comment above */
  top: -0.7rem; left: 50%; transform: translateX(-50%);
  font-family: 'Roobert', system-ui, sans-serif;
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: -0.01em;
  color: #fff;
  background: var(--wp--preset--color--coral);
  padding: 0.25rem 0.6rem 0.05rem;   /* asymmetric — nudges the text down ~1.5px to sit visually centred */
  white-space: nowrap;
}
/* Secondary badge treatment (Pro's "Popular") — ink fill, distinct from
   Game-show's coral "Best value" so the two don't compete for attention. */
.features-table__plan-badge--secondary {
  background: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--cream);
}
/* Tier-title typography lifted verbatim from the pricing page: Pro/Enterprise
   here use pricing.php's PLAIN .plan-card__name treatment (== the Free card
   there); Game-show uses pricing.php's .plan-card--featured coral-gradient
   text-clip (== the Pro card there) — an explicit choice by Max, not a 1:1
   name match, since Enterprise gets the gradient on the pricing page but the
   plain treatment here. */
.features-table__plan-name {
  font-family: 'Roobert Semimono', ui-monospace, monospace;
  font-weight: 400;
  font-size: 1.375rem;
  line-height: 1;
  letter-spacing: -0.091em;
  color: var(--wp--preset--color--ink);
  -webkit-text-stroke: 0.3px currentColor;
}
.features-table__plan--pop .features-table__plan-name {
  background: linear-gradient(to right, #FF3623 0%, #FF3623 50%, #FFA174 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  color: transparent;
  padding-right: 0.15em;
}

/* ---------- SECTION HEADINGS (full-width band) ----------
   A deeper shelf of the SAME sand family (not a generic grey overlay — that
   read as a mismatched stripe rather than part of the table) + a firmer top
   rule + extra breathing room, so each of the 5 categories reads as a clear
   break rather than just another row. Built as its own subgrid (sharing the
   outer grid's column tracks) so it can carry an explicit white pass-through
   swatch in the Game-show column — otherwise its own tan fill cuts a visible
   gap into the highlighted column every time a new category starts. */
.features-table__section {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
  position: relative;
  z-index: 1;
  /* NO margin-top here (was 0.5rem) — margin sits OUTSIDE every child's own
     background box, so nothing (section-label/-fill/-pop, all colour-coded
     per column) could ever paint over it. In the sand columns that gap was
     invisible because the grid's own base background happens to match the
     surrounding cells; in the white Game-show column it showed as a real
     cream strip, since nothing white covers the grid's base colour there.
     The equivalent breathing room now lives INSIDE .features-table__section-
     label's own top padding below, where every column's own background
     already stretches to cover it (grid default align-items:stretch). */
}
.features-table__section-label,
.features-table__section-fill {
  background: var(--ft-section-bg);
  /* No border-top — the band's own colour shift already reads as the
     divider between categories; a hairline on top of that read as a second,
     redundant line right after the previous category's last row. */
}
.features-table__section-label {
  grid-column: 1 / 2;
  padding: 2.5rem 0 0.85rem 1.375rem; /* top = old 2rem content pad + the removed 0.5rem margin */
}
.features-table__section--first .features-table__section-label { padding-top: 0.85rem; }
.features-table__section-pop {
  grid-column: 3 / 4;
  background: var(--wp--preset--color--white);
}
.features-table__section-label {
  font-family: 'Pixelar', monospace;
  font-size: 1.0625rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--wp--preset--color--coral);
}

/* ---------- FEATURE ROWS ----------
   Explicit background (see the header-row comment above for why — the
   animated overlay behind these rows can't be relied on for paint-through). */
.features-table__label,
.features-table__cell {
  position: relative;
  z-index: 1;
  display: flex;
  border-bottom: 0.5px solid var(--ft-border);
  background: var(--ft-table-bg);
}
.features-table__label {
  align-items: center;
  gap: 0.875rem; /* matches comparison__row-label's icon-to-copy gap */
  padding: calc(1rem + 3px) 1.25rem calc(1rem + 3px) 1.375rem; /* +6px row height */
  /* Divider starts at the icon's left edge (1.375rem), not the cell edge —
     same offset-gradient technique as comparison__row-label. */
  border-bottom: none;
  background-image: linear-gradient(to right, transparent 1.375rem, var(--ft-border) 1.375rem);
  background-repeat: no-repeat;
  background-size: 100% 0.5px;
  background-position: bottom;
}
/* Row icon — same 25px flex-centred slot as .comparison__row-icon on the pricing page. */
.features-table__row-icon { flex-shrink: 0; width: 25px; display: flex; align-items: center; justify-content: center; }
.features-table__label-head { display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem; }
.features-table__feature {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--wp--preset--color--ink);
  line-height: 1.25;
}
.features-table__ai {
  color: var(--wp--preset--color--coral);
  font-weight: 700;
  /* The ✳︎ glyph renders from a fallback font that ignores font-weight, so
     thicken its strokes directly to read as bold. */
  -webkit-text-stroke: 0.6px currentColor;
  font-size: 0.8125rem;
  margin-left: 0.15rem;
  cursor: help;
}
/* Info tip — hover/tap reveal for the feature description. Mirrors
   .plan-card__feature-tip / .plan-card__tip-modal on the pricing page
   (same icon, same hover-desktop / tap-mobile interaction) for consistency. */
.features-table__info {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  line-height: 0;
  cursor: pointer;
  position: relative;
  opacity: 0.8;
}
.features-table__info svg { display: block; }
/* Tip modal is reparented to <body> and positioned via JS (position:fixed,
   top/left set in features-table.js). This escapes the row's own stacking
   context entirely — CSS position:absolute WITHIN the row let a sibling row
   above (also position:relative + z-index:1, inside a wrap forced to
   overflow-y:auto by the overflow-x:auto sibling-axis rule) win the paint
   order at the overlap point, letting its text bleed through the "opaque"
   modal. Fully reparenting sidesteps the ambiguity rather than fighting it
   with z-index (tried raising the row's own z-index on open — did not
   reliably win in testing). JS shows/hides it for BOTH hover and tap now
   (no more CSS-only :hover rule, since JS must run first to compute position). */
.features-table__tip-modal {
  display: none;
  position: fixed;
  width: fit-content;
  max-width: 240px;
  background: #FFFFFF;
  box-shadow: 2px 2px 0px rgba(253,106,97,0.20), 0px 20px 50px rgba(255,54,35,0.20);
  padding: 0.625rem 0.75rem;
  z-index: 1000;
  pointer-events: none;
  font-family: var(--wp--preset--font-family--body);
  font-weight: 500;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--wp--preset--color--ink);
  text-align: left;
}

/* status pills — live rows get none; beta = coral outline, soon = a solid
   warm-brown chip so the two stay visually distinct.

   SOON was a #A79389 outline to match beta's treatment. QA finding, 2026-08:
   the coming-soon rows were hard to pick out. Measured, and it was not only a
   taste problem — #A79389 on the sand table surface (#F4E6D9) is 2.39:1, well
   under the 4.5:1 WCAG AA needs at this size, so the label was barely legible
   before it was un-noticeable. Now a filled chip in the same brown family,
   darkened to #5F4C45: 7.19:1 against its own cream label, and a solid dark
   shape reads at a glance against the light table. Same box metrics as beta
   (border kept) so the two pill types never shift the row. Deliberately NOT
   coral — beta owns coral, and a second coral chip would compete with the
   page's actual CTAs. */
.features-table__pill {
  font-family: var(--wp--preset--font-family--body);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  padding: 0.2rem 0.4rem;
  white-space: nowrap;
}
.features-table__pill--beta {
  color: var(--wp--preset--color--coral);
  border: 1px solid var(--wp--preset--color--coral);
}
.features-table__pill--soon {
  color: var(--wp--preset--color--cream);
  background: #5F4C45;
  border: 1px solid #5F4C45;
}
.features-table__cell {
  align-items: center;
  justify-content: center;
  padding: calc(1rem + 3px) 0.75rem; /* +6px row height, matches label */
  text-align: center;
}
.features-table__val {
  font-family: var(--wp--preset--font-family--body); /* Roobert */
  font-size: 0.8125rem;
  font-weight: 500; /* Roobert Medium — not bold */
  color: var(--wp--preset--color--ink);
  line-height: 1.3;
}
.features-table__check { color: var(--wp--preset--color--ink); display: block; }
.features-table__dash { width: 16px; height: 2px; background: #C6B4A8; display: block; }
.features-table__sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Game-show column cells: explicit white fill (not relying on the animated
   overlay behind them for paint-through — see FEATURE ROWS comment above).
   NO divider — matches comparison.css's own highlighted-row treatment, which
   drops all internal dividers so the highlight reads as one clean card. */
.features-table__cell--pop {
  background: var(--wp--preset--color--white);
  border-bottom: none;
}

/* Tint the Pro/Enterprise columns a touch darker than the feature-name
   column, at every breakpoint — a clean visual separation between "what"
   (column 1) and "how much of it" (the plan columns). Originated as a
   mobile-only fix (to distinguish the pinned column from the columns
   scrolling under it) but reads well everywhere, so promoted to the base
   rule. Targeted via :not(--pop) rather than nth-child — the category band
   is a single subgrid child per row (not 4 separate cells), so nth-child
   parity breaks every time a band is inserted; :not(--pop) reaches exactly
   the Pro + Enterprise slots regardless of row type, and never matches
   .features-table__label (a different class entirely). Game-show stays
   white/highlighted as before. */
.features-table__plan:not(.features-table__plan--pop),
.features-table__cell:not(.features-table__cell--pop) {
  background-color: #E8DACD; /* --ft-table-bg (#F4E6D9), ~12/channel darker */
}
.features-table__section-fill {
  background-color: #DDD0C3; /* --ft-section-bg (#E9DCCF), same ~12/channel darker */
}

/* Last row of a category: no divider under it (the category band that
   follows already draws a firm top rule, so a divider here just doubled up
   the same line). Which row counts as "last" shifts with the coming-soon
   toggle (hidden rows aren't the last VISIBLE one) — features-table.js
   recomputes these two classes on load and on every toggle change; a plain
   :last-of-type couldn't do this since display:none doesn't affect CSS
   structural pseudo-class matching. */
.features-table__label--last { background-image: none; }
.features-table__cell--last { border-bottom: none; }

/* ---------- COMING-SOON TOGGLE (hide rows) ---------- */
.features-table__grid.is-hiding-soon [data-row-status="soon"] { display: none; }

/* Coming-soon rows get a dimmed row icon to read as visually distinct from
   live/beta rows, without touching the row backdrop. */
.features-table__label[data-row-status="soon"] .features-table__row-icon {
  opacity: 0.7;
}

/* ---------- SCROLL REVEAL (scoped) ---------- */
.features-table .js-reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.55s cubic-bezier(0.22,1,0.36,1), transform 0.55s cubic-bezier(0.22,1,0.36,1);
}
.features-table .js-reveal.is-visible { opacity: 1; transform: none; }
/* Stagger the lift — header, controls and table are all above the fold, so
   JS's IntersectionObserver marks all three .is-visible in the same tick;
   without a delay they'd rise as one flat block. Staggering the transition
   onset (not the JS) gives the same top-to-bottom sequence feel as the
   How It Works steps, ~80ms apart, matching the FAQ header's own cascade. */
.features-table__header.js-reveal.is-visible { transition-delay: 0s; }
.features-table__controls.js-reveal.is-visible { transition-delay: 0.08s; }
.features-table__wrap.js-reveal.is-visible { transition-delay: 0.16s; }

/* ---------- FOOT NOTE ---------- */
.features-table__foot {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--wp--custom--color--subcopy);
  margin: 1.5rem 0 0;
  opacity: 0.8;
}

/* ---------- TABLET ---------- */
@media (max-width: 1023px) {
  .features-table { padding-block: 4rem 5rem; }
  /* Title step-down — matches pricing's tablet breakpoint */
  .features-table__title { font-size: 3.575rem; line-height: 3.3rem; }   /* 3.25rem/3rem * 1.1 */
}

/* ---------- MOBILE ---------- */
@media (max-width: 640px) {
  .features-table { padding-block: 3rem 3.5rem; }
  /* Title + handshake — matches pricing's mobile breakpoint */
  .features-table__title {
    font-size: clamp(2.2275rem, 12.03vw, 2.8215rem);   /* mobile clamp * 1.1, then +8% */
    line-height: 0.8421;
    letter-spacing: -0.10763em;
    width: min(8.5em, 88vw);
    overflow: visible;
  }
  .features-table__title-handshake {
    width: 50px;   /* 48 * 1.04 */
    height: 50px;
    top: 50%;
    left: calc(-0.05em - 7px); /* nudged 5px further left */
    margin-top: -35px; /* half height (-25) plus a further nudge up */
  }
  .features-table__lead { max-width: 300px; }
  .features-table__legend { gap: 0.9rem; font-size: 0.75rem; }
  .features-table__scroll-hint svg { shape-rendering: crispEdges; }
  /* Let the table bleed off the right edge instead of stopping short at the
     page's own gutter. .features-table__inner's padding-inline (the same
     clamp(1rem,4vw,3rem) used site-wide) is what the wrap's own -12px/+12px
     margin/padding pair does NOT cancel — only each other — so the table was
     still stopping at that outer gutter on the right, reading as an
     unintended crop now that the table scrolls. Left is untouched: the
     sticky column already handles its own edge there. */
  .features-table__wrap {
    margin-right: calc(-1 * clamp(1rem, 4vw, 3rem) - 12px);
    /* 16px trailing scroll margin, so max scroll shows breathing room after
       Enterprise rather than stopping flush against it. Deliberately padding
       on the WRAP (a plain block scroll container), NOT the grid: an earlier
       attempt padded .features-table__grid itself, which — being a CSS Grid —
       distributes any leftover container space into its minmax() tracks
       whenever the grid has a definite width to fill. That grew the tier
       columns unevenly and, worse, misaligned .features-table__pop-layer
       (the animated Game-show frame, a separate grid using the same track
       list) from the real cells, since the two grids' definite-vs-intrinsic
       width status differed. Padding a non-grid element sidesteps that whole
       class of bug — it's just trailing whitespace, nothing to distribute. */
    padding-right: 16px;
  }
  /* Tier titles — desktop's 22px overflows the tier columns' 108px mobile
     minimum ("Enterprise" ran 28px wider than the cell, "Game-show" wrapped
     onto 2 lines at its hyphen). 14px measured live: the tightest case
     (Enterprise) fits with ~12px of breathing room either side, comfortably
     clear of a knife-edge fit. */
  .features-table__plan-name { font-size: 0.875rem; font-weight: 700; }

  /* ---------- STICKY FEATURE COLUMN ----------
     Desktop's --ft-cols gives the label track minmax(420px, 1fr) — sized to
     match the fluid header content above it. On mobile that's the whole
     problem: horizontal scroll has to cover 420px of label before a visitor
     even reaches the first tier column, and once scrolled, the feature name
     for whatever they're looking at is off-screen. Fix: shrink the label
     track to its minimum viable width and pin it with position:sticky, so
     scrolling only ever moves between tiers — the feature name stays put.
     286px. NOT sized off a "force everything onto one line" measurement —
     that overshoots, because .features-table__label-head already
     flex-wraps gracefully: a status pill that doesn't fit just drops to
     its own line under the title, which is fine (only the TITLE must
     never wrap). The real floor was found empirically: binary-searched
     live in-browser for the exact width where a title first wraps —
     280px ("30,000+ verified questions" is the tightest). 286px adds a
     6px safety margin over that exact boundary (a knife-edge fit broke
     once already this session — see the max-content note below — so a
     hard-zero margin isn't trustworthy across devices). At 286px the
     tightest row's trailing gap is ~20px, which is just its own
     `padding-right` (1.25rem) showing through once nothing is forced
     against the edge — not slack worth trimming further without also
     touching that shared padding value. A hardcoded px, NOT `max-content`:
     max-content was tried first (self-sizing, no magic number to
     maintain) but it breaks position:sticky on the label cells below —
     sticky needs a DEFINITE size on its containing block, and
     intrinsic-sizing keywords don't reliably count as definite even once
     layout resolves them, so the sticky column silently stopped sticking
     (confirmed in testing: it tracked scrollLeft 1:1 instead of staying
     pinned). Revisit this number if a future feature name grows past the
     current longest. Tier columns keep their existing 108–140px range. */
  .features-table {
    --ft-cols: 286px repeat(3, minmax(108px, 140px));
  }
  /* Cancel the desktop floor (744px, sized for the old fluid label track) —
     286 + 3×108 is already the correct natural minimum at this column set;
     the inherited 744px would just pad in dead, unscrollable-for-a-reason
     space. */
  .features-table__grid {
    min-width: 610px; /* 286 + 3×108 */
  }
  .features-table__section-label,
  .features-table__label {
    position: sticky;
    left: 0;
    z-index: 3; /* above .features-table__pop-layer's 2, so nothing bleeds under the pinned column */
  }
  /* The corner (header row, column 1) needs its own rule for two reasons:
     (1) SPECIFICITY — it also carries .ft-head, whose base rule
     `.features-table__grid .ft-head { position: relative }` (0-2-0) outranks a
     bare `.features-table__corner` (0-1-0), so the shared sticky rule above
     silently lost and the corner scrolled away with the header. Match that
     specificity (this selector is 0-3-0) so sticky actually takes.
     (2) Z-INDEX — the plan badges are z-index 4, so a corner at 3 would let
     "Popular"/"Best value" bleed over it when the header scrolls under. 5
     tucks the ENTIRE header row (names + badges) behind the pinned column,
     matching how the allowance rows already behave. Safe from the frame-cap
     issue the header-row comment above warns about: that concerns column 3
     (Game-show); the corner is column 1 and never overlaps the frame. */
  .features-table__grid .features-table__corner.ft-head {
    position: sticky;
    left: 0;
    z-index: 5;
  }
  /* Sticky elements need their own opaque paint — background-color (not the
     `background` shorthand) so .features-table__label's divider gradient
     (set via background-image) and the category band's border-top survive. */
  .features-table__corner { background-color: var(--ft-table-bg); }
  .features-table__section-label { background-color: var(--ft-section-bg); }
  .features-table__label { background-color: var(--ft-table-bg); }
  /* Category-band Game-show column: on desktop this cell is hard-white
     (.features-table__section-pop) so the highlight runs UNBROKEN through the
     bands. On mobile that reads as the white column bleeding through each
     category divider — so fill it with the band's own sand instead, letting
     every category strip cross the table as one continuous colour. The
     animated frame (a hollow ring, painted by .features-table__pop above) still
     runs the full height either way. Sand + matching top rule mirror the
     section-label/-fill cells (which also carry no border-top — see base
     rule — so the whole band reads as one continuous colour with no
     hairline anywhere along its top edge). */
  .features-table__section-pop {
    background-color: var(--ft-section-bg);
  }
  /* Lift the whole category band ABOVE the animated Game-show frame
     (.features-table__pop, z-index 2) so the band's own sand paints over the
     ring instead of the ring bleeding across the divider. The frame still runs
     full-height through the feature rows on either side of each band; it just
     no longer crosses the bands themselves. Pairs with the sand section-pop
     above — together every category strip reads as one clean, unbroken band. */
  .features-table__section { z-index: 3; }
  /* Crop the plan badges where they scroll behind the pinned column. Badges sit
     at top:-0.7rem, so they poke ABOVE the corner cell's own box — raising the
     corner's z-index alone can't hide that overhang. This pseudo extends the
     corner's opaque paint up into the overhang strip (page cream, matching the
     gap above the table), travelling with the sticky corner and painting inside
     its z-index:5 context, so any badge sliding under column 1 is fully masked,
     names and badges alike. */
  .features-table__corner.ft-head::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: 1.25rem;
    background: var(--wp--preset--color--cream);
  }
}

/* ==================================================================
   FINAL CTA — kwizzbit/features-cta (bottom of the Features page)
   Reuses .faq__title / .faq__lead verbatim (same classes as the FAQ
   preview segment's sidebar in faq.php) so typography and their existing
   responsive step-downs in faq.css apply automatically — this wrapper just
   left-aligns everything (matching the rest of the page's headlines, e.g.
   .features-table__title) in a full-width inner rather than the FAQ
   sidebar's narrow centred column, and adds the accent colour for "You.".
   ================================================================== */
.features-final-cta {
  background: var(--wp--preset--color--cream);
  padding-block: 2.25rem 4.5rem;
  text-align: left;
}
@media (min-width: 641px) {
  .features-final-cta { padding-top: calc(2.25rem + 12px); }
}
.features-final-cta__inner {
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 3rem);
}
/* Match the lead's width to the headline's — .faq__title has no width of
   its own (its <br>-broken lines just wrap within whatever container it's
   given), so instead of guessing a ch value, wrap title+lead together in a
   shrink-to-fit box: width:fit-content sizes the box to its widest CHILD's
   intrinsic width, and for a box with forced <br> breaks that's the widest
   individual line ("feature: You.", not the full available width) — then
   the lead at width:100% exactly matches that. */
.features-final-cta__copy { width: fit-content; }
/* Lead width tuned to the headline's own widest line ("feature: You.", ~320px)
   so the subcopy sits within the same measure as the title above it, rather
   than running noticeably wider. */
.features-final-cta .faq__lead { width: 100%; max-width: 320px; }

/* "You." accent — same shimmering coral gradient text-clip treatment as
   .modes-hero__title-coral (modes-full.html): a wide linear-gradient clipped
   to the text, animated by panning background-position back and forth. */
.features-final-cta__accent {
  color: var(--wp--preset--color--coral); /* fallback for no background-clip support */
  background: linear-gradient(100deg, #FF3623 0%, #FF3623 20%, #FF7055 42%, #FF6F5F 58%, #FF3623 80%, #FF3623 100%);
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: features-cta-text-shimmer 3.5s ease-in-out infinite alternate;
}
@keyframes features-cta-text-shimmer {
  from { background-position: 0% center; }
  to   { background-position: 100% center; }
}

/* ---------- FINAL CTA — staggered lift-up reveal ----------
   Mirrors the features-table scroll-reveal (same distance/easing/duration).
   Per-element onset via --cta-i set inline in the markup, so the title, lead,
   trust strip and button rise top-to-bottom ~90ms apart. features-cta.js adds
   .is-visible when the section scrolls in, gated on kwb:loaded. */
.features-final-cta__inner .js-cta-reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.55s cubic-bezier(0.22,1,0.36,1), transform 0.55s cubic-bezier(0.22,1,0.36,1);
}
.features-final-cta__inner .js-cta-reveal.is-visible {
  opacity: 1;
  transform: none;
  transition-delay: calc(var(--cta-i, 0) * 0.09s);
}
@media (prefers-reduced-motion: reduce) {
  .features-final-cta__inner .js-cta-reveal { opacity: 1; transform: none; transition: none; }
  .features-final-cta__accent { animation: none; }
}
/* Trust strip — same markup/image as the login/signup form's
   .gateway__trust, but that's centred (flex-direction:column,
   align-items:center) for its own single-column form context. Left-align
   here to match the rest of this block; margin-top independent of
   gateway.css's 2.5rem (tuned for sitting under a button there) since it
   now sits under a paragraph instead. */
.features-final-cta .gateway__trust {
  align-items: flex-start;
  margin-top: 1.75rem;
  margin-bottom: 1.75rem;
}
.features-final-cta .btn { margin-top: 0; }
