/* ============================================================================
   Mobile/QR store (crpay.biz /Mobile) - page layer on top of oc-core.css
   Prefix: ocm- (see BRANDING.md section 6). Tokens only - if a value isn't a
   var(--oc-*) it belongs in oc-core, not here.

   Division of labor: this file owns how the page LOOKS; Assetts/styles.css
   owns only flow STATE (which wizard panels start hidden - custom.js toggles
   them). Phone-first 560px column; must also read well on desktop.
   ============================================================================ */

/* ---- typography override (store surfaces only, decided 2026-08) ------------
   Poppins (headings) + Inter (body), self-hosted woff2 in Assetts/fonts/.
   The system stacks stay as fallbacks. Re-declaring the tokens here wins
   because this file loads after oc-core.css. Also raises the small-text
   floor: sentences at 16px in ink-2 (never ink-3), labels >= 14px -
   hierarchy comes from color and weight, not smallness. */
@font-face {
  font-family: "Inter";
  src: url("fonts/inter-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("fonts/poppins-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("fonts/poppins-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
:root {
  --oc-font: "Inter", -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --oc-display: "Poppins", "Futura", "Futura PT", "Century Gothic", "Segoe UI", sans-serif;
}
/* Small-text floor overrides for oc-core components used on this site. */
.oc-help  { font-size: 16px; color: var(--oc-ink-2); }
.oc-error { font-size: 16px; }
.oc-eyebrow { font-size: 14px; }
.oc-chip { font-size: 14px; }
/* The gold credit chip is the gratitude moment, so it gets read: gold text
   on gold-soft is 3.25:1 in light mode (the worst pairing on either site).
   Ink text keeps the gold wash + a gold edge as the celebration signal.
   oc-core is read-only, so the correction lives here. */
.oc-chip--prize { color: var(--oc-ink); border-color: var(--oc-accent); }
/* The prize chip holds a SENTENCE ("«Name» gets credit for this order"), not
   a dot+label pair: oc-core's flex gap PLUS the markup's &nbsp; stack into a
   double-wide space after the name. Zero the gap - the &nbsp; is the space. */
#credit_line .oc-chip, .ocm-thanks-credit .oc-chip { gap: 0; }

/* ---- shell ---------------------------------------------------------------- */
/* Sticky so the cart chip stays reachable while browsing products.
   z-index 300: must beat the PayPal SDK's button iframes (inline z-index
   100/200 in the root stacking context) while staying under .ocm-dialog
   (1000) and #progress (1001). */
.ocm-topbar {
  position: sticky; top: 0; z-index: 300;
  background: var(--oc-surface);
  border-bottom: 1px solid var(--oc-border);
  /* Content aligns to the 560px column like the cards below (participant-
     surface pattern) - the bar background still spans the page. Plain
     padding line = fallback where max() is unsupported. */
  padding: 10px 18px;
  padding-left: max(18px, calc((100% - var(--oc-maxw)) / 2));
  padding-right: max(18px, calc((100% - var(--oc-maxw)) / 2));
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.ocm-topbar-side { display: flex; align-items: center; gap: 8px; }

/* Cart chip - a real <button> so Enter/Space work. Keeps legacy classes
   .cart / .carttotal: custom.js shows it with .css({display:'inline'}) and
   writes the count/total into .carttotal. min-height 44px per the
   touch-target rule (it's the persistent route back to the cart). */
.ocm-cartchip {
  background: var(--oc-primary-soft); color: var(--oc-primary-700);
  border: 0; border-radius: var(--oc-pill);
  min-height: 44px; padding: 10px 14px; font-size: 14px; font-weight: 600;
  cursor: pointer; white-space: nowrap;
}
:where(:root[data-theme="dark"]) .ocm-cartchip { color: var(--oc-primary); }

.ocm-main {
  max-width: var(--oc-maxw);
  margin: 0 auto;
  padding: 22px 18px 48px;
}

.ocm-head { margin-bottom: 6px; }
.ocm-head .oc-h1 { margin-top: 2px; }

/* ---- group branding plate --------------------------------------------------
   The group's mascot/logo + name on a wash of their chosen color. The raw
   color is NEVER used behind text: it's mixed to a fixed-lightness tint
   against the surface token, so ink passes contrast in both themes. Where
   color-mix is unsupported the background declaration drops and the plate
   falls back to plain surface-2 - still fine. --grp-accent is set on <html>
   by applyGroupBranding(); without it the fallback keeps the plate neutral. */
.ocm-plate {
  display: flex; align-items: center; gap: 14px;
  margin-top: 12px; padding: 14px 16px;
  border: 1px solid var(--oc-border); border-radius: var(--oc-r);
  background: var(--oc-surface-2);
  background: color-mix(in srgb, var(--grp-accent, transparent) 14%, var(--oc-surface-2));
}
/* The uploader normalizes logos to 150x150 on white, so a fixed white plate
   matches the baked-in matte and reads as a framed badge in dark mode. */
.ocm-plate-logo {
  width: 56px; height: 56px; flex: 0 0 auto;
  object-fit: contain; background: #FFFFFF;
  border: 1px solid var(--oc-border); border-radius: var(--oc-r-sm);
  padding: 4px;
}

/* Group name - written by custom.js after the group lookup. */
.ocm-groupname { font-family: var(--oc-display); font-size: 21px; font-weight: 700; line-height: 1.25; }

/* Two-up field row (state + zip). Collapses to one column on tiny screens. */
.ocm-formrow { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 360px) { .ocm-formrow { grid-template-columns: 1fr; gap: 0; } }

/* Quantity field sits below the product description. */
.ocm-qty-field { margin-top: 14px; }

/* Full-width third action (e.g. Close under Remove/Update) inside a dialog. */
.ocm-dialog .oc-btn--block { margin-top: 10px; }

/* Duplicate-order warning written server-side above the payment options.
   Text in INK (danger-on-danger-soft is 4.07:1 at 16px/700 - fails AA, and
   this is a must-read warning); the red wash + border carry the danger
   signal. Plain border line = no-color-mix fallback. */
.ocm-dupnote {
  /* Regular weight so the (VB-tightened) message holds two lines in the
     560px column; only the participant's name is bold via the <b> in the
     server string. Wash + border still carry the danger signal. */
  color: var(--oc-ink); font-weight: 400;
  background: var(--oc-danger-soft);
  border: 1px solid var(--oc-danger);
  border: 1px solid color-mix(in srgb, var(--oc-danger) 40%, transparent);
  border-radius: var(--oc-r);
  padding: 12px 14px; margin: 14px 0;
}

/* Wizard step cards get .oc-card oc-card--pad in markup; spacing here. */
.ocm-panel { margin-top: 18px; }

/* Card intro copy: secondary ink so the bold-ink field labels pop by
   contrast (labels deliberately stay ink, NOT the blue accent - blue is
   reserved for money and actions, and the error state flips labels red).
   oc-core zeroes p margins, so the air before the first field lives here. */
.ocm-cardintro { color: var(--oc-ink-2); margin: 0 0 16px; }
#student_form .oc-h2, #contact .oc-h2 { margin: 0 0 4px; }

/* "Shopping Cart" heading needs air above the first item card. */
#listHeader { margin-bottom: 12px; }

/* Back/Next rows */
.ocm-actions { display: flex; gap: 10px; margin-top: 14px; }
.ocm-actions .oc-btn { flex: 1; }

/* ---- flow states driven by custom.js -------------------------------------- */

/* Invalid input - custom.js adds/removes class="error" on the input itself. */
.oc-input.error, .oc-select.error {
  border-color: var(--oc-danger);
}
.oc-input.error:focus, .oc-select.error:focus {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--oc-danger) 22%, transparent);
}

/* Field label flagged by custom.js (ocm-lbl-error replaces the legacy inline
   red/white color swaps - white labels would vanish on the light background). */
.ocm-lbl-error { color: var(--oc-danger) !important; }

/* "Loading..." overlay - custom.js appends <div id="progress"> during lookups. */
#progress {
  position: fixed; top: 40%; left: 50%; transform: translate(-50%, -50%);
  background: var(--oc-surface); color: var(--oc-ink);
  border: 1px solid var(--oc-border); border-radius: var(--oc-r);
  box-shadow: var(--oc-shadow-lg);
  padding: 18px 28px; font-weight: 600; z-index: 1001;
}

/* "Group ID invalid." - shown by custom.js when the lookup finds nothing. */
#groupID_Error { color: var(--oc-danger); font-weight: 600; font-size: 16px; }

/* ---- secondary action buttons (2026-08-15) --------------------------------- */
/* Back / Return-to-the-store read as bordered-with-ink now - the ghost and
   subtle variants sat too faint on the white page. Block-level secondaries
   also carry the consistent breathing room the owner asked for (several
   sat flush against the card above); the product row's inline Back stays
   unmargined so it aligns with Add to Cart. */
.ocm-btn-secondary {
  background: var(--oc-surface);
  border: 1px solid var(--oc-border-2);
  color: var(--oc-ink);
}
.ocm-btn-secondary.oc-btn--block { margin-top: 14px; }

/* ---- share card (2026-08-14) ----------------------------------------------- */
/* Post-payment growth moment on the thank-you page: the two store links and
   a native share button. Primary-soft wash - gold stays reserved for the
   participant-credit moment. */
.ocm-sharecard {
  background: var(--oc-primary-soft);
  border-radius: var(--oc-r);
  padding: 16px 18px;
  margin-top: 14px;
  text-align: left;
}
.ocm-sharecard .oc-eyebrow { margin: 0 0 6px; }
.ocm-sharelead { margin: 0 0 4px; font-size: 14.5px; color: var(--oc-ink); line-height: 1.5; }
/* Labeled link rows, matching the confirmation email's share card
   (2026-08-14): small-caps label / bold link / quiet description. Labels
   and descriptions use ink-2 - ink-3 falls below AA on the soft wash. */
.ocm-sharerows { margin: 0 0 12px; }
.ocm-sharerow { padding: 10px 0 8px; border-bottom: 1px solid var(--oc-border); }
.ocm-sharerow:last-child { border-bottom: none; }
.ocm-sharerow-label {
  font-size: 11.5px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--oc-ink-2);
}
.ocm-sharerow-link { font-size: 16px; font-weight: 700; padding-top: 2px; }
.ocm-sharerow-link a { word-break: break-all; }
.ocm-sharerow-desc { font-size: 13.5px; color: var(--oc-ink-2); padding-top: 1px; }
/* One share button per store (2026-08-15): small gap between a row's
   explanation and its button. */
