/* ============================================================================
   SHOP — product page and checkout modal.

   Tokens come from moonieful-brand.css, which is loaded first. Nothing here
   redefines a colour; it only uses them. The four brand rules still apply:
   gold is never a word, --accent is 24px-and-up only, body copy is --ink, and
   small text on a teal band uses --on-teal.

   External file, not a <style> block, so the page's CSP needs no
   'unsafe-inline' in style-src beyond what Stripe's Element already requires.
   ========================================================================== */

/* ------------------------------------------------------------- shell ---- */
.shop-wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }

.shop-header {
  padding: 22px 0;
  border-bottom: 1px solid var(--line-soft);
}
.shop-header-inner {
  max-width: var(--wrap); margin: 0 auto; padding: 0 20px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.shop-brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.shop-brand img { height: 38px; width: auto; }
.shop-brand-name {
  font-family: var(--font-head); font-size: 1.25rem; font-weight: 700;
  color: var(--teal-deep); line-height: 1;
}
.shop-back { font-size: .92rem; color: var(--ink-soft); text-decoration: none; }
.shop-back:hover { color: var(--teal-deep); text-decoration: underline; }

/* ------------------------------------------------------------ product --- */
.product {
  display: grid; grid-template-columns: 1fr 1fr; gap: 56px;
  align-items: start;
  padding: 56px 0 40px;
}
@media (max-width: 880px) {
  .product { grid-template-columns: 1fr; gap: 32px; padding: 32px 0 24px; }
}

.product-cover {
  background: var(--aqua-pale);
  border-radius: var(--radius);
  padding: 32px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow);
}
.product-cover img { max-width: 100%; height: auto; border-radius: 6px; box-shadow: var(--shadow-lift); }
.product-cover-placeholder {
  font-family: var(--font-head); font-size: 1.6rem; color: var(--teal-deep);
  text-align: center; line-height: 1.3; padding: 60px 20px;
}

.product h1 {
  font-family: var(--font-head);
  font-size: clamp(2rem, 4.5vw, 2.9rem);
  font-weight: 700; color: var(--ink);
  line-height: 1.1; margin: 0 0 14px;
}
.product-desc { font-size: 1.05rem; line-height: 1.75; color: var(--ink-soft); max-width: var(--measure); }
.product-desc p { margin: 0 0 14px; }

.product-price {
  display: flex; align-items: baseline; gap: 12px;
  margin: 24px 0 6px;
}
.product-price-now {
  font-family: var(--font-head); font-size: 2.1rem; font-weight: 700;
  color: var(--teal-deep); line-height: 1;
}
.product-price-was {
  font-size: 1.1rem; color: var(--ink-soft); text-decoration: line-through;
}

.product-specs {
  list-style: none; padding: 0; margin: 22px 0 0;
  display: flex; flex-wrap: wrap; gap: 8px;
}
.product-specs li {
  font-size: .84rem; color: var(--ink-soft);
  background: var(--aqua-pale);
  border: 1px solid var(--line-soft);
  border-radius: 999px; padding: 6px 13px;
}

/* --------------------------------------------------------------- CTA ---- */
.btn-buy {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--teal-deep); color: var(--white);
  font-family: var(--font-body); font-size: 1.02rem; font-weight: 700;
  border: 2px solid var(--teal-deep); border-radius: 999px;
  padding: 15px 34px; min-height: 52px;
  cursor: pointer; text-decoration: none;
  margin-top: 26px;
  transition: background-color .18s, border-color .18s;
}
.btn-buy:hover { background: #0a5555; border-color: #0a5555; color: var(--white); }
.btn-buy:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.btn-buy[disabled] { opacity: .5; cursor: not-allowed; }

.shop-closed {
  margin-top: 26px; padding: 16px 20px;
  background: var(--warn-bg);
  border-left: 4px solid var(--warn);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--warn); font-weight: 600; font-size: .97rem;
  max-width: var(--measure);
}

/* ----------------------------------------------------------- editions ---- */
/* One card per format. Side by side where there is room, stacked on a phone.
   A single edition gets no card chrome at all, so the page looks exactly as it
   did before the paperback existed. */
