.tier-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 820px) {
  /* Stretch, not start. With `align-items: start` each card took its natural
     height, which meant `.tier-features { flex: 1 }` had no slack to push the
     button down — so the three Choose buttons sat at 785px, 813px and 834px.
     A price comparison whose call to action is at three heights is harder to
     read than one that is not, for no reason at all. */
  .tier-grid { grid-template-columns: repeat(3, 1fr); }
}

.tier {
  padding: 24px 22px;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* On a phone the cards stack, and the one we recommend leads the stack
   rather than sitting between the other two. Visual order only: the page
   and its reading order are unchanged, and at three columns it keeps the
   middle, where a recommended card belongs. */
@media (max-width: 620px) {
  .tier.is-featured { order: -1; }
}

/* The one people are meant to pick, said with weight rather than with a
   colour nobody can read against. */
.tier.is-featured {
  border-color: rgba(37, 99, 235, 0.45);
  box-shadow:
    var(--elev-rim),
    0 18px 40px -16px var(--fill-brand-glow);
}

.tier-flag {
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 4px 12px;
  border-radius: var(--r-pill);
  color: #ffffff;
  background: linear-gradient(135deg, var(--fill-brand-from), var(--fill-brand-to));
  white-space: nowrap;
}

/* Name, price, rate and badges as one block, so the rule below it lands at
   the same height on all three cards. */
.tier-head {
  padding-bottom: 18px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--stage-border);
}

.tier-name {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* The number that is actually charged, and the loudest thing on the card. */
.tier-price {
  margin-top: 8px;
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.1;
  color: var(--text-primary);
}

/* The price before an offer link took its percentage off. Struck through and
   quiet, directly above the number that will actually be charged. */
.tier-list-price {
  margin-top: 8px;
  font-size: 15px;
  font-weight: 700;
  color: var(--text-tertiary);
  text-decoration: line-through;
}
.tier-list-price + .tier-price { margin-top: 0; }

/* What it works out at monthly. Quieter than the total — the total is what is
   charged, this is what makes three totals comparable. */
.tier-rate {
  margin-top: 3px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-tertiary);
  letter-spacing: 0;
}

/* A reserved row. The shortest package has no saving to show and the featured
   one carries an extra line, so the slot is held open on every card whether or
   not it has anything in it. Only at three columns: stacked on a phone there
   is nothing to line up with, and an empty 46px gap would just be a gap. */
.tier-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

@media (min-width: 820px) {
  .tier-badges { min-height: 24px; align-content: flex-start; }
  .tier.is-featured .tier-badges { min-height: 24px; }
}

/* align-self, because a flex child stretches to the cross axis by default and
   `display: inline-block` does nothing about it — this pill rendered as an
   87%-wide green bar. */
.tier-save {
  align-self: flex-start;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--success) 14%, transparent);
  font-size: 11px;
  font-weight: 750;
  line-height: 1.2;
  color: var(--success);
  white-space: nowrap;
}

.tier-trial {
  align-self: flex-start;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--ebid-primary);
}

.tier-features {
  list-style: none;
  padding: 0;
  margin: 0 0 20px;
  display: flex;
  flex-direction: column;
  gap: 9px;
  flex: 1;
}

.tier-features li {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-secondary);
}

.tier-features li::before {
  content: "✓";
  color: var(--success);
  font-weight: 800;
  flex: none;
  font-size: 12px;
  line-height: 1.5;
}

/* One height for both button variants. btn-ghost and btn-primary differ by
   2px in their own styles, which put the featured card's Choose button on its
   own baseline even after everything above it lined up. 44px is also the
   smallest thing worth asking a thumb to hit. */
.tier .btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* There is no struck-through row any more: every package holds the same
   thing, so every row on every card is a tick. */

/* Marks the package the account last bought. A tag rather than a disabled
   button: buying it again is how somebody renews, so the button stays live. */
.tier-current {
  margin: 0 0 8px;
  text-align: center;
  font-size: 11px;
  font-weight: 750;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* The payment history, under the tiers.
 *
 * GET /billing/history had worked since checkout was written and nothing had
 * ever called it, so a customer wanting proof of what they paid had to ask us
 * for it. Only settled payments are listed — a pending row is an abandoned
 * checkout, and showing it here invites a support call about money that never
 * left anybody's account. */
.pay-history {
  max-width: 560px;
  margin: var(--space-6) auto 0;
  padding: 18px 20px;
}

/* Paying by bank transfer (js/packages.js renderTransfer). The same card as
   the payment history, so the two read as one billing area. */
.pay-transfer {
  max-width: 560px;
  margin: var(--space-6) auto 0;
  padding: 18px 20px;
  font-size: 13px;
  line-height: 1.6;
}
.pay-transfer h2 {
  font-size: 13px;
  font-weight: 800;
  margin: 0 0 6px;
  color: var(--text-secondary);
}
.pay-transfer p { margin: 6px 0; }
.pay-transfer ul { list-style: none; margin: 10px 0; padding: 0; }
.pay-transfer li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-top: 1px solid var(--stage-border);
}
.pay-transfer li:first-child { border-top: 0; }
.pay-transfer code {
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
.pay-transfer a { color: var(--ebid-primary); font-weight: 700; }
.pay-history-how { font-weight: 500; color: var(--text-tertiary); }

.pay-history h2 {
  font-size: 13px;
  font-weight: 800;
  margin: 0 0 10px;
  color: var(--text-secondary);
}

.pay-history ul { list-style: none; margin: 0; padding: 0; }

.pay-history li {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: baseline;
  gap: 12px;
  padding: 9px 0;
  font-size: 13px;
  border-top: 1px solid var(--stage-border);
}
.pay-history li:first-child { border-top: 0; }

.pay-history-when {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--text-tertiary);
}
.pay-history-what { font-weight: 650; min-width: 0; }
.pay-history-amount { font-weight: 800; font-variant-numeric: tabular-nums; }
.pay-history a { color: var(--ebid-primary); font-weight: 700; font-size: 12px; }

/* Four columns do not fit a phone. The date and the receipt link drop to a
   second row rather than the amount shrinking to nothing. */
@media (max-width: 460px) {
  .pay-history li { grid-template-columns: 1fr auto; }
  .pay-history-when { grid-column: 1; order: 2; }
  .pay-history a { grid-column: 2; order: 3; text-align: right; }
}

/* The dock floats over the bottom of every page (position: fixed, no desktop
   breakpoint), so whatever ends a page sits underneath it. That was already
   true of the billing footnote here; a bordered card makes the collision
   obvious rather than merely untidy. Enough room for the dock plus its
   shadow. */
.packages-page { padding-bottom: 104px; }