.ocm-sharerow .oc-btn { margin-top: 8px; }
.ocm-sharebtn svg { width: 18px; height: 18px; vertical-align: -3px; margin-right: 8px; }

/* ---- dialogs --------------------------------------------------------------- */
/* Fixed centered dialogs shown by custom.js. Floating popups take the full
   modal treatment (2026-08-14): even 1px border, shadow-lg, and a dimmed
   backdrop matching the webstore's .ocw-modal-backdrop (rgba(15,22,32,.55)).
   The backdrop is the 100vmax shadow spread - pure CSS, so none of
   custom.js's scattered .show()/.hide() call sites had to change. The old
   left-accent style stays on IN-FLOW notes only (.ocm-banner, .ocm-dupnote
   keep their colored-edge language); .ocm-dialog--danger stays in markup but
   no longer restyles the edge. Two-button dialogs still put their actions in
   .ocm-dialog-actions (secondary/ghost LEFT of primary, per BRANDING.md). */
.ocm-dialog {
  display: none;
  position: fixed; top: 40%; left: 50%; transform: translate(-50%, -50%);
  width: min(420px, calc(100% - 36px));
  background: var(--oc-surface); color: var(--oc-ink);
  border: 1px solid var(--oc-border);
  border-radius: var(--oc-r);
  box-shadow: var(--oc-shadow-lg), 0 0 0 100vmax rgba(15, 22, 32, .55);
  padding: 18px; z-index: 1000; text-align: left;
}
.ocm-dialog p { margin-bottom: 12px; }
.ocm-dialog-actions { display: flex; gap: 10px; }
.ocm-dialog-actions .oc-btn { flex: 1; }

