/* ============================================================
   Checkout — layout and payment UI.

   Built entirely on the tokens already in styles.css: --navy,
   --border, --paper, --muted, --r-md, --s-*, --shadow-sm. No new
   colours, no new radii, no new shadows. A payment page that looks
   like a different website is the opposite of reassuring.

   Kept in its own file because only two pages load it. The other
   eighty have no reason to download checkout styles.
   ============================================================ */

/* ------------------------------------------------- hidden wins ---- */

/* The `hidden` attribute works by a UA rule of display:none, which ANY
   author rule setting display beats. .co-alert is display:flex, so the
   error box rendered as an empty pink bar under the total on every
   visit — permanently, on a payment page, which reads as "something is
   wrong here" before the customer has done anything.
   Same trap for .btn (inline-flex) on the hidden Try-again button.
   One rule, applied first, so it cannot happen again on this page. */
[hidden] { display: none !important; }

/* ---------------------------------------------------------- layout */

.co-grid {
  display: grid;
  gap: var(--s-lg);
  align-items: start;
}

/* Two columns only when there is genuinely room. Below this the
   summary sits under the form, which is the order you want on a
   phone: decide, then confirm, then pay. */
@media (min-width: 900px) {
  .co-grid {
    grid-template-columns: minmax(0, 1.35fr) minmax(320px, 1fr);
    gap: var(--s-xl);
  }
  /* The summary follows you down the page on desktop, so the total
     and the Pay button are never scrolled away from. */
  .co-aside { position: sticky; top: var(--s-lg); }
}

.co-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--s-lg);
  margin-bottom: var(--s-md);
}

.co-card + .co-card { margin-top: 0; }

.co-card-head { margin-bottom: var(--s-md); }

.co-card-head h2 {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--charcoal);
  margin: 0;
  letter-spacing: -0.01em;
}

.co-card-head p {
  font-size: .9rem;
  color: var(--muted);
  margin: 4px 0 0;
}

/* Numbered steps. Cheap to render, and it tells someone at a glance
   how many things are left before they are done. */
.co-step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  margin-right: 10px;
  border-radius: var(--r-pill);
  background: var(--navy);
  color: var(--white);
  font-size: .78rem;
  font-weight: 700;
  vertical-align: 2px;
}

/* ---------------------------------------------------------- fields */

.co-field { margin-bottom: var(--s-md); }
.co-field:last-child { margin-bottom: 0; }

.co-field label {
  display: block;
  font-size: .85rem;
  font-weight: 600;
  color: var(--charcoal);
  margin-bottom: 6px;
}

.co-input {
  width: 100%;
  padding: 12px 14px;
  font: inherit;
  font-size: 1rem;              /* 16px: anything smaller makes iOS
                                   zoom the whole page on focus */
  color: var(--charcoal);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  transition: border-color .15s ease, box-shadow .15s ease;
}

.co-input::placeholder { color: #9AA4B5; }

.co-input:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(13, 27, 82, 0.10);
}

/* Invalid state carries a border colour AND the message below, never
   colour alone — that is unreadable to anyone who cannot see red. */
.co-input[aria-invalid="true"] {
  border-color: var(--red);
}

.co-hint {
  display: block;
  font-size: .85rem;
  color: var(--muted);
  margin-top: 6px;
}

.co-hint.is-error { color: var(--red); font-weight: 600; }
.co-hint.is-ok    { color: var(--success); font-weight: 600; }

/* "We changed your selection." Amber and boxed, because this is the one
   message on the page the customer must not skim past — green would
   read as "fine, carry on" and grey would disappear. */
.co-hint.is-note {
  color: #8A5A16;
  background: #FDF4E6;
  border: 1px solid #F3DFBC;
  border-radius: var(--r-sm);
  padding: 9px 11px;
  font-weight: 500;
  line-height: 1.45;
}

textarea.co-input { resize: vertical; min-height: 78px; }

/* ------------------------------------------------- payment methods */

.co-methods {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-sm);
  margin: 0;
  padding: 0;
  border: 0;
  /* A <fieldset> defaults to min-width:min-content, which stops it
     shrinking below the widest thing inside and pushes a horizontal
     scrollbar onto narrow phones. Measured: it really is min-content
     here. This is the standard fix and it is only needed because these
     are real radios in a real fieldset - which is what makes the picker
     work with a keyboard and a screen reader. */
  min-width: 0;
}

/* Three across is fine down to about 340px because the labels are
   short. Stacking them would push the Pay button off a phone screen
   for no benefit. */
@media (max-width: 380px) {
  .co-methods { gap: 6px; }
}

.co-method {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 8px;
  text-align: center;
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}