.editions-multi {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px; margin-top: 26px;
}
.editions-multi .edition {
  padding: 18px 20px 22px;
  border: 1px solid rgba(14,107,107,.18);
  border-radius: 12px;
  background: #fff;
}
.editions-multi .edition .product-price { margin-top: 0; }
.editions-multi .btn-buy { margin-top: 18px; width: 100%; padding: 14px 20px; }

.edition-format {
  font-family: var(--font-display, inherit);
  font-size: .78rem; font-weight: 700; letter-spacing: 1.1px;
  text-transform: uppercase; color: var(--teal-deep);
  margin-bottom: 8px;
}

/* ------------------------------------------------ quantity (physical) ---- */
.product-qty {
  display: flex; align-items: center; gap: 10px;
  margin-top: 22px;
}
.product-qty label { font-weight: 700; font-size: .95rem; color: var(--ink); }
.product-qty input {
  width: 78px; min-height: 44px;      /* 44px: WCAG 2.2 AA target size */
  padding: 8px 10px; font-size: 1rem; font-family: var(--font-body);
  border: 1px solid rgba(14,107,107,.22); border-radius: 8px;
  background: #fff; color: var(--ink);
}
.product-qty input:focus { outline: 2px solid var(--teal-deep); outline-offset: 1px; }

.product-shipping-note {
  margin-top: 10px; font-size: .88rem; color: var(--ink-soft);
}

/* --------------------------------------------------- test-mode banner ---- */
/* Same warn pair as .shop-closed above: --warn on --warn-bg measures 5.29:1, so
   this reads at AA even though it is the "quiet" yellow. Gold is never used for
   text anywhere on the site. Appears above the card fields, and on the product
   page under the buy button, whenever Stripe test keys are in play. */
.shop-testbar {
  margin: 20px 0 4px;
  padding: 12px 15px;
  background: var(--warn-bg);
  border-left: 4px solid var(--warn);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--warn);
  font-size: .88rem; line-height: 1.5;
  max-width: var(--measure);
}
.shop-testbar strong { font-weight: 700; }

/* ------------------------------------------------------------- modal ---- */
.checkout-modal {
  border: none; padding: 0; background: transparent;
  max-width: 480px; width: calc(100% - 24px);
  max-height: calc(100vh - 32px);
}
.checkout-modal::backdrop { background: rgba(36,52,52,.6); backdrop-filter: blur(4px); }

/* The dialog scrolls whenever the payment form is taller than the viewport.
   Left alone, Windows draws a square grey bar with an arrow button at each end,
   which reads as pasted-on next to the card's rounded corners. A fully rounded
   thumb (radius 999px caps both ends), no buttons, and a transparent track in
   the brand teal instead. Firefox gets the same via scrollbar-width/color; it
   has no equivalent of the ::-webkit- pseudo-elements. */
.checkout-modal {
  scrollbar-width: thin;
  scrollbar-color: rgba(14,107,107,.38) transparent;
}
.checkout-modal::-webkit-scrollbar { width: 10px; }
.checkout-modal::-webkit-scrollbar-track { background: transparent; }
.checkout-modal::-webkit-scrollbar-thumb {
  background: rgba(14,107,107,.38);
  border-radius: 999px;
  /* Inset the thumb without shrinking the hit area: the border stays part of
     the element, background-clip just keeps the paint off it. */
  border: 2px solid transparent;
  background-clip: content-box;
}
.checkout-modal::-webkit-scrollbar-thumb:hover {
  background: rgba(14,107,107,.60);
  background-clip: content-box;
}
/* The little up/down arrows at each end; removing them is what lets the thumb
   run the full track and keeps both ends rounded. */
.checkout-modal::-webkit-scrollbar-button { display: none; }

.checkout-card {
  background: var(--page);
  border-radius: var(--radius);
  padding: 26px 28px 24px;
  box-shadow: var(--shadow-lift);
}
@media (max-width: 480px) { .checkout-card { padding: 20px 18px 18px; } }

.checkout-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  margin-bottom: 4px;
}
.checkout-title {
  font-family: var(--font-head); font-size: 1.35rem; font-weight: 700;
  color: var(--ink); line-height: 1.2;
}
.checkout-sub { font-size: .9rem; color: var(--ink-soft); margin-top: 2px; }