/* ---- banners ---------------------------------------------------------------- */
/* Delivery-constraint notices ("only order if you are local"). Amber warn,
   not the legacy red-on-white shout - red is reserved for errors/destructive. */
/* Body text is INK, not warn: warn #96660F on warn-soft is only 4.18:1 at
   this size (fails AA). The amber wash + border carry the caution signal;
   the words stay maximally legible. Plain border line = no-color-mix
   fallback (the shorthand drops whole in older browsers). */
.ocm-banner {
  display: block;
  background: var(--oc-warn-soft); color: var(--oc-ink);
  border: 1px solid var(--oc-warn);
  border: 1px solid color-mix(in srgb, var(--oc-warn) 30%, transparent);
  border-radius: var(--oc-r);
  padding: 12px 14px; margin-top: 14px;
  font-size: 16px;
}
.ocm-banner p { margin: 0 0 6px; }
.ocm-banner p:last-child { margin-bottom: 0; }
.ocm-banner a { color: inherit; font-weight: 700; }

/* "Choose the right state" note under the delivery form. */
#stateInstructions {
  color: var(--oc-danger); font-weight: 600; font-size: 16px; margin-top: 8px;
}

/* Please-fill-out-all-fields note (custom.js toggles visibility). */
#formErrors { color: var(--oc-danger); font-weight: 600; font-size: 16px; margin-top: 8px; }

