/* ==========================================================================
   Auth pages — /pasok and /pasok/confirm.

   LAYOUT ONLY. Every colour, radius, type size, focus ring and control here
   comes from styles.css: this file positions the existing components and adds
   no design language of its own. Loaded only by the auth pages, so it cannot
   reach the calculator even by accident.
   ========================================================================== */

/* The card is centred in the VISUAL viewport, not in what is left below the
   header. Those are not the same thing: the header occupies flow space, so
   centring inside the remainder lands the card half a header lower than the
   eye expects — which is the "excessive space above" this replaces, in a
   milder form.
 *
   The correction is one line: add the header's height to the bottom padding.
   Flex centres the content box inside the padding, so the extra bottom padding
   lifts the card by half of it — exactly cancelling the offset. On a viewport
   too short to centre in, min-block-size gives way and the page simply
   scrolls. */
.auth-main {
  --auth-header: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-block-size: calc(100svh - var(--auth-header));
  padding-block: 32px calc(32px + var(--auth-header));
}
@media (min-width: 768px) {
  .auth-main {
    --auth-header: 88px;
    padding-block: 48px calc(48px + var(--auth-header));
  }
}

.auth-card {
  width: 100%;
  max-width: 27rem;          /* compact: one field and one button need no more */
  margin-inline: auto;
}

/* h1 for document structure, h3 for size. A 36–56px heading inside a 432px
   card is what was breaking "Pasok sa Uwi Plan mo" onto its own last word.
   text-wrap: balance evens the lines and keeps a single word off the last one
   where the browser supports it. */
.auth-title {
  font-size: var(--fs-h3);
  font-weight: 600;
  text-wrap: balance;
  margin-bottom: 10px;
}

.auth-lede {
  font-size: var(--fs-body);
  color: var(--ink-60);
  line-height: 1.6;
  margin: 0 0 22px;
  text-wrap: pretty;
}

/* One column, so the field and the button are the same width by construction
   rather than by two numbers that have to be kept in step. */
.auth-form { display: grid; gap: 18px; }
.auth-form .btn { width: 100%; }

/* The field is a plain input-shell with no prefix — the same control as the
   calculator's, minus the currency chip. */
.auth-form .field { margin-bottom: 0; }

/* The Turnstile security check sits between the field and the button. Its
   managed widget is 65px tall; reserving that stops the button jumping when
   the iframe arrives. The unreplaced marker in the static file takes no room. */
.auth-form [data-turnstile]:empty { display: none; }
.auth-turnstile { min-height: 65px; }

.auth-alt {
  margin: 22px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--ink-08);
}

/* Never the browser's blue. Teal is the design system's action colour, and
   the underline offset keeps it legible against the ink text around it.
   Button-links are excluded: their own .btn variant owns foreground colour. */
.auth-page a:not(.btn) {
  color: var(--teal);
  text-decoration-color: var(--mint-edge);
  text-underline-offset: 3px;
  font-weight: 500;
}
.auth-page a:not(.btn):hover { color: var(--dark-teal); text-decoration-color: currentColor; }

/* The confirmation step is the same card with a different message, so the two
   steps read as one flow rather than two designs. */
.auth-note {
  margin: 0 0 22px;
  padding: 14px 16px;
  background: var(--mint-wash);
  border: 1px solid var(--mint-edge);
  border-radius: var(--r-input);
  font-size: var(--fs-helper);
  color: var(--ink);
  line-height: 1.55;
}

/* --- The saved plan (Phase 3) -------------------------------------------
 *
 * Deliberately almost nothing. The page is a date, when it changed, and two
 * buttons; the form that would turn it into a dashboard is collapsed until
 * asked for. Every value below is a design-system token — no new palette, no
 * new scale.
 */
.plan-label {
  margin: 0 0 6px;
  font-size: var(--fs-helper);
  font-weight: 500;
  color: var(--ink-60);
  letter-spacing: 0.02em;
}

/* The one thing the page exists to say, at the size that admits it. */
.plan-date {
  margin: 0 0 10px;
  font-size: var(--fs-h1);
  font-weight: 700;
  line-height: 1.05;
  color: var(--dark-teal);
  text-wrap: balance;
}

/* No date is not a smaller date: it is a sentence, set as one, so it can
   never be mistaken for a month at a glance. */
.plan-none {
  margin: 0 0 10px;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--ink);
  text-wrap: pretty;
}

.plan-updated {
  margin: 0 0 26px;
  font-size: var(--fs-helper);
  color: var(--ink-60);
}

