/* Purchase and license recovery pages. */
.commerce [hidden] { display: none !important; }

.commerce {
  min-height: 70vh;
  padding-block: clamp(3rem, 8vw, 6rem);
}

.commerce__layout {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(2.5rem, 7vw, 6rem);
  align-items: start;
}

.commerce__intro h1 {
  font-size: clamp(2.4rem, 6vw, 4rem);
  margin-bottom: 1.35rem;
}

.commerce__intro p { max-width: 38ch; color: var(--ink-dim); }
.commerce__intro .eyebrow { margin-bottom: 1.25rem; }
.commerce__mark { width: 72px; height: 72px; margin-bottom: 2rem; }

.commerce__panel {
  border-top: 1px solid var(--line-hi);
  padding-top: 1.75rem;
  min-width: 0;
}

.commerce__panel h2 { font-size: 1.3rem; margin-bottom: 1rem; }
/* /buy leads with the price, so it runs larger than the other panel heads.
   Has to beat ".commerce__panel h2" (0,1,1), hence the element in the
   selector -- a bare .commerce__price lost and silently stayed at 1.3rem. */
.commerce__panel h2.commerce__price { font-size: 1.8rem; }
/* Reserves two lines so the panel does not jump as the polling message
   changes length. (It only half works: the longest pending message is four
   lines and jumps anyway.) */
.commerce__status { min-height: 3.3em; }

/* Once the ready panel is up the status is final and one line, so stop
   reserving the second -- that was 28px of dead space under "Purchase
   complete." #purchase-ready comes AFTER the status in the DOM, so this
   needs :has(); there is no previous-sibling combinator. Engines without
   :has() simply keep the reserve. */
.commerce__panel:has(#purchase-ready:not([hidden])) .commerce__status {
  min-height: 0;
}

/* The intro promises two downloads that only exist once the licence resolves.
   /purchase is reachable without a valid token -- lost fragment, revisit,
   expired link -- and there the links pointed at hidden controls while the
   panel opposite told you to use your email instead. #purchase-ready lives in
   the other column, so this keys off the shared layout wrapper rather than a
   sibling. Without :has() the ready copy shows, which is the old behaviour. */
.purchase-intro--pending { display: none; }

.commerce__layout:not(:has(#purchase-ready:not([hidden]))) .purchase-intro--ready {
  display: none;
}

.commerce__layout:not(:has(#purchase-ready:not([hidden]))) .purchase-intro--pending {
  display: block;
}
[data-commerce-page="buy"] .commerce__status:empty { display: none; }
.commerce__status:focus { outline: none; }
.commerce__countdown { color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.commerce__actions { display: flex; gap: 1.25rem; flex-wrap: wrap; margin-block: 1.75rem; }
.commerce .btn { padding: 0.35rem 0.55rem; white-space: normal; }
.commerce .btn:disabled { cursor: wait; opacity: 0.55; }
.commerce button.btn-pixel-box[disabled] { cursor: wait; }
/* The App Store route sits OUTSIDE #checkout-details deliberately. commerce.js
   only unhides that block once it has confirmed availability, so with checkout
   disabled or the config request failing the buyer was left with a status
   message and no way to buy at all. A fallback must not share the gate it is a
   fallback for. It is also the only purchase route with JavaScript off, where
   #checkout-details never unhides.

   1rem under the label clears Apple's stated clear space (a quarter of the
   badge height, 13.75px at 55px) on the tight side; the 1.75rem block margins
   clear it everywhere else. */
.commerce__alt { margin-block: 1.75rem; }
.commerce__alt-head { margin-bottom: 1rem; }

.commerce__secondary { margin-top: 2rem; color: var(--ink-dim); }
.commerce__secondary a { white-space: normal; }
.commerce__note { color: var(--ink-dim); font-size: 0.9375rem; }
.commerce__countries { margin-block: 0.75rem 1.5rem; font-size: 0.9375rem; }
.commerce__countries summary { cursor: pointer; text-decoration: underline; text-underline-offset: 0.2em; }
.commerce__countries ul { columns: 2; column-gap: 1.5rem; padding-left: 1.25rem; margin-top: 1rem; }
.commerce__countries li { break-inside: avoid; margin-bottom: 0.35rem; }
.commerce__registered { overflow-wrap: anywhere; }
.commerce__steps { padding-left: 1.4rem; margin-block: 1.5rem; }
.commerce__steps li { padding-left: 0.2rem; margin-bottom: 0.8rem; }
.commerce .field input { min-height: 48px; }
.commerce .field label { color: var(--ink-dim); }
.commerce__footer { display: flex; flex-wrap: wrap; gap: 0.8rem 1.5rem; }

@media (max-width: 760px) {
  .commerce__layout { grid-template-columns: 1fr; }
  .commerce__mark { width: 56px; height: 56px; margin-bottom: 1.5rem; }
  .commerce__intro p { max-width: none; }
}

/* Windows interest list. Shares the commerce field styling so the one input
   matches the recover form rather than inventing a second look. */
.notify { margin-block: 1.5rem; }
.notify .field { max-width: 26rem; margin-bottom: 1rem; }
.notify__purpose { margin-top: 0.9rem; max-width: 34rem; }
.notify .commerce__status { min-height: 0; margin-top: 0.75rem; }

/* .btn carries no chrome of its own -- it is text-decoration plus a blur, meant
   for links. The pixel buttons are fixed artwork reading "Buy Now", so neither
   is usable here. This is the plain monochrome equivalent, weighted to match
   Buy Direct so the one action on the page reads as an action. */
.notify__submit {
  appearance: none;
  -webkit-appearance: none;
  display: inline-block;
  min-height: 48px;
  padding: 0 1.5rem;
  border: 0;
  border-radius: 4px;
  background: var(--ink-hi);
  color: #000;
  font-family: var(--font-fig-mono);
  font-weight: 700;
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.notify__submit:hover { background: var(--ink); }
.notify__submit:focus-visible { outline: 2px solid var(--ink-hi); outline-offset: 3px; }
.notify__submit[disabled] { cursor: wait; opacity: 0.55; }
.hero__platform {
  max-width: 34rem;
  margin: 0 auto 1.25rem;
  color: var(--ink-dim);
  font-size: 0.9375rem;
}