.co-method:hover { border-color: #C3CDDE; }

/* The real radio sits on top, invisible but full-size, so the whole
   card is the hit target and keyboard/screen-reader behaviour stays
   native. Reimplementing radios with divs and JS is how checkouts
   become unusable with a keyboard. */
.co-method input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.co-method-name {
  font-size: .92rem;
  font-weight: 700;
  color: var(--charcoal);
  line-height: 1.2;
}

.co-method-sub {
  font-size: .75rem;
  color: var(--muted);
}

.co-method-mark {
  width: 26px; height: 26px;
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  background: var(--paper-dim);
  color: var(--navy);
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .02em;
}

/* Selected state: border, tint, AND a filled mark. Three signals, so
   it survives colour-blindness and a bad screen in bright sun. */
.co-method:has(input:checked) {
  border-color: var(--navy);
  background: var(--paper);
}

.co-method:has(input:checked) .co-method-mark {
  background: var(--navy);
  color: var(--white);
}

.co-method:has(input:focus-visible) {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

/* Flash the card the code just selected on the customer's behalf, so
   the change is seen and not merely stated. Motion is the enhancement;
   the amber note carries the meaning without it. */
.co-method.is-switched { animation: co-flash 1.2s ease-out 1; }

@keyframes co-flash {
  0%, 100% { box-shadow: 0 0 0 0 rgba(232, 163, 61, 0); }
  15%      { box-shadow: 0 0 0 4px rgba(232, 163, 61, 0.55); }
  70%      { box-shadow: 0 0 0 4px rgba(232, 163, 61, 0.25); }
}

@media (prefers-reduced-motion: reduce) {
  .co-method.is-switched { animation: none; box-shadow: 0 0 0 3px rgba(232, 163, 61, 0.45); }
}

/* ------------------------------------------------------- summary */

.co-sum-line {
  display: flex;
  justify-content: space-between;
  gap: var(--s-md);
  padding: 8px 0;
  font-size: .95rem;
}

.co-sum-line .co-sum-name { color: var(--charcoal); }
.co-sum-line .co-sum-qty  { color: var(--muted); font-style: normal; }
.co-sum-line .co-sum-val  { font-variant-numeric: tabular-nums; white-space: nowrap; }

.co-sum-rule { border: 0; border-top: 1px solid var(--border); margin: var(--s-sm) 0; }

.co-sum-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s-md);
  padding-top: var(--s-sm);
}

.co-sum-total span { font-weight: 700; color: var(--charcoal); }

.co-sum-total strong {
  font-size: 1.6rem;
  font-weight: 800;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

/* --------------------------------------------------------- the CTA */

.co-pay {
  width: 100%;
  margin-top: var(--s-md);
  padding: 15px 20px;
  font: inherit;
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--white);
  background: var(--navy);
  border: 0;
  border-radius: var(--r-md);
  cursor: pointer;
  transition: background .15s ease;
}

.co-pay:hover:not(:disabled) { background: var(--navy-dark); }

.co-pay:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px; }

/* Disabled is deliberately obvious. A Pay button that looks clickable
   while a charge is in flight is how customers pay twice. */
.co-pay:disabled {
  background: #9AA4B5;
  cursor: not-allowed;
}

.co-trust {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-top: var(--s-sm);
  font-size: .82rem;
  color: var(--muted);
  text-align: center;
}

.co-trust svg { width: 14px; height: 14px; flex: none; }

/* ------------------------------------------------------- statuses */

.co-state { text-align: center; padding: var(--s-xl) var(--s-lg); }

.co-state-icon {
  width: 52px; height: 52px;
  margin: 0 auto var(--s-md);
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
}

.co-state-icon svg { width: 26px; height: 26px; }

.co-state-icon.is-success { background: #E7F6ED; color: var(--success); }
.co-state-icon.is-failed  { background: #FDECEE; color: var(--red); }
.co-state-icon.is-pending { background: #FDF4E6; color: var(--amber); }
.co-state-icon.is-working { background: var(--paper-dim); color: var(--navy); }

.co-state h2 {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--charcoal);
  margin: 0 0 8px;
}

.co-state p {
  color: var(--muted);
  margin: 0 auto var(--s-md);
  max-width: 42ch;
}

/* Receipt rows on the success screen. */
.co-receipt {
  text-align: left;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--s-md);
  margin: var(--s-md) 0;
}

.co-receipt div {
  display: flex;
  justify-content: space-between;
  gap: var(--s-md);
  padding: 6px 0;
  font-size: .92rem;
}

.co-receipt dt { color: var(--muted); margin: 0; }
.co-receipt dd { margin: 0; font-weight: 600; color: var(--charcoal); text-align: right; }

/* A spinner that respects reduced-motion: people who get motion sick
   from spinners still need to know something is happening, so the
   text does that job and the animation simply stops. */
.co-spin {
  width: 26px; height: 26px;
  border: 2.5px solid var(--border);
  border-top-color: var(--navy);
  border-radius: var(--r-pill);
  animation: co-spin 0.8s linear infinite;
}

@keyframes co-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .co-spin { animation: none; }
}

.co-alert {
  display: flex;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--r-sm);
  font-size: .92rem;
  margin-bottom: var(--s-md);
  background: #FDECEE;
  border: 1px solid #F7CDD2;
  color: #8E2733;
}

.co-alert svg { width: 17px; height: 17px; flex: none; margin-top: 1px; }

/* -------------------------------------------------- order history */

.ord {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--s-md);
  margin-bottom: var(--s-sm);
  background: var(--white);
}

.ord:last-child { margin-bottom: 0; }

.ord-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-sm);
  flex-wrap: wrap;
}

.ord-ref {
  font-family: var(--font-mono);
  font-size: .86rem;
  font-weight: 600;
  color: var(--charcoal);
}

.ord-badge {
  font-size: .74rem;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  white-space: nowrap;
}

/* Each badge carries its own word, so the colour is decoration rather
   than the message — "Paid" and "Payment failed" read the same in
   greyscale. */
.ord-badge.is-ok    { background: #E7F6ED; color: #14713C; }
.ord-badge.is-warn  { background: #FDF4E6; color: #8A5A16; }
.ord-badge.is-bad   { background: #FDECEE; color: #8E2733; }
.ord-badge.is-muted { background: var(--paper-dim); color: var(--muted); }

.ord-items {
  margin: 8px 0 0;
  font-size: .92rem;
  color: var(--charcoal);
}

.ord-meta {
  display: flex;
  justify-content: space-between;
  gap: var(--s-sm);
  margin-top: 8px;
  font-size: .88rem;
  color: var(--muted);
}

.ord-meta span:last-child {
  font-weight: 700;
  color: var(--charcoal);
  font-variant-numeric: tabular-nums;
}

.ord-note {
  margin: 6px 0 0;
  font-size: .84rem;
  color: var(--muted);
}