/* .plan-edit / .plan-field are gone with the settings-form presentation they
   styled: the plan now renders the calculator's own .field, .input-shell and
   .cur-chip, so there is one field treatment in this product rather than two.
   .plan-form only needs to not add a second card inside the one it is in. */
.plan-form { margin: 0; }

/* --- The signed-in plan screen ------------------------------------------
 *
 * Almost nothing, on purpose. The page is rendered in the PRODUCT shell — the
 * site's own header / section / .wrap, at the calculator's width — and the
 * grid, the cards, the fields and the result composition are all the
 * calculator's own classes from styles.css. The only thing this file adds is
 * the state cue, which the calculator has no equivalent of.
 *
 * It used to add a lot more, because the page was being rendered inside the
 * 27rem auth card and everything had to be squeezed to fit. Fixing the shell
 * deleted the need for the squeezing.
 */
.plan-page { background: var(--bg); }

/* The line that says which of the three states the date is in. On the dark
   card, at the contrast the card already uses for secondary text. */
.plan-state {
  margin: 10px 0 0;
  font-size: var(--fs-helper);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.72);
}
/* An unsaved number and a simulation are both provisional, and mint is how
   this product says "where you are" rather than "where you're going". */
.plan-state[data-mode="preview"],
.plan-state[data-mode="scenario"] { color: var(--mint); }

.plan-form { margin: 0; }
.plan-save { width: 100%; margin-top: 26px; }

/* Paano Kung and the process section need no styles of their own: they are
   the main page's `.section`, `.pk-control`, `.pk-compare`, `.pk-cell`,
   `.pk-impact`, `.stepper`, `.steps` and `.step`, all from styles.css. The
   only rule here is the one the UA stylesheet cannot express — a [hidden]
   <section> whose display the sheet would otherwise set. */
.plan-pk-section[hidden] { display: none; }

/* The sections sit outside .wrap's calculator column, so they need the page's
   own rhythm rather than the card's. */
.plan-page .plan-pk-section,
.plan-page .plan-edu,
.plan-page .plan-process { margin-top: 0; }

/* --- The sticky's stage ---------------------------------------------------
   #planStage holds the compact date, the seven answers and the result card,
   and nothing else. It is the sticky's containing block, so the bar is
   released at the bottom of the result card and never reaches Paano Kung.
   Each field keeps a scroll margin equal to what the header and the bar cover
   (measured by plano.js), so a field the browser scrolls to is not left under
   the bar. */
.plan-stage { position: relative; }
@media (max-width: 767px) {
  .plan-stage .field,
  .plan-stage .target-block { scroll-margin-top: var(--plan-sticky-clear, 180px); }
  /* Hiding is IMMEDIATE, showing still fades in. plano.js tucks the bar the
     moment content arrives beneath it; a 280ms fade-out would leave it
     half-visible over that content for the length of the fade. */
  .plan-page .uwi-sticky[data-tucked="true"] { transition-duration: 0s; }
  /* A question in the bar may wrap, but never to more than two lines: a
     third line makes the bar cover the very field it is asking about. */
  .plan-page .uwi-sticky[data-empty="true"] .uwi-sticky-date {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
  }
}

/* Q7's one-tap zero: a small secondary chip under the field, never a
   full-width call to action — it is one valid answer, not the suggested one. */
.plan-zero {
  display: inline-flex;
  align-items: center;
  width: auto;
  margin-top: 10px;
  padding: 0 16px;
  font-size: 0.875rem;
}
.plan-zero[hidden] { display: none; }

/* --- Bago ka umuwi ---------------------------------------------------------
   Education only. Three illustrative states, stacked on phones and three
   across on wider screens. The monthly gap is the largest figure in each. */
.plan-edu { border-bottom: 1px solid var(--ink-08); }
.edu-states {
  display: grid;
  gap: 14px;
  margin: 28px 0 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 720px) {
  .edu-states { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
}
.edu-state {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 18px 20px 20px;
  background: var(--surface);
  border: 1px solid var(--ink-08);
  border-radius: var(--r-card);
}
.edu-state[data-trend="stable"] { border-color: var(--mint-edge); background: var(--mint-wash); }
.edu-state-title { font-size: 1rem; font-weight: 600; line-height: 1.35; margin: 0; }
.edu-math {
  margin-top: 8px;
  font-size: 0.875rem;
  color: var(--ink-60);
  font-variant-numeric: tabular-nums;
}
.edu-gap { margin-top: 10px; line-height: 1.1; }
.edu-gap-figure {
  display: block;
  font-size: clamp(1.75rem, 7vw, 2.125rem);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--dark-teal);
  font-variant-numeric: tabular-nums;
}
.edu-gap-label {
  display: block;
  margin-top: 4px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-60);
}
.edu-fund { margin-top: 14px; }
.edu-fund-label {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink-60);
}
.edu-bars {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 44px;
  margin-top: 6px;
  padding-bottom: 1px;
  border-bottom: 1px solid var(--ink-12);
}
.edu-bar {
  flex: 1 1 0;
  height: var(--h);
  min-height: 2px;
  background: var(--teal);
  border-radius: 4px 4px 0 0;
}
.edu-state[data-trend="fast"] .edu-bar { background: var(--ink-45); }
.edu-note { margin-top: 12px; font-size: 0.9375rem; line-height: 1.5; color: var(--ink); }