.checkout-close {
  background: none; border: none; cursor: pointer;
  color: var(--ink-soft); font-size: 1.5rem; line-height: 1;
  padding: 4px 8px; border-radius: var(--radius-sm);
  min-width: 40px; min-height: 40px;
}
.checkout-close:hover { background: var(--aqua-pale); color: var(--ink); }
.checkout-close:focus-visible { outline: 2px solid var(--teal-deep); outline-offset: 2px; }

.checkout-field { margin-top: 16px; }
.checkout-field label {
  display: block; font-size: .87rem; font-weight: 700;
  color: var(--ink); margin-bottom: 6px;
}
.checkout-field input[type="email"],
.checkout-field input[type="text"] {
  width: 100%;
  font-family: var(--font-body); font-size: 1rem;
  color: var(--ink); background: var(--page);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px 14px; min-height: 46px;
}
.checkout-field input:focus {
  border-color: var(--teal-deep);
  outline: 2px solid rgba(14,107,107,.28); outline-offset: 1px;
}
.checkout-field input[aria-invalid="true"] { border-color: var(--danger); }

/* ------------------------------------------- address & delivery speed ---- */
/* Same input rules as the fields above, extended to the types the address
   block uses. Kept as one selector list rather than a new class so the two
   halves of the form cannot drift apart visually. */
.checkout-field input[type="tel"],
.checkout-field input[type="number"],
.checkout-field select {
  width: 100%;
  font-family: var(--font-body); font-size: 1rem;
  color: var(--ink); background: var(--page);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px 14px; min-height: 46px;
}
.checkout-field select:focus {
  border-color: var(--teal-deep);
  outline: 2px solid rgba(14,107,107,.28); outline-offset: 1px;
}

.checkout-section-title {
  margin-top: 22px; padding-top: 16px;
  border-top: 1px solid var(--line-soft);
  font-weight: 700; font-size: .95rem; color: var(--ink);
}

.checkout-optional { font-weight: 400; color: var(--ink-soft); }

.checkout-hint { margin-top: 10px; font-size: .86rem; color: var(--ink-soft); }

/* Two fields side by side, stacking on a narrow phone rather than squeezing —
   a 2-character state field next to a ZIP is unusable at 320px. */
.checkout-row-fields { display: flex; gap: 12px; }
.checkout-row-fields .checkout-field { flex: 1; min-width: 0; }
@media (max-width: 400px) {
  .checkout-row-fields { display: block; }
}

.shipping-options { margin-top: 10px; }
.shipping-option {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; margin-bottom: 8px;
  min-height: 48px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-size: .93rem; color: var(--ink); cursor: pointer;
}
.shipping-option:hover { border-color: var(--teal-deep); }
.shipping-option input { accent-color: var(--teal-deep); width: 18px; height: 18px; flex-shrink: 0; }
.shipping-option:has(input:checked) {
  border-color: var(--teal-deep);
  background: var(--aqua-pale);
}
.shipping-option:focus-within { outline: 2px solid rgba(14,107,107,.28); outline-offset: 1px; }
.shipping-option-price { margin-left: auto; color: var(--teal-deep); white-space: nowrap; }

.checkout-consent {
  display: flex; align-items: flex-start; gap: 9px;
  margin-top: 16px; font-size: .88rem; color: var(--ink-soft); line-height: 1.5;
}
.checkout-consent input { accent-color: var(--teal-deep); width: 17px; height: 17px; margin-top: 2px; flex-shrink: 0; }

/* Stripe mounts its iframe in here. It inherits the fonts and colours passed
   to Elements in checkout.js, so it reads as part of this form. */
#payment-element { margin-top: 18px; min-height: 40px; }

.checkout-summary {
  margin-top: 20px; padding-top: 14px;
  border-top: 1px solid var(--line-soft);
  font-size: .95rem;
}
.checkout-row { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; color: var(--ink-soft); }
/* Without this, `display: flex` above beats the browser's own
   `[hidden] { display: none }` — author styles outrank the UA stylesheet — and
   the shipping, tax and processing-fee rows stay on screen showing $0.00 (or
   worse, a stale figure from the last thing you looked at) on a cart that has
   none of them. Every row the JS hides needs this. */
.checkout-row[hidden] { display: none; }
.checkout-row-total {
  font-weight: 700; color: var(--ink); font-size: 1.08rem;
  padding-top: 10px; margin-top: 6px;
  border-top: 1px solid var(--line-soft);
}
.checkout-row-total span:last-child { color: var(--teal-deep); }

