/* ============================================================
   40 — PRODUCT SUITE
   Payments leads as a 2×2 feature panel carrying a real checkout
   fragment; the other eight are compact glyph cards. Accent lives
   only in the glyph tile, the arrow link and the hover hairline —
   never as a card fill. Every accent is normalised against its own
   tint so all nine land in the same contrast band (~5:1).
   ============================================================ */

/* ---------------- Header ---------------- */

.products__head {
  margin-inline: auto;
  text-align: center;
}

/* Modifier, not a restyle of the .eyebrow primitive: --c-brand is
   4.45:1 on --surface-alt, below AA at 14px. --c-brand-press is 5.83:1. */
.products__eyebrow { color: var(--c-brand-press); }

.products__title { margin-top: var(--s-4); }

.products__lead {
  margin-top: var(--s-5);
  margin-inline: auto;
  max-width: 54ch;
}

/* ---------------- Grid ---------------- */

.products__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
  margin-top: var(--s-11);
}

/* 2 cols: feature spans the row → 2 + 8 = 10 cells, exactly 5 rows. */
@media (min-width: 680px) {
  .products__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6); }
  .products__item--feature { grid-column: 1 / -1; }
}

/* 3 cols: feature is 2×2 → 4 + 8 = 12 cells, exactly 4 rows.
   The asymmetry is the point; nothing is widowed at any width. */
@media (min-width: 1024px) {
  .products__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .products__item--feature { grid-column: span 2; grid-row: span 2; }
}

.products__item { display: flex; }

/* ---------------- Card ---------------- */

.products__card {
  --accent: var(--c-brand);
  --ink: 81%;
  /* fallbacks for browsers without color-mix: neutral tile, navy ink */
  --accent-tint: var(--c-hairline-soft);
  --accent-ink:  var(--c-navy);
  --accent-line: var(--c-brand);

  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  padding: var(--s-6);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--text-body);
  box-shadow:
    inset 0 0 0 1px var(--border),
    var(--sh-xs);
  transition:
    transform var(--t-fast) var(--ease-out),
    box-shadow var(--t-fast) var(--ease-out);
}

@media (min-width: 1024px) {
  .products__card { padding: var(--s-7); }
}

/* Pointer-tracked spotlight (main.js sets --mx / --my).
   Driven by --accent-ink, not the raw --accent: the raw palette spans
   L* 40→90, so lime at .07 over white moved 7/255 — invisible. --accent-ink
   is already luminance-normalised into one band, so at .12 every card
   moves ~20-25/255 off white and the effect reads on all nine. */
.products__card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0;
  background: radial-gradient(
    ellipse 58% 74% at var(--mx, 50%) var(--my, 0%),
    var(--accent-ink),
    transparent 70%
  );
  transition: opacity var(--t-slow) var(--ease-expo);
}

.products__card:hover,
.products__card:focus-visible {
  transform: translateY(-2px);
  box-shadow:
    inset 0 0 0 1px var(--accent-line),
    var(--sh-sm);
}

.products__card:hover::before,
.products__card:focus-visible::before { opacity: .12; }

.products__card:active { transform: translateY(0); }

/* ---------------- Glyph tile ---------------- */

.products__tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--s-9);
  height: var(--s-9);
  border-radius: var(--r-md);
  background: var(--accent-tint);
  color: var(--accent-ink);
  transition: transform var(--t-base) var(--ease-expo);
}

.products__card:hover .products__tile { transform: translateY(-1px) scale(1.04); }

.products__glyph { width: var(--s-6); height: var(--s-6); }

/* ---------------- Copy ---------------- */

.products__name {
  margin-top: var(--s-5);
  font-size: var(--fs-h4);
  font-weight: var(--fw-semi);
  letter-spacing: var(--tracking-snug);
  color: var(--text-strong);
}

.products__desc {
  margin-top: var(--s-2);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
  color: var(--text-body);
}

/* ---------------- In-card arrow link ----------------
   A real labelled link idiom (base .arrow-link) rather than a bare
   chevron, so the card has a verbal affordance. It is a <span>, not an
   <a> — the card itself is the link — and its gap only grows on card
   hover. --accent-ink holds ≥5:1 on the white card for all nine. */

.products__cta {
  margin-top: auto;
  padding-top: var(--s-6);
  color: var(--accent-ink);
  gap: var(--s-1);
}

.products__cta:hover { color: var(--accent-ink); gap: var(--s-1); }

.products__card:hover .products__cta,
.products__card:focus-visible .products__cta { gap: var(--s-3); }

/* ---------------- Feature card ---------------- */

.products__card--feature { justify-content: center; }

.products__lockup { min-width: 0; }

.products__name--feature { margin-top: 0; }

.products__desc--feature {
  margin-top: var(--s-3);
  font-size: var(--fs-body);
  max-width: 42ch;
}

.products__card--feature .products__cta { margin-top: var(--s-6); padding-top: 0; }

@media (min-width: 680px) {
  .products__card--feature {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: center;
    column-gap: var(--s-8);
  }
}

/* ---------------- Checkout fragment ---------------- */

.products__pay {
  width: 100%;
  min-width: 0;
  margin-top: var(--s-8);
  padding: var(--s-5);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow:
    inset 0 0 0 1px var(--border),
    var(--sh-md);
  transition: transform var(--t-base) var(--ease-expo);
}