.edu-copy { margin-top: 26px; }
.edu-copy p { color: var(--ink-60); line-height: 1.62; }
.edu-copy p + p { margin-top: 12px; }

.edu-count-title { margin-top: 30px; font-size: 1.125rem; }
.edu-count {
  display: grid;
  gap: 14px;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 720px) {
  .edu-count { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
}
.edu-count li { display: flex; align-items: flex-start; gap: 12px; min-width: 0; }
.edu-icon { flex: none; margin-top: 1px; color: var(--teal); }
.edu-count p { font-size: 0.9375rem; line-height: 1.5; color: var(--ink-60); }
.edu-count .edu-count-name { font-weight: 600; color: var(--ink); }

.edu-close {
  margin-top: 26px;
  padding: 16px 18px;
  border-left: 3px solid var(--mint);
  background: var(--mint-wash);
  border-radius: 0 var(--r-input) var(--r-input) 0;
}
.edu-close p { font-size: 0.9375rem; line-height: 1.55; color: var(--ink); }
.edu-close .edu-close-title { font-weight: 600; }
.edu-close p + p { margin-top: 6px; }

.plan-save { width: 100%; margin-top: 26px; }

/* .pk-inline is gone with the disclosure it styled: Paano Kung is now the
   main page's own section below the calculator, and needs nothing from here. */


/* The save action closes the plan's own fields, above the Paano Kung rule. */
.plan-save { width: 100%; margin-top: 26px; }


/* Checkout is a short three-state flow inside the product shell. Keep review
   and payment at a readable width without creating a second design system. */
.checkout-review,
.checkout-flow {
  max-width: 44rem;
}
.checkout-review { margin-inline: auto; }
.checkout-review [hidden] { display: none; }
.checkout-review h1 { margin-bottom: 14px; }
.checkout-preview { margin-top: 24px; padding: 20px; }
.checkout-preview .tier-list { margin-bottom: 0; }
.checkout-pricing {
  margin-top: 18px;
  padding: 18px 20px;
  border: 1px solid var(--mint-edge);
  border-radius: var(--r-input);
  background: var(--mint-wash);
}
.checkout-pricing p { margin: 0; }
.checkout-pricing p + p { margin-top: 8px; font-size: var(--fs-helper); }
.checkout-form { margin-top: 24px; }
.checkout-email-review {
  margin: -4px 0 0;
  padding: 12px 14px;
  border-radius: var(--r-input);
  background: var(--ink-04);
  overflow-wrap: anywhere;
}
.checkout-window-note { margin: -6px 0 0; }

.pay-card { margin-top: 22px; padding: 20px; }
.pay-head, .pay-to { margin: 0; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px 18px; }
.pay-head dt, .pay-to dt { color: var(--ink-60); }
.pay-head dd, .pay-to dd { margin: 0; font-weight: 700; overflow-wrap: anywhere; }
.pay-amount { font-size: var(--fs-h3); color: var(--dark-teal); }
.pay-deadline { margin-top: 22px; font-size: 1.125rem; font-weight: 700; }
.payment-deadline-passed h2 { margin-bottom: 10px; }
.payment-deadline-passed .auth-form { margin-top: 18px; }

/* --- Proof ng bayad: spacing rhythm, not a redesign -----------------------
 *
 * Everything in this card inherits `p { margin: 0 }` from styles.css, so the
 * heading, the requirement sentence, the picker, the CTA, the steps and the
 * three tail sentences were rendering at ZERO separation and reading as one
 * dense column. These rules add the gaps and nothing else: no new type scale,
 * no icons, no second card, no change to the form or its controls.
 *
 * Scoped to `.proof-card` on purpose. The checkout shell is `.plan-page`,
 * which /plano also uses, so a rule written against the shell would move
 * spacing on the paid product page as a side effect.
 */
.proof-card h2 { margin-bottom: 7px; }
/* `!important`, and not lightly. styles.css:1388 carries
   `.section h2 + .lede { margin-top: 14px !important }` inside the homepage's
   max-width:720px block, and the product shell renders this card inside a
   `.section` — so on a phone that homepage rule lands on this heading pair and
   nothing without `!important` can outrank it. The selector is deliberately
   narrower than the leak it answers (`.checkout-flow .proof-card h2 + …`), so
   it can only ever affect this one card. The leak itself belongs to the
   homepage and is out of scope for this change. */
.checkout-flow .proof-card h2 + .proof-intro { margin: 0 !important; }
.proof-card .proof-intro { margin: 0; }
.proof-card .proof-status { margin-top: 12px; }

/* The form's own `gap` carries picker -> CTA. 15px rather than the auth
   default 18px: this form sits inside a card that already has its own
   padding, and the pair reads as one unit at the tighter figure. */
.proof-card .payment-proof-form { margin-top: 15px; gap: 15px; }
/* The deadline helper belongs to the CTA above it but is not part of the
   control pair, so it takes the grid gap plus a little. */
.proof-card .payment-proof-form > p { margin-top: 3px; }

.proof-card .pay-steps { margin: 18px 0 0; padding-inline-start: 1.35rem; }
.proof-card .pay-steps li + li { margin-top: 7px; }

/* Help, privacy, security. One block with real paragraph spacing instead of
   three sentences run together. */
.proof-card .proof-support { margin-top: 22px; }
.proof-card .proof-support p { margin: 0; }
.proof-card .proof-support p + p { margin-top: 12px; }

/* --- Proof received: a clean completion state ----------------------------
 *
 * Five paragraphs at zero separation under the H1. The reference and what
 * happens to it are one block; the rest is ordinary paragraph rhythm, with
 * the single "nothing left to do" line given room of its own.
 */
.checkout-done h1 { text-wrap: balance; }
.checkout-done .done-status {
  margin-top: 20px;
  padding: 14px 16px;
  border: 1px solid var(--mint-edge);
  border-radius: var(--r-input);
  background: var(--mint-wash);
}
.checkout-done .done-status p { margin: 0; }
.checkout-done .done-status p + p { margin-top: 9px; }
.checkout-done .done-ref { overflow-wrap: anywhere; }

.checkout-done .done-next { margin-top: 19px; }
.checkout-done .done-rest { margin-top: 15px; }
/* Readable, but plainly the least urgent thing on the page. */
.checkout-done .done-help {
  margin-top: 18px;
  font-size: var(--fs-helper);
  color: var(--ink-60);
}

@media (max-width: 720px) {
  .checkout-preview, .checkout-pricing, .pay-card { padding: 16px; }
  .pay-head, .pay-to { grid-template-columns: 1fr; gap: 2px; }
  .pay-head dd + dt, .pay-to dd + dt { margin-top: 10px; }
}
@media (max-width: 720px) {
  .checkout-done .done-status { padding: 13px 14px; }
}


/* Payment upload/review forms must not inherit the file input's intrinsic
   width on narrow phones. Keep the long proof CTA inside its card. */
.payment-proof-form, .payment-admin-form { grid-template-columns: minmax(0, 1fr); }
.payment-proof-form label, .payment-admin-form label { min-width: 0; }
.payment-proof-form input, .payment-admin-form input, .payment-admin-form textarea {
  display: block; width: 100%; min-width: 0; max-width: 100%;
}
.payment-proof-form .btn, .payment-admin-form .btn { white-space: normal; }

/* Payment QR: the fixed-amount GCash image is intentionally tall rather than
   a square code. Keep its natural aspect ratio, make it large enough to scan
   from another device, and give same-phone buyers an obvious download action. */
.pay-qr {
  margin: 24px 0 0;
  display: grid;
  justify-items: center;
  gap: 12px;
}
.pay-qr-label {
  margin: 0;
  font-weight: 600;
  color: var(--ink);
}
.pay-qr img {
  display: block;
  width: min(100%, 340px);
  height: auto;
  border-radius: var(--r-input);
}
.pay-qr-help {
  margin: 0;
  max-width: 34rem;
  text-align: center;
  font-size: var(--fs-helper);
  line-height: 1.55;
  color: var(--ink-60);
}
.pay-qr-actions { margin: 0; }
.pay-qr-download { min-width: min(100%, 18rem); }

/* --- Admin navigation + pre-approved access ----------------------------
 * This is an operator surface, but it keeps the product's existing fields,
 * cards and buttons. The responsive row becomes labelled facts on a phone so
 * the email and note wrap instead of creating a spreadsheet scroller. */
.admin-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 20px;
  margin-bottom: 20px;
}
.admin-heading .eyebrow { margin: 0; }
.admin-nav { display: flex; gap: 8px; }
.admin-nav a {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  border: 1px solid var(--ink-12);
  border-radius: 999px;
  color: var(--teal);
  font-weight: 600;
  text-decoration: none;
}
.admin-nav a[aria-current="page"] {
  color: var(--surface);
  border-color: var(--dark-teal);
  background: var(--dark-teal);
}