.btn-pay {
  width: 100%; margin-top: 18px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--teal-deep); color: var(--white);
  font-family: var(--font-body); font-size: 1.02rem; font-weight: 700;
  border: 2px solid var(--teal-deep); border-radius: 999px;
  padding: 14px 28px; min-height: 52px; cursor: pointer;
}
.btn-pay:hover:not([disabled]) { background: #0a5555; border-color: #0a5555; }
.btn-pay:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.btn-pay[disabled] { opacity: .55; cursor: not-allowed; }

.checkout-error {
  margin-top: 14px; padding: 11px 14px;
  background: var(--danger-bg); border-left: 4px solid var(--danger);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--danger); font-size: .9rem; font-weight: 600;
}
.checkout-error[hidden] { display: none; }

.checkout-trust {
  margin-top: 14px; text-align: center;
  font-size: .8rem; color: var(--ink-soft); line-height: 1.5;
}

/* Spinner on the pay button. Not colour-only: the label changes too. */
.spinner {
  width: 16px; height: 16px; flex-shrink: 0;
  border: 2px solid rgba(255,255,255,.4);
  border-top-color: var(--white);
  border-radius: 50%;
  animation: shop-spin .7s linear infinite;
}
@keyframes shop-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 2.4s; } }

/* ------------------------------------------------------- thank you ------ */
.thanks { max-width: 640px; margin: 0 auto; padding: 56px 20px; text-align: center; }
.thanks h1 {
  font-family: var(--font-head); font-size: clamp(1.9rem, 4vw, 2.6rem);
  font-weight: 700; color: var(--ink); margin: 0 0 12px; line-height: 1.15;
}
.thanks-lead { font-size: 1.05rem; color: var(--ink-soft); line-height: 1.7; margin: 0 0 8px; }
.thanks-order {
  display: inline-block; margin: 14px 0 26px;
  background: var(--aqua-pale); border: 1px solid var(--line-soft);
  border-radius: 999px; padding: 7px 18px;
  font-size: .92rem; color: var(--ink); font-weight: 700;
}
.thanks-panel {
  background: var(--page); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 26px 24px;
  box-shadow: var(--shadow); text-align: left;
}
.thanks-panel h2 {
  font-family: var(--font-head); font-size: 1.15rem; color: var(--ink);
  margin: 0 0 10px; font-weight: 700;
}
.thanks-status { display: flex; align-items: center; gap: 10px; color: var(--ink-soft); font-size: .95rem; }
/* display:flex above beats the browser's [hidden]{display:none}, so
   order-status.js setting .hidden = true did nothing and "Preparing your
   file…" kept spinning underneath "Ready. Your personal copy is below."
   Same fix as .checkout-error[hidden] further up. */
.thanks-status[hidden] { display: none; }
.thanks-status .spinner { border-color: rgba(14,107,107,.25); border-top-color: var(--teal-deep); }

.btn-download {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  background: var(--teal-deep); color: var(--white);
  font-size: 1rem; font-weight: 700;
  border: 2px solid var(--teal-deep); border-radius: 999px;
  padding: 14px 28px; min-height: 52px;
  text-decoration: none; margin-top: 12px;
}
.btn-download:hover { background: #0a5555; border-color: #0a5555; color: var(--white); }
.btn-download:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

.thanks-note { font-size: .88rem; color: var(--ink-soft); margin-top: 16px; line-height: 1.6; }

/* The "check your spam folder" line used to be .thanks-note — .88rem in muted
   grey, at the bottom of the panel. Receipts from moonieful.com do land in spam
   (the domain is not yet DKIM-authenticated with SendGrid), and buyers were
   missing the line entirely. Full-size text on a tinted card instead, so the
   one instruction that gets them to their receipt is not the faintest thing
   on the page. */
.thanks-spam {
  margin-top: 16px; padding: 12px 14px;
  background: var(--aqua-pale);
  border-left: 4px solid var(--teal-deep);
  border-radius: var(--radius-sm);
  font-size: .95rem; color: var(--ink); line-height: 1.6;
}

.thanks-problem {
  background: var(--warn-bg); border-left: 4px solid var(--warn);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 14px 18px; color: var(--warn); font-weight: 600;
  font-size: .95rem; text-align: left; line-height: 1.6;
}