/* ---- product view ----------------------------------------------------------- */
/* Product shots are JPEGs on white studio mattes. The deliberately-constant
   white plate + border makes the photo read as a framed product card in
   dark mode (instead of a glaring hole in the page) and gives it an edge on
   the white card in light mode. Never dim the merchandise with a filter. */
.ocm-prodimg {
  display: block; max-width: 100%; height: auto;
  margin: 0 auto 14px;
  background: #FFFFFF; /* constant on purpose - matches the baked-in matte */
  padding: 10px;
  border: 1px solid var(--oc-border);
  border-radius: var(--oc-r);
}
.ocm-prodname { font-family: var(--oc-display); font-size: 21px; font-weight: 700; line-height: 1.25; }
.ocm-prodprice {
  font-family: var(--oc-display); font-size: 24px; font-weight: 700;
  font-variant-numeric: tabular-nums; margin-top: 2px;
  color: var(--oc-primary); /* the AA-safe brand accent; name stays full ink */
}
.ocm-proddesc { color: var(--oc-ink-2); margin-top: 10px; }

/* ---- browse list ------------------------------------------------------------
   The group's items grouped under brochure headings, rendered by
   renderBrowse() in custom.js. Same card family as the cart items. */
.ocm-browse-head {
  font-family: var(--oc-display); font-size: 13.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--oc-ink-2);
  padding: 14px 0 8px;
}
.ocm-browse-head:first-child { padding-top: 4px; }

.ocm-browse-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; margin-bottom: 8px;
  background: var(--oc-surface); border: 1px solid var(--oc-border);
  border-radius: var(--oc-r);
  /* The whole card opens the product detail view (2026-08-14). */
  cursor: pointer;
}
/* Constant white plate: product shots carry a baked-in white matte, so this
   frames them in dark mode instead of leaving a glaring slab. 88px shows
   the 198x138 medium tier at better than 2x on a phone. */
.ocm-browse-img {
  width: 88px; height: 62px; flex: 0 0 auto;
  object-fit: contain; background: #FFFFFF;
  border: 1px solid var(--oc-border); border-radius: var(--oc-r-sm);
}
.ocm-browse-info { flex: 1 1 auto; min-width: 0; }
.ocm-browse-name { font-weight: 700; line-height: 1.3; }
.ocm-browse-meta { font-size: 14px; color: var(--oc-ink-2); font-variant-numeric: tabular-nums; }
.ocm-browse-meta .price { color: var(--oc-primary); font-weight: 600; }
/* Flow actions, so full 48px per the button rule - they were oc-btn--sm
   (38px) and failed both the 48px button floor and the 44px touch target. */
.ocm-browse-btn { flex: 0 0 auto; padding: 0 16px; }
/* Add-confirmation: flips to the "good" green for ~1.4s in place, so the
   shopper sees it landed without being pulled out of the list. */
/* Confirmation text is INK on the green wash, not the green itself:
   good-on-good-soft measures 4.09:1 in light mode, under AA. The wash plus
   the check mark carry the "it worked" signal; the word stays legible.
   (Same correction already applied to the warn/danger notices.) */