.access-admin { max-width: 74rem; margin-inline: auto; }
.access-admin > h1 { margin-bottom: 22px; }
.access-create {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(11rem, 0.7fr);
  gap: 18px 20px;
  margin-bottom: 22px;
  padding: 20px;
}
.access-create .field { margin: 0; min-width: 0; }
.access-create .access-note { grid-column: 1 / -1; }
.access-create textarea {
  display: block;
  width: 100%;
  min-width: 0;
  resize: vertical;
  border: 1px solid var(--ink-12);
  border-radius: var(--r-input);
  background: var(--surface);
  padding: 12px 14px;
  font: inherit;
}
.access-create textarea:focus {
  outline: none;
  border-color: var(--teal);
  box-shadow: 0 0 0 3px var(--mint-wash);
}
.access-create .btn { justify-self: start; }

.access-table {
  margin-top: 22px;
  border: 1px solid var(--ink-08);
  border-radius: var(--r-card);
  background: var(--surface);
  overflow: hidden;
}
.access-row {
  display: grid;
  grid-template-columns: minmax(13rem, 1.5fr) minmax(8rem, 0.75fr) minmax(6rem, 0.55fr) minmax(9rem, 0.85fr) minmax(7rem, 0.55fr);
  gap: 12px;
  align-items: center;
  padding: 14px 16px;
  border-top: 1px solid var(--ink-08);
}
.access-table-head {
  border-top: 0;
  background: var(--ink-04);
  color: var(--ink-60);
  font-size: var(--fs-helper);
  font-weight: 600;
}
.access-email { min-width: 0; overflow-wrap: anywhere; }
.access-email small {
  display: block;
  margin-top: 4px;
  color: var(--ink-60);
  font-weight: 400;
  white-space: pre-wrap;
}
.access-status { font-weight: 600; }
.access-status[data-status="claimed"] { color: var(--dark-teal); }
.access-status[data-status="revoked"] { color: var(--ink-60); }
.access-row form { margin: 0; }
.access-row .btn { min-height: 48px; padding-inline: 14px; }
.access-empty { margin: 0; padding: 22px; color: var(--ink-60); }