@media (min-width: 680px) {
  .products__pay { margin-top: 0; }
}

.products__card--feature:hover .products__pay { transform: translateY(-2px); }

.products__pay-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--c-hairline-soft);
}

.products__pay-label {
  font-size: var(--fs-xs);
  color: var(--text-body);              /* 7.80:1 on --surface */
}

.products__pay-amount {
  font-size: var(--fs-h4);
  font-weight: var(--fw-semi);
  letter-spacing: var(--tracking-snug);
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}

/* Padding stays at --s-3 both axes: at 1024 the panel column is only
   ~258px wide and the 19-character card number has to fit without
   ellipsis. Every text node still has an ellipsis guard behind it. */
.products__pay-field {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
  margin-top: var(--s-4);
  padding: var(--s-3);
  border-radius: var(--r-sm);
  box-shadow: inset 0 0 0 1px var(--border);
}

.products__pay-icon {
  flex: none;
  width: var(--s-5);
  height: var(--s-5);
  color: var(--text-muted);
}

.products__pay-num,
.products__pay-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-xs);
  color: var(--text-body);
}

.products__pay-num { font-family: var(--font-mono); }

.products__pay-split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-2);
  margin-top: var(--s-2);
}

.products__pay-cell {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: var(--s-3);
  border-radius: var(--r-sm);
  box-shadow: inset 0 0 0 1px var(--border);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-body);
}

.products__pay-cell--text { font-family: var(--font-sans); }

/* Card number + expiry/CVC read as one group, billing address as the next.
   The address row is 1.4/1 because "United States" needs the width and a
   postal code does not. */
.products__pay-split + .products__pay-split {
  margin-top: var(--s-4);
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
}

.products__pay-brands {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-4);
  color: var(--text-muted);
}

.products__pay-brand { width: var(--s-7); height: auto; }

.products__pay-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--s-8);
  margin-top: var(--s-4);
  border-radius: var(--r-pill);
  background: var(--c-brand);
  color: var(--text-invert);            /* 4.82:1 */
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  letter-spacing: var(--tracking-snug);
}

/* ---------------- Accents ----------------------------------------
   --ink is tuned per hue: a uniform mix ratio over a non-uniform
   palette is what washed the pale glyphs out. Each value puts the
   glyph at ~5:1 against its own tile tint — and, since it now also
   drives the spotlight, keeps all nine hovers in one visible band.
   ------------------------------------------------------------- */

.products__card--billing  { --accent: var(--c-cyan);    --ink: 44%; }
.products__card--connect  { --accent: var(--c-teal);    --ink: 40%; }
.products__card--terminal { --accent: var(--c-lime);    --ink: 39%; }
.products__card--radar    { --accent: var(--c-magenta); --ink: 62%; }
.products__card--issuing  { --accent: var(--c-orange);  --ink: 45%; }

/* Two mixes + one shifted brand. No fallback declaration: a custom
   property accepts any token stream, so an earlier --accent would be
   dead code — the derived values below carry the real fallback. */
.products__card--tax      { --accent: color-mix(in srgb, var(--c-brand) 52%, var(--c-magenta)); --ink: 74%; }
.products__card--identity { --accent: color-mix(in srgb, var(--c-cyan) 55%, var(--c-brand));    --ink: 56%; }
.products__card--atlas    { --accent: color-mix(in srgb, var(--c-orange) 58%, var(--c-magenta)); --ink: 52%; }

@supports (color: color-mix(in srgb, red, blue)) {
  .products__card {
    --accent-tint: color-mix(in srgb, var(--accent) 13%, var(--c-white));
    --accent-ink:  color-mix(in srgb, var(--accent) var(--ink), var(--c-navy));
    /* derived from the normalised ink, not the raw accent: every
       hairline lands ~2:1 on white against the 1.23:1 of --border,
       so the brighten reads on all nine, not just the purple one. */
    --accent-line: color-mix(in srgb, var(--accent-ink) 45%, var(--c-white));
  }
}

/* ---------------- Footer row ---------------- */

.products__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s-2) var(--s-4);
  margin-top: var(--s-10);
  text-align: center;
}

.products__foot-q {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-body);              /* 7.38:1 on --surface-alt */
}

/* Modifier, not a restyle of the .arrow-link primitive. --c-brand is
   4.45:1 and --c-brand-hover 3.47:1 on --surface-alt; press holds 5.83:1
   in both states, so the hover state change is carried by the gap and an
   underline rather than a colour drop below AA. */
.products__link { color: var(--c-brand-press); min-height: 44px; }
.products__link:hover,
.products__link:focus-visible {
  color: var(--c-brand-press);
  text-decoration: underline;
  text-underline-offset: 0.22em;
}

/* ---------------- Reduced motion ---------------- */

@media (prefers-reduced-motion: reduce) {
  .products__card:hover,
  .products__card:focus-visible,
  .products__card:active { transform: none; }
  .products__card:hover .products__tile { transform: none; }
  .products__card--feature:hover .products__pay { transform: none; }
  .products__card:hover .products__cta,
  .products__card:focus-visible .products__cta { gap: var(--s-1); }
  .products__card::before { display: none; }
}
