/* pay.css — the commerce surface, shared by every record site.
 *
 * WHY THIS FILE EXISTS. The checkout modal, the premium star and the locked-field affordance were
 * copy-pasted into three brand stylesheets and had drifted: PermitWatch said "Unlock", CarrierHelm
 * said "Premium", ModelWatch said "Subscribers only", and the three `.pay__*` blocks disagreed on
 * geometry badly enough that chrome.js had to inject an inline <style> at render time to override
 * whichever sheet had won. One purchase looked like three different products.
 *
 * The factory rule still holds: a product owns its LOOK, the engine owns MECHANISM. Checkout is
 * mechanism. Everything here is drawn from brand tokens — `--brand`, `--paper`, `--ink`, `--rule`
 * — so PermitWatch's modal is still drafting-paper blue and CarrierHelm's is still its own. What
 * is shared is the shape of the thing and the words on it, not the palette.
 *
 * Loaded AFTER the brand sheet, so the few geometry properties named here win.
 */

:root{
  --pay-max:680px;
  --pay-accent:var(--brand, var(--blue, #1B4F8A));
}

/* ---- the overlay -------------------------------------------------------- */
/* The overlay scrolls and the box is never capped. A max-height on .pay__box puts the pay button
   below an unreachable fold: Stripe's embedded checkout measures its own content and grows, and
   what does not fit is the bottom. Stated here so a future "tidy" cannot reintroduce it. */
.pay{position:fixed;inset:0;z-index:100;background:rgba(0,0,0,.55);display:flex;
  align-items:flex-start;justify-content:center;padding:24px 16px 48px;overflow-y:auto;
  overscroll-behavior:contain}
.pay[hidden]{display:none}
.pay__box{position:relative;background:var(--paper,#fff);color:var(--ink,#111);width:100%;
  max-width:min(var(--pay-max), calc(100vw - 32px));padding:26px 24px 22px;
  max-height:none;overflow:visible;box-shadow:0 24px 70px rgba(0,0,0,.3)}
.pay__x{position:absolute;top:8px;right:10px;border:0;background:none;font-size:26px;line-height:1;
  cursor:pointer;padding:4px 8px;color:inherit;min-width:44px;min-height:44px}

/* ---- mobile: a sheet, not a shrunken dialog ------------------------------
   At 390px the old modal was a 16px-margin card holding a sign-in form, and the form scrolled
   inside a box that itself scrolled inside the overlay — two nested scrollers and a 44px target
   for the close control. Below 600px it becomes a full-height sheet: one scroller, a header that
   stays put, and actions that do not need hunting for. */
@media (max-width:600px){
  .pay{padding:0;align-items:stretch}
  .pay__box{max-width:none;min-height:100%;padding:56px 16px 24px;box-shadow:none}
  .pay__x{position:fixed;top:4px;right:6px;z-index:2;background:var(--paper,#fff);
    border:1px solid var(--rule,#ccc);border-radius:50%;width:40px;height:40px;
    display:grid;place-items:center;padding:0;font-size:22px}
  .pay__steplabel{display:none}
}

/* ---- the step rail ------------------------------------------------------ */
.pay__steps{display:flex;list-style:none;margin:0 0 20px;padding:0 0 14px;
  border-bottom:1px solid var(--rule,#ddd)}
.pay__step{flex:1 1 0;min-width:0}
.pay__step[hidden]{display:none}
.pay__stepback{display:flex;align-items:center;gap:7px;width:100%;border:0;background:none;
  font:inherit;font-size:12.5px;padding:0;text-align:left;cursor:default;opacity:.65;color:inherit}
.pay__step.is-done .pay__stepback{cursor:pointer;opacity:.85}
.pay__step.is-now .pay__stepback{opacity:1;font-weight:600}
.pay__stepn{flex:0 0 auto;width:21px;height:21px;border-radius:50%;
  border:1px solid var(--rule,#bbb);display:grid;place-items:center;font-size:11.5px;font-weight:700}
.pay__step.is-now .pay__stepn{border-color:var(--pay-accent);color:var(--pay-accent)}
.pay__steplabel{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(max-width:520px){.pay__steplabel{display:none}}

/* ---- plan choices ------------------------------------------------------- */
.pay__opts{display:grid;gap:10px}
.pay__opt{display:grid;grid-template-columns:1fr auto;gap:2px 12px;text-align:left;width:100%;
  background:var(--paper,#fff);border:1px solid var(--rule,#ccc);padding:14px 16px;cursor:pointer;
  font:inherit;color:inherit;text-decoration:none}
.pay__opt:hover,.pay__opt:focus-visible{border-color:var(--pay-accent)}
.pay__opt-n{font-weight:700;font-size:16px}
.pay__opt-p{font-weight:700;font-size:20px;text-align:right}
.pay__opt-d{grid-column:1/-1;font-size:13.5px;line-height:1.45;opacity:.8}
.pay__box h2{margin:0 0 6px;font-size:22px;letter-spacing:-.01em}
.pay__lede{margin:0 0 18px;color:var(--ink-2,#555);font-size:15px}
.pay__opt--one{border-width:2px;border-color:var(--pay-accent)}
.pay__opt-p small{font-size:12px;font-weight:400;color:var(--ink-3,#667)}
.pay__fine{margin:16px 0 0;font-size:12.5px;opacity:.7;line-height:1.5}
.pay__back{border:0;background:none;cursor:pointer;font:inherit;padding:0 0 12px;color:inherit}
.pay__summary{margin:0 0 16px;padding:9px 12px;background:rgba(127,127,127,.09);
  font-size:14px;font-weight:600}
.pay__summary[hidden]{display:none}
.pay__actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:18px 0 12px}

/* ---- Stripe's embedded checkout ----------------------------------------- */
/* MIN-height, never height: Stripe writes an inline `height:0` before its first self-measure, so
   a fixed height clips the pay button, and `height:100%` of a viewport-derived box clips it too.
   min-height beats a smaller inline height and yields to a larger one. */
.pay__mount{min-height:560px;height:auto;max-height:none}
.pay__mount > iframe{width:100%!important;border:0;min-height:560px}

/* ---- the embedded Keelhelm ID form -------------------------------------- */
/* Rendered in the page, on this origin — not framed. The old iframe reported its height by
   postMessage, and BOTH visible symptoms of that arrangement (a "Loading…" that never cleared
   and a letterbox too short to hold a sign-in form) were the same failure: no message, no
   height, no way to tell a slow frame from a blocked one. There is nothing to wait for now. */
/* The frame is sized by the page inside it, which reports its height by postMessage. That
   message is now one of three ways the placeholder clears (see pay.js mountIdentity), so these
   rules only have to make the STATIC case usable: a frame that renders but never reports is
   still a full sign-in form, not a letterbox. 190px — the old floor — was not.
   `min(72vh, 620px)` keeps the close control and the step rail on screen at the same time. */
.pay__idhost{min-height:min(72vh,620px)}
.pay__idframe{display:block;width:100%;min-height:min(72vh,620px);border:0;
  opacity:0;transition:opacity .15s}
.pay__idframe.is-ready{opacity:1}
@media (max-width:600px){
  /* On a phone the sheet is already full height, so the frame takes what is left rather than a
     viewport fraction that would put its submit button under the fold. */
  .pay__idhost,.pay__idframe{min-height:520px}
}

/* ---- the premium mark ---------------------------------------------------- */
/* Two states off one shape: filled = you have this, outline = this is premium. The star is never
   the only signal — `.prem` always prints its word — because it is invisible to a screen reader
   and identical to its own outline in monochrome. */
.prem-star{width:11px;height:11px;flex:0 0 auto;fill:currentColor;position:relative;top:.5px}
.prem-star--o{fill:none;stroke:currentColor;stroke-width:1.3;stroke-linejoin:round}
.btn .prem-star{width:12px;height:12px;margin-left:8px;top:1px}
.locked--cta .prem-star,.locked__cta .prem-star{margin:0 5px 0 0;top:1px}
/* CarrierHelm's badge is the one being standardised on — the owner named it as the theme every
   site should share. Shape and type scale are fixed here; the two colours come from tokens, so
   PermitWatch's "Included" is blueprint blue and CarrierHelm's stays its green. */
.prem{display:inline-flex;align-items:center;gap:5px;vertical-align:middle;
  font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;line-height:1;
  color:var(--pay-accent);background:var(--ok-bg,var(--tint,rgba(127,127,127,.08)));
  border:1px solid var(--pay-badge-rule,var(--rule,#ccd));padding:4px 6px}
.prem--locked{color:var(--ink-3,#667);background:var(--panel,var(--tint,rgba(127,127,127,.08)));
  border-color:var(--rule,#ccd)}

/* ---- a locked or absent field -------------------------------------------- */
/* The CTA reads as a control, not a dead label — a locked field is where someone learns there is
   something to buy — but stays quiet enough not to look like an advert inside a public record. */
.locked--cta,.locked__cta{font:inherit;font-weight:600;font-size:14.5px;color:var(--pay-accent);
  background:none;border:0;border-bottom:1px solid currentColor;padding:0;cursor:pointer;
  min-height:24px;display:inline-flex;align-items:center}
.locked--cta:hover,.locked--cta:focus-visible,
.locked__cta:hover,.locked__cta:focus-visible{opacity:.78}

/* N/A is not a CTA and must not look like one: there is nothing behind it to buy. The dotted
   underline only appears when there is a note explaining why, and `title` supplies the hover. */
.locked--na{color:var(--ink-3,#667);font-variant-numeric:tabular-nums}
.locked--na[title]{text-decoration:underline;text-underline-offset:2px;
  text-decoration-style:dotted;cursor:help}

/* Screen-reader-only: carries the hover sentence, which `title` never announces. */
.vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---- the "why am I seeing this" step ------------------------------------- */
.pay__why .pay__shape{margin:0 0 14px;padding:12px 14px;overflow-x:auto;font-size:12.5px;
  line-height:1.55;background:rgba(127,127,127,.09);border-left:3px solid var(--pay-accent)}
.pay__why .pay__shape code{white-space:pre}
.pay__why .pay__list{margin:0 0 18px;padding-left:20px;font-size:15px;line-height:1.7}