@media (max-width: 720px) {
  .access-create { grid-template-columns: minmax(0, 1fr); padding: 16px; }
  .access-create .access-note { grid-column: auto; }
  .access-create .btn { width: 100%; }
  .access-table { border: 0; background: transparent; overflow: visible; }
  .access-table-head { display: none; }
  .access-row:not(.access-table-head) {
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
    margin-bottom: 14px;
    padding: 16px;
    border: 1px solid var(--ink-08);
    border-radius: var(--r-card);
    background: var(--surface);
  }
  .access-row [role="cell"] {
    display: grid;
    grid-template-columns: minmax(6.5rem, 0.65fr) minmax(0, 1fr);
    gap: 12px;
    align-items: start;
    min-width: 0;
  }
  .access-row [role="cell"]::before {
    content: attr(data-label);
    color: var(--ink-60);
    font-size: var(--fs-helper);
  }
  .access-row [role="cell"] form { min-width: 0; }
  .access-row [role="cell"] .btn { width: 100%; }
  .access-email small { grid-column: 2; }
}


/* --- Versioned legal documents -----------------------------------------
 * Long-form legal copy is a reading task, not a product dashboard. Keep the
 * same brand system, but tighten the top entry, narrow the text column inside
 * a quiet surface, and step the heading scale down one level so section names
 * do not compete with the document title.
 */
.legal-page { background: var(--bg); }

.legal-page .section {
  padding-block: 36px 64px;
}

.legal-document {
  width: 100%;
  max-width: var(--max-reading);
  margin-inline: auto;
  padding: 24px 22px 30px;
  background: var(--surface);
  border: 1px solid var(--ink-08);
  border-radius: var(--r-card);
}

.legal-document .eyebrow { margin-bottom: 10px; }

.legal-document h1 {
  margin-bottom: 16px;
  font-size: var(--fs-h2);
  font-weight: 700;
  text-wrap: balance;
}

.legal-document h2 {
  margin-top: 30px;
  margin-bottom: 10px;
  font-size: var(--fs-h3);
  font-weight: 600;
  text-wrap: balance;
}