.ocm-browse-btn.is-added {
  background: var(--oc-good-soft); color: var(--oc-ink);
  border-color: var(--oc-good);
  box-shadow: none;
}

/* ---- cart ------------------------------------------------------------------- */
/* Cart item cards (participant-site line pattern) - addProd() in custom.js
   appends these; each carries its own quantity select and Remove button.
   The hidden .quantity span and the .price span in the meta line are the
   value contract for getTotals()/setAmt()/the zip-tax lookup. */
.ocm-cartitem {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 14px; margin-bottom: 10px;
  background: var(--oc-surface); border: 1px solid var(--oc-border);
  border-radius: var(--oc-r);
}
.ocm-cartitem .name { font-weight: 700; }
.ocm-cartitem-meta { font-size: 14px; color: var(--oc-ink-2); font-variant-numeric: tabular-nums; }
.ocm-cartitem-meta .price { color: var(--oc-primary); font-weight: 600; }
.ocm-cartitem-ctrls { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
/* Remove is a flow action on a payment page - 44px minimum, not the 38px
   oc-btn--sm default it inherits from the markup. */
.ocm-cartitem-ctrls .oc-btn--sm { min-height: 44px; }
.ocm-cartitem-qty { width: 78px; min-height: 44px; padding: 8px 32px 8px 12px; }

/* Receipt-rule total (style B, user-picked): a strong rule ties the label
   and amount together across the card; the amount stays a modest 20px so
   the row reads as a checkout summary, not a dumbbell. */
.ocm-totalbar {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-top: 14px;
  border-top: 2px solid var(--oc-ink);
  padding-top: 12px;
}
.ocm-totalbar .ocm-total-label { color: var(--oc-ink); font-weight: 700; }
.ocm-totalbar .ocm-total-amount {
  font-family: var(--oc-display); font-size: 20px;
  font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--oc-primary); /* money is blue - matches the product price */
}

/* ---- payment section (PayPal + Apple Pay + hosted card fields) -------------- */
/* Replaces the former inline style block in Default.aspx. Class and id names
   are load-bearing for the PayPal/Apple Pay scripts in Default.aspx. */

#payment-section { margin-top: 18px; }

/* One wallet stack (2026-08-14): Apple Pay / Google Pay / PayPal / Venmo
   render as a single column with ~10px gaps - no section titles, no OR
   dividers between wallets (the section h2 rule left with the headings).
   The one remaining divider introduces the card form. Hidden wallet
   sections are display:none, so their margins collapse away with them. */
#applepay-section, #googlepay-section { margin: 0 0 10px; }

/* Standalone Venmo render (2026-08-27): its own container below the PayPal
   button. :not(:empty) keeps the gap from appearing on devices where Venmo
   is ineligible and the container stays empty. */
#venmo-button-container:not(:empty) { margin-top: 10px; }

.ocm-cards-note { font-size: 16px; color: var(--oc-ink-2); margin: 0 0 14px; }

.ocm-cardrow {
  border: 1px solid var(--oc-border-2);
  border-radius: var(--oc-r-sm);
  padding: 10px 12px;
  margin-bottom: 10px;
  background: var(--oc-surface);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.ocm-cardrow:focus-within {
  border-color: var(--oc-primary);
  box-shadow: 0 0 0 4px var(--oc-primary-ring);
}
.ocm-cardrow input {
  border: none; outline: none; width: 100%;
  font-size: 16px; font-family: inherit;
  color: var(--oc-ink); background: transparent;
}
.ocm-cardrow input::placeholder { color: var(--oc-ink-3); }
/* Billing State is a native <select> now (2026-08-14) - flush inside the
   row like the inputs, native chevron kept as the affordance. */
.ocm-cardrow select {
  border: none; outline: none; width: 100%;
  font-size: 16px; font-family: inherit;
  color: var(--oc-ink); background: transparent;
  padding: 0;
}

.ocm-billing-heading {
  font-family: var(--oc-display); font-size: 16px; font-weight: 700;
  margin: 20px 0 10px;
}

.ocm-billing-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 10px; }
.ocm-billing-grid .ocm-cardrow { margin-bottom: 0; }

