/* THE BUY UNIT — one component, two placements.
 *
 * The same markup is a fixed bottom bar on mobile and a sticky right sidebar on
 * desktop. Emitting it once and moving it with CSS is the point: two copies
 * would eventually disagree about the score or the price.
 */

.buy {
  --buy-bg: var(--card, #fff);
  --buy-line: var(--line, #e5e7eb);
  --buy-ink: var(--ink, #111827);
  --buy-mute: var(--mute, #6b7280);
  /* --accent is not a token in guide.css; the site's is --green. This resolved
   * to the fallback teal on every review page, so the primary call to action was
   * a different green from the rest of the site. */
  --buy-accent: var(--green, #12684A);
}
[data-theme="dark"] .buy { --buy-bg: #16181d; --buy-line: #2a2e37; --buy-ink: #e8eaee; --buy-mute: #9aa2b1; }
/* --green inverts to a light mint in dark mode, so white-on-green would fail
 * contrast on the one element that must never be hard to read. Same treatment
 * guide.css already uses for .brand__mark: keep the light green, darken the
 * label. */
[data-theme="dark"] .buy__cta { color: #08251A; }

.buy__inner { display: flex; align-items: center; gap: 14px; }
.buy__score { display: flex; flex-direction: column; align-items: center; line-height: 1; flex: none; }
.buy__num { font-size: 30px; font-weight: 800; color: var(--buy-ink); letter-spacing: -0.02em; }
.buy__of { font-size: 9px; text-transform: uppercase; letter-spacing: 0.09em; color: var(--buy-mute); margin-top: 3px; white-space: nowrap; }
.buy__body { min-width: 0; flex: 1; }
.buy__price { margin: 0; font-size: 17px; font-weight: 700; color: var(--buy-ink); }
.buy__facts { margin: 0; display: none; }
.buy__cta {
  display: block; text-align: center; background: var(--buy-accent); color: #fff;
  font-weight: 700; font-size: 15px; text-decoration: none; border-radius: 10px;
  padding: 13px 18px; line-height: 1.2; white-space: nowrap;
}
.buy__cta:hover { filter: brightness(1.07); }
.buy__cta:focus-visible { outline: 3px solid var(--buy-accent); outline-offset: 2px; }
/* Always visible, both viewports. Small and quiet, but it must READ — the
 * relationship is stated here, not deferred to the /disclosure click. */
.buy__disc { margin: 8px 0 0; font-size: 11.5px; line-height: 1.4; color: var(--buy-mute); }
.buy__disc a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.buy__disc a:hover { color: var(--buy-accent); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- MOBILE: fixed bottom bar ---------- */
@media (max-width: 979px) {
  .buy {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    background: var(--buy-bg); border-top: 1px solid var(--buy-line);
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -6px 24px rgba(0,0,0,.10);
  }
  /* TWO elements in the bar: score and button. The price is deliberately NOT
     here - it lives in the spec table and the review body, and duplicating it
     next to a "check current price" button was both crowded and slightly
     self-contradictory. With only two children there is room for the full
     button label at 390px. */
  .buy__body { display: none; }
  .buy__inner { gap: 12px; justify-content: space-between; }
  .buy__act { flex: 1 1 auto; min-width: 0; }
  /* The label must never truncate. Brand names vary a lot - "Amazon" is 29
     characters in the label, "Ariel Rider" is 34 - so at narrow widths the text
     WRAPS rather than being clipped or ellipsised. A cut-off call to action
     reads as broken, and an ellipsised one hides which retailer you are about
     to be sent to, which is the one thing the button has to be honest about. */
  .buy__cta { padding: 11px 12px; font-size: 13.5px; line-height: 1.25; white-space: normal; }
  .buy__disc { font-size: 11px; margin-top: 7px; }
  /* Keep the bar from covering the end of the article. */
  body { padding-bottom: 108px; }
}

/* ---------- DESKTOP: sticky right sidebar ---------- */
@media (min-width: 980px) {
  main.has-buy { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 40px; align-items: start; }
  main.has-buy > .read { grid-column: 1; }
  .buy {
    grid-column: 2; grid-row: 1; position: sticky; top: 88px;
    background: var(--buy-bg); border: 1px solid var(--buy-line); border-radius: 14px;
    padding: 18px; box-shadow: 0 2px 14px rgba(0,0,0,.05);
  }
  .buy__inner { flex-direction: column; align-items: stretch; gap: 14px; }
  .buy__score { flex-direction: row; align-items: baseline; gap: 8px; }
  .buy__num { font-size: 40px; }
  .buy__of { font-size: 10px; margin-top: 0; }
  .buy__price { font-size: 20px; margin-bottom: 2px; }
  .buy__asof { display: block; margin-top: 2px; }
  /* The sidebar has room for the decision specs; the mobile bar does not. */
  .buy__facts { display: block; margin-top: 12px; border-top: 1px solid var(--buy-line); padding-top: 12px; }
  .buy__facts > div { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; font-size: 13px; }
  .buy__facts dt { color: var(--buy-mute); }
  .buy__facts dd { margin: 0; font-weight: 600; color: var(--buy-ink); text-align: right; }
}