.legal-document p {
  line-height: 1.72;
  text-wrap: pretty;
}

.legal-document p + p { margin-top: 12px; }

.legal-document a {
  color: var(--teal);
  text-decoration-color: var(--mint-edge);
  text-underline-offset: 3px;
  font-weight: 500;
}

.legal-document a:hover {
  color: var(--dark-teal);
  text-decoration-color: currentColor;
}

@media (min-width: 768px) {
  .legal-page .section { padding-block: 48px 88px; }
  .legal-document { padding: 42px 48px 48px; }
  .legal-document h2 { margin-top: 36px; }
}


/* --- Payment admin review -------------------------------------------------
   Operator UI only. Keep the customer payment page simple, but make payment
   review efficient enough that proof, verification and exception handling do
   not become a scrolling exercise. */
.payment-review {
  max-width: 1180px;
  margin-inline: auto;
}
.payment-review [id] { scroll-margin-top: 156px; }

.payment-review-bar {
  position: sticky;
  top: 80px;
  z-index: 35;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  margin: -4px 0 24px;
  padding: 10px 12px;
  background: rgba(251, 250, 247, 0.96);
  backdrop-filter: blur(10px);
  border: 1px solid var(--ink-08);
  border-radius: var(--r-input);
  box-shadow: 0 8px 24px rgba(6, 44, 82, 0.06);
}
@media (min-width: 768px) { .payment-review-bar { top: 88px; } }
.payment-review-bar a {
  color: var(--teal);
  font-weight: 600;
  text-decoration: none;
}
.payment-review-back { margin-right: auto; }
.payment-review-links { display: inline-flex; flex-wrap: wrap; gap: 8px; }
.payment-review-links a {
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  padding: 0 11px;
  border: 1px solid var(--ink-08);
  border-radius: 999px;
  background: var(--surface);
}
.payment-review-links a:hover { border-color: var(--teal); color: var(--dark-teal); }

.payment-review-head { margin-bottom: 18px; }
.payment-review-head h1 { margin-top: 6px; }

.payment-review-facts {
  display: grid;
  gap: 0;
  margin: 0;
  border: 1px solid var(--ink-08);
  border-radius: var(--r-card);
  background: var(--surface);
  overflow: hidden;
}
.payment-review-facts > div {
  display: grid;
  grid-template-columns: minmax(130px, 0.8fr) minmax(0, 1.4fr);
  gap: 12px;
  padding: 11px 14px;
  border-top: 1px solid var(--ink-08);
}
.payment-review-facts > div:first-child { border-top: 0; }
.payment-review-facts dt { color: var(--ink-60); font-size: var(--fs-helper); }
.payment-review-facts dd { margin: 0; font-weight: 500; overflow-wrap: anywhere; }

.payment-review-grid {
  display: grid;
  gap: 24px;
  align-items: start;
  margin-top: 24px;
}
@media (min-width: 940px) {
  .payment-review-grid:not(.is-verified) {
    grid-template-columns: minmax(0, 0.9fr) minmax(360px, 1.1fr);
  }
  .payment-review-grid.is-verified { grid-template-columns: minmax(0, 760px); }
}

.payment-proof-panel,
.payment-action-card,
.payment-email-panel {
  border: 1px solid var(--ink-08);
  border-radius: var(--r-card);
  background: var(--surface);
}
.payment-proof-panel,
.payment-action-card { padding: 20px; }

.payment-section-head {
  display: flex;
  gap: 16px;
  justify-content: space-between;
  align-items: end;
  margin-bottom: 16px;
}
.payment-section-head h2 { margin-top: 4px; }
.payment-proof-open { flex: none; }

.payment-proof-link {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  max-height: min(50vh, 480px);
  border-radius: var(--r-input);
  background: var(--ink-08);
  overflow: hidden;
}
.payment-proof-preview {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: min(50vh, 480px);
  object-fit: contain;
  object-position: top center;
  background: var(--ink-08);
}
.payment-proof-original { margin-top: 12px; }

.payment-action-card > h2 { margin: 4px 0 18px; }
.payment-review .auth-form label {
  display: grid;
  gap: 7px;
  min-width: 0;
}
.payment-review .auth-form input:not([type="hidden"]),
.payment-review .auth-form textarea,
.payment-review .auth-form select {
  width: 100%;
  min-width: 0;
  min-height: var(--tap);
  padding: 10px 12px;
  border: 1px solid var(--ink-12);
  border-radius: var(--r-input);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
}
.payment-review .auth-form input:focus,
.payment-review .auth-form textarea:focus,
.payment-review .auth-form select:focus {
  outline: none;
  border-color: var(--teal);
  box-shadow: 0 0 0 3px var(--mint-wash);
}
.payment-review .auth-form textarea {
  min-height: 7rem;
  line-height: 1.5;
  resize: vertical;
}
.payment-review .auth-form textarea.payment-admin-note { min-height: 5rem; }