/* "Billing same as delivery" (2026-08-14): label wraps the checkbox so the
   whole 44px row is the tap target; checked hides + mirrors the fields. */
.ocm-billsame {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 12px; font-size: 16px; color: var(--oc-ink);
  min-height: 44px; cursor: pointer;
}
.ocm-billsame input[type="checkbox"] {
  width: 22px; height: 22px; flex: 0 0 auto;
  accent-color: var(--oc-primary);
}

/* Spinner inside the Pay Now button. currentColor works on both themes'
   button fills; the plain border line is the no-color-mix fallback. */
.ocm-spinner {
  display: inline-block; width: 15px; height: 15px;
  margin-right: 8px; vertical-align: middle;
  border: 2px solid currentColor;
  border: 2px solid color-mix(in srgb, currentColor 45%, transparent);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: ocm-spin .7s linear infinite;
}
@keyframes ocm-spin { to { transform: rotate(360deg); } }

.ocm-wallet-status { margin-top: 8px; font-size: 16px; color: var(--oc-ink-2); }
.ocm-wallet-status.error { color: var(--oc-danger); font-weight: 600; }

#card-field-errors {
  color: var(--oc-danger); font-size: 16px; font-weight: 600;
  margin-top: 8px; min-height: 18px;
}

.ocm-or-divider {
  display: flex; align-items: center; text-align: center;
  color: var(--oc-ink-2); font-size: 13.5px; font-weight: 600;
  letter-spacing: .08em; margin: 22px 0;
}
.ocm-or-divider::before, .ocm-or-divider::after {
  content: ""; flex: 1; border-bottom: 1px solid var(--oc-border);
}
.ocm-or-divider:not(:empty)::before { margin-right: 12px; }
.ocm-or-divider:not(:empty)::after  { margin-left: 12px; }

/* The surface-2 well is GONE (2026-08-27): it existed to give the old
   light-silver PayPal buttons a boundary on white, then made the silver
   Venmo button vanish. With PayPal blue (2026-08-15) and Venmo standalone
   in Venmo brand blue (2026-08-27), every button carries its own contrast
   and the stack sits bare on the card like Apple's and Google's. Top
   margin 0: the 10px stack gap comes from the wallet sections above. */
#paypal-button-container {
  margin-top: 0;
}

/* Apple's SDK renders this custom element; the CSS variables are the
   documented sizing hooks. 48px matches the system button height. */
apple-pay-button {
  --apple-pay-button-width: 100%;
  --apple-pay-button-height: 48px;
  --apple-pay-button-border-radius: 6px;
  --apple-pay-button-padding: 0px;
  display: block;
  width: 100%;
}

/* ---- thank-you page --------------------------------------------------------- */
/* Participant-credit chip spacing on the payment screen. */
#credit_line { margin: 8px 0 4px; }

/* One-time celebration on the thank-you page (BRANDING.md section 9,
   Personality) - pieces are injected by the page script in brand colors.
   Skipped under prefers-reduced-motion (script checks too; this kills any
   strays). This is the ceiling for animation. */
.ocm-confetti {
  position: fixed; inset: 0; overflow: hidden;
  pointer-events: none; z-index: 999;
}
.ocm-confetti span {
  position: absolute; top: -14px;
  width: 8px; height: 14px; border-radius: 2px;
  opacity: .9;
  animation: ocm-confetti-fall linear forwards;
}
@keyframes ocm-confetti-fall {
  to { transform: translateY(105vh) rotate(720deg); opacity: .7; }
}
@media (prefers-reduced-motion: reduce) { .ocm-confetti { display: none; } }

.ocm-okmark {
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--oc-good-soft); color: var(--oc-good);
  display: flex; align-items: center; justify-content: center;
  font-size: 28px; font-weight: 700;
  margin: 0 auto 14px;
}
/* Breathing room at the top of the thank-you card (oc-core zeroes h/p
   margins) and the centered gold credit chip for the participant. */
#thankyou h1 { margin: 0 0 12px; }
#thankyou > p { margin: 0 0 14px; }
.ocm-thanks-credit { text-align: center; margin: 0 0 12px; }