.payment-template { margin-bottom: -4px; }
.payment-template-select { margin-top: 0; }

.payment-secondary-action {
  margin-top: 26px;
  padding-top: 24px;
  border-top: 1px solid var(--ink-08);
}
.payment-secondary-action h3 { margin-bottom: 14px; }

/* The access email's delivery state on a verified order. The data-access-
   state hook colours the edge only; the heading always says the state in
   words. */
.payment-access-card {
  margin-bottom: 20px;
  padding: 18px 20px;
  border: 1px solid var(--ink-08);
  border-left: 4px solid var(--ink-12);
  border-radius: var(--r-card);
  background: var(--surface);
}
.payment-access-card[data-access-state="sent"] { border-left-color: var(--teal); }
.payment-access-card[data-access-state="pending"] { border-left-color: var(--mint); }
.payment-access-card[data-access-state="failed"],
.payment-access-card[data-access-state="unsent"] { border-left-color: var(--ink); background: var(--mint-wash); }
.payment-access-card > h2 { margin: 4px 0 8px; font-size: 1.25rem; }
.payment-access-retry { margin-top: 14px; }

.payment-email-panel > summary {
  min-height: var(--tap);
  display: flex;
  align-items: center;
  cursor: pointer;
  font-weight: 600;
  color: var(--dark-teal);
}

.payment-email-panel {
  margin-top: 24px;
  padding: 0 20px;
}
.payment-email-panel > summary { padding: 14px 0; }
.payment-email-body {
  padding: 2px 0 20px;
  border-top: 1px solid var(--ink-08);
}
.payment-email-body > .helper { margin: 14px 0 18px; }
.payment-email-form + .payment-email-form {
  margin-top: 22px;
  padding-top: 22px;
  border-top: 1px solid var(--ink-08);
}

@media (max-width: 620px) {
  .payment-review-facts > div { grid-template-columns: 1fr; gap: 3px; }
  .payment-review-bar strong { order: -1; width: 100%; }
  .payment-review-back { margin-right: 0; }
  .payment-review-links { margin-left: auto; }
  .payment-section-head { align-items: stretch; flex-direction: column; }
  .payment-proof-open { width: 100%; }
  .payment-proof-preview { max-height: 50vh; }
}

/* --- /admin/payments: the operations queue --------------------------------
 *
 * ONE TABLE, TWO SHAPES. Seven columns on a desktop; the same cells restacked
 * into a compact block on a phone. A horizontally scrolling table is not an
 * option here — an operator reconciling a wallet on a phone must be able to
 * read a reference, a status and a deadline without dragging sideways.
 *
 * Scoped to `.payment-queue`. The product shell is `.plan-page`, shared with
 * /plano, so an unscoped `table` or `td` rule would reach the customer pages.
 */
.payment-queue { max-width: 76rem; }
.payment-queue h1 { margin-bottom: 18px; }
.pq-sr {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

.pq-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.pq-filter {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: var(--tap);
  padding: 8px 14px;
  border: 1px solid var(--ink-12);
  border-radius: 999px;
  font-size: var(--fs-helper); font-weight: 600;
  text-decoration: none; color: var(--ink-60);
  white-space: nowrap;
}
.pq-filter:hover { border-color: var(--teal); color: var(--dark-teal); }
.pq-filter[aria-current="page"] {
  background: var(--dark-teal); border-color: var(--dark-teal); color: #fff;
}
.pq-count { font-variant-numeric: tabular-nums; opacity: .85; }
.pq-filter[aria-current="page"] .pq-count { opacity: 1; }

.pq-table { width: 100%; border-collapse: collapse; font-size: var(--fs-helper); }
.pq-table thead th {
  text-align: left; padding: 8px 12px;
  border-bottom: 1px solid var(--ink-12);
  font-size: .75rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-60); white-space: nowrap;
}
.pq-table td { padding: 9px 12px; border-bottom: 1px solid var(--ink-08); vertical-align: middle; }
.pq-row.is-done td { color: var(--ink-60); }

/* Reference leads the hierarchy, so it is the one bold thing in the row. */
.pq-ref a { font-weight: 700; text-decoration: none; white-space: nowrap; }
.pq-ref a:hover { text-decoration: underline; }
/* The FULL address stays in the DOM and on the clipboard — an operator
   reconciling an inbox needs it. Only the rendering is clamped. */
.pq-customer span {
  display: block; max-width: 22ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pq-amount, .pq-proof, .pq-deadline { white-space: nowrap; font-variant-numeric: tabular-nums; }

.pq-chip, .pq-flag {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  font-size: .75rem; font-weight: 600; white-space: nowrap;
}
.pq-chip { background: var(--ink-04); color: var(--ink); }
.pq-flag { margin-left: 6px; background: var(--ink-04); color: var(--ink-60); }
/* Colour never carries the state alone — every chip also says what it is. */
.pq-chip[data-chip="Proof received"] { background: var(--mint-wash); color: var(--dark-teal); }
.pq-chip[data-chip="Verified · notified"] { background: var(--mint-wash); color: var(--dark-teal); }
.pq-chip[data-chip="Email failed"],
.pq-flag { background: #fbe9e6; color: #9c2f26; }
.pq-chip[data-chip="Waiting for clearer proof"],
.pq-chip[data-chip="Email ready"],
.pq-chip[data-chip="Verified · not notified"] { background: #f8ecdd; color: #8a4c12; }

/* 34px on a desktop, where the pointer is precise and row density is the
   whole point of this screen. The full var(--tap) target comes back in the
   phone block below, where a thumb has to hit it. */
.pq-go {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 34px; padding: 6px 16px;
  border-radius: var(--r-input);
  background: var(--dark-teal); color: #fff;
  font-weight: 600; text-decoration: none; white-space: nowrap;
}
.pq-go:hover { filter: brightness(1.08); }
/* A finished record needs no call to action competing with the live ones. */
.pq-go.is-quiet {
  background: transparent; color: var(--ink-60);
  border: 1px solid var(--ink-12); font-weight: 500;
}
.pq-empty { margin: 24px 0; color: var(--ink-60); }
.pq-finalize { margin-top: 32px; padding-top: 22px; border-top: 1px solid var(--ink-08); }

/* --- phone: the same cells, restacked ------------------------------------
 *
 *   KU-4269-4241                      [Review]
 *   owner@example.com · ₱299
 *   ● Proof received
 *   Proof 17:55 · Payment deadline 18:25
 */
@media (max-width: 720px) {
  .pq-table, .pq-table tbody, .pq-row, .pq-table td { display: block; width: 100%; }
  .pq-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  /* FOUR ROWS, TWO COLUMNS, and every cell gets its OWN area. Two cells
     sharing one grid area do not sit side by side — they stack in the same
     track and print over each other, which is what an earlier draft of this
     block did to the email/amount and proof/deadline pairs. */
  .pq-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "ref      action"
      "customer amount"
      "status   status"
      "proof    proof"
      "deadline deadline";
    column-gap: 10px; row-gap: 4px;
    padding: 14px 0;
    border-bottom: 1px solid var(--ink-08);
  }
  .pq-table td { padding: 0; border: 0; min-width: 0; }
  .pq-ref { grid-area: ref; align-self: center; }
  .pq-ref a { font-size: 1rem; }
  .pq-action { grid-area: action; align-self: center; justify-self: end; }
  .pq-customer { grid-area: customer; min-width: 0; align-self: baseline; }
  .pq-amount { grid-area: amount; justify-self: end; align-self: baseline; }
  .pq-status { grid-area: status; margin-top: 6px; }
  /* One operational line: "Proof 12:00 PM PHT · Payment deadline 12:30 PM PHT".
     Smaller than the row's body text because it is reference material, and
     allowed to wrap rather than push the row sideways. */
  .pq-proof, .pq-deadline {
    margin-top: 4px; color: var(--ink-60);
    font-size: .8125rem; white-space: nowrap;
  }
  /* TWO LINES, NOT ONE. Sharing a row would size the second column to the
     longest deadline string — which starved the reference column and pushed
     the text past the right edge at 390px. Each timestamp gets the full
     width, stays fully labelled, and can never overflow. */
  .pq-proof { grid-area: proof; }
  .pq-deadline { grid-area: deadline; margin-top: 1px; }
  /* The stacked form loses the header row, so each timestamp names itself —
     "Payment deadline", never a bare "Deadline": proof may legitimately
     arrive after the deadline when the payment itself was on time. */
  .pq-proof::before, .pq-deadline::before { content: attr(data-label) " "; }
  .pq-go { min-height: var(--tap); padding: 8px 14px; }
  .pq-filters { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
  .pq-filters::-webkit-scrollbar { display: none; }
  .pq-filter { flex: none; }
}
