/* ==========================================================================
   Gift Card Purchase — supplemental styles
   Everything else is Tailwind. This file only holds what Tailwind can't
   express cleanly: brand theming hooks, the gift-card "art" treatments and
   the motion.

   Brand theming: the server can emit a <style> block overriding --gc-brand-*
   on :root (or on #gc-root) to match the provider's brand.
   ========================================================================== */

:root {
  --gc-brand: #4f46e5;
  --gc-brand-hover: #4338ca;
  --gc-brand-soft: #eef2ff;
  --gc-brand-ring: rgba(79, 70, 229, 0.35);
  --gc-radius: 1rem;
}

/* --------------------------------------------------------------------------
   Carousel — one card per slide, scroll-snapped.

   `contain: paint` is load-bearing: without it Chromium lets the slides
   (8 x the scroller width) inflate documentElement.scrollWidth, which shows
   up as a horizontally scrolling page on phones.
   -------------------------------------------------------------------------- */
.gc-scroller {
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-behavior: smooth;
  contain: paint;
}
.gc-scroller::-webkit-scrollbar { display: none; }


/* --------------------------------------------------------------------------
   The gift card element
   Looks like a printed card / image, but it is live DOM: gradient ground,
   an SVG motif layer, the provider mark and the occasion name.
   -------------------------------------------------------------------------- */
.gc-card {
  position: relative;
  aspect-ratio: 1.586 / 1;      /* ISO/IEC 7810 ID-1, i.e. credit-card proportions */
  border-radius: var(--gc-radius);
  overflow: hidden;
  isolation: isolate;
  /* background-color and `color` are set inline per occasion: the colour shows
     while the art loads (and if it fails), the ink tints the provider mark. */
  outline: 1px solid rgba(24, 24, 27, 0.06);
  outline-offset: -1px;
  box-shadow:
    0 1px 2px rgba(15, 23, 42, 0.08),
    0 8px 24px -8px rgba(15, 23, 42, 0.25);
  transform: translateZ(0);
  transition:
    transform 320ms cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 320ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* The art layer. One flat JPEG per occasion carrying the gradient, the motif,
   the "GIFT CARD" eyebrow and the occasion name — the same file the gift card
   email uses, because email clients render neither SVG nor CSS gradients. The
   soft top-light that used to be a ::before is baked into it. */
.gc-card-art {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Sweeping shine */
.gc-card::after {
  content: "";
  position: absolute;
  top: -60%;
  bottom: -60%;
  left: -75%;
  width: 45%;
  z-index: 3;
  transform: rotate(18deg) translateX(-40%);
  background: linear-gradient(
    to right,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.75) 50%,
    rgba(255, 255, 255, 0) 100%
  );
  opacity: 0;
  pointer-events: none;
}

.gc-card-option:hover .gc-card,
.gc-card-option:focus-visible .gc-card {
  transform: translateY(-6px) scale(1.015);
  box-shadow:
    0 2px 4px rgba(15, 23, 42, 0.1),
    0 18px 30px -14px rgba(15, 23, 42, 0.4);
}

.gc-card-option:hover .gc-card::after,
.gc-card-option:focus-visible .gc-card::after {
  animation: gc-shine 900ms cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes gc-shine {
  0%   { opacity: 0; transform: rotate(18deg) translateX(-40%); }
  15%  { opacity: 1; }
  100% { opacity: 0; transform: rotate(18deg) translateX(420%); }
}

.gc-card-content {
  position: relative;
  z-index: 4;
  display: block;
  height: 100%;
  padding: 4.5cqw;
}

/* Sized in cqw with no clamp ON PURPOSE. The occasion name and the "GIFT CARD"
   eyebrow are baked into the art and therefore scale linearly with the card; a
   clamp() here would stop tracking them and the two would drift apart at the
   17rem review size. Don't reintroduce a min/max. */
.gc-card-provider {
  font-size: 3.13cqw;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.75;
}

/* Sits under the provider mark on the card. The recipient is not the buyer —
   without this they have a business name and no idea which branch honours it. */
.gc-card-location {
  display: block;
  margin-top: 0.15em;
  font-size: 2.7cqw;
  font-weight: 500;
  letter-spacing: 0.02em;
  opacity: 0.7;
}

.gc-card-logo {
  max-height: 8.6cqw;
  max-width: 62%;
  object-fit: contain;
}

/* Container queries so type scales with the card, not the slide or viewport */
.gc-card { container-type: inline-size; }

/* --------------------------------------------------------------------------
   Selected state — driven by the sr-only radio via :has()
   (peer-checked handles the same thing in Tailwind; :has keeps it in one place)
   -------------------------------------------------------------------------- */
.gc-card-option:has(input:checked) .gc-card {
  transform: translateY(-6px) scale(1.02);
  box-shadow:
    0 2px 4px rgba(15, 23, 42, 0.1),
    0 18px 30px -16px rgba(15, 23, 42, 0.45);
}

.gc-card-option:has(input:checked) .gc-card-check {
  opacity: 1;
  transform: scale(1);
}

/* Keyboard focus still needs a visible ring — this only appears while
   tabbing, never on click or touch. */
.gc-card-option:has(input:focus-visible) .gc-card {
  box-shadow:
    0 0 0 3px #fff,
    0 0 0 6px var(--gc-brand),
    0 18px 30px -16px rgba(15, 23, 42, 0.45);
}

.gc-card-check {
  position: absolute;
  bottom: 0.75rem;
  right: 0.75rem;
  z-index: 5;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 9999px;
  background: var(--gc-brand);
  color: #fff;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.85);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 200ms ease, transform 260ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.gc-card-option:has(input:checked) .gc-card-label { color: var(--gc-brand); font-weight: 600; }

/* --------------------------------------------------------------------------
   Segmented radio groups ("for someone else" / "for myself", "now" / "later")
   -------------------------------------------------------------------------- */
.gc-choice {
  transition: border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease;
}
.gc-choice-input:checked + .gc-choice {
  border-color: var(--gc-brand);
  background-color: var(--gc-brand-soft);
  box-shadow: 0 0 0 1px var(--gc-brand);
}
.gc-choice-input:focus-visible + .gc-choice {
  outline: 2px solid var(--gc-brand);
  outline-offset: 2px;
}
.gc-choice-input:checked + .gc-choice .gc-choice-dot {
  border-color: var(--gc-brand);
  background-color: var(--gc-brand);
}
.gc-choice-input:checked + .gc-choice .gc-choice-dot::after { transform: scale(1); }
.gc-choice-dot::after {
  content: "";
  display: block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 9999px;
  background: #fff;
  transform: scale(0);
  transition: transform 180ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Carousel dots */
.gc-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 9999px;
  background: #d4d4d8;
  transition: width 220ms cubic-bezier(0.22, 1, 0.36, 1), background-color 200ms ease;
}
.gc-dot[aria-current="true"] {
  width: 1.5rem;
  background: var(--gc-brand);
}

/* Amount preset chips */
.gc-amount-chip[aria-pressed="true"] {
  border-color: var(--gc-brand);
  background-color: var(--gc-brand);
  color: #fff;
}

/* reCAPTCHA v3 renders a floating badge bottom-right. Google's terms allow
   hiding it provided the attribution text is shown instead — which it is, under
   the Buy button. Remove this rule if you remove that text. */
.grecaptcha-badge { visibility: hidden; }

/* Honeypot. Positioned off-screen rather than display:none — naive bots skip
   display:none inputs but happily fill this one. Also out of the tab order and
   the accessibility tree (see the markup), so no real person ever meets it. */
.gc-hp {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   Fields
   -------------------------------------------------------------------------- */
.gc-field {
  width: 100%;
  border-radius: 0.625rem;
  border: 1px solid #d4d4d8;
  background: #fff;
  padding: 0.75rem 0.875rem;
  font-size: 1.0625rem;
  line-height: 1.625rem;
  color: #18181b;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.gc-field::placeholder { color: #a1a1aa; }
.gc-field:focus {
  outline: none;
  border-color: var(--gc-brand);
  box-shadow: 0 0 0 3px var(--gc-brand-ring);
}
.gc-field:disabled { background: #f4f4f5; color: #71717a; cursor: not-allowed; }

/* .gc-field's padding shorthand beats Tailwind's pl-* utilities, so prefixed
   inputs (the "$" on the amount field) get their own class. */
.gc-field-prefixed { padding-left: 1.75rem; }

/* Fieldset legends: float removes the notch in the rounded border so these
   sections match the plain <section> cards. */
.gc-legend { float: left; width: 100%; padding: 0; }
.gc-legend + * { clear: both; }

/* Only flag invalid fields after a submit/continue attempt */
.gc-validated .gc-field:invalid,
.gc-field.gc-invalid {
  border-color: #dc2626;
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.18);
}

.gc-label {
  display: block;
  font-size: 0.9375rem;
  font-weight: 500;
  color: #3f3f46;
  margin-bottom: 0.375rem;
}
.gc-req { color: #dc2626; }

/* Payment gateway iframe mount — sized/styled to match .gc-field exactly */
.gc-iframe-mount {
  position: relative;
  min-height: 3.25rem;
  border-radius: 0.625rem;
  border: 1px solid #d4d4d8;
  background: #fff;
  overflow: hidden;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.gc-iframe-mount.gc-iframe-focus {
  border-color: var(--gc-brand);
  box-shadow: 0 0 0 3px var(--gc-brand-ring);
}
.gc-iframe-mount iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 3.25rem;
  border: 0;
}

/* --------------------------------------------------------------------------
   Step transitions & misc motion
   -------------------------------------------------------------------------- */
/* Tailwind display utilities (flex/grid/block) out-specify the [hidden]
   attribute, so anything we toggle with `hidden` needs this to actually hide. */
#gc-root [hidden],
#gc-root[hidden] { display: none !important; }

.gc-step[hidden] { display: none !important; }

.gc-step-enter { animation: gc-fade-up 380ms cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes gc-fade-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.gc-reveal { animation: gc-reveal 260ms cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes gc-reveal {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   Success-panel calls to action
   -------------------------------------------------------------------------- */
.gc-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border-radius: 0.75rem;
  padding: 0.8125rem 1.5rem;
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.25;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, filter 160ms ease;
}
.gc-cta:focus-visible {
  outline: 2px solid var(--gc-brand);
  outline-offset: 2px;
}

/* The provider's brand colour, not the panel's emerald: the emerald says
   "this worked", the button says "here is where you go next", and they are
   different jobs. */
.gc-cta-primary {
  background: var(--gc-brand);
  color: #fff;
}
.gc-cta-primary:hover { filter: brightness(1.1); }

.gc-cta-secondary {
  background: #fff;
  border: 1px solid #d4d4d8;
  color: #3f3f46;
}
.gc-cta-secondary:hover { background: #f4f4f5; }

/* Collapsible details chevron */
.gc-details[open] .gc-details-chevron { transform: rotate(180deg); }
.gc-details-chevron { transition: transform 200ms ease; }

/* Spinner on the submit button */
.gc-spinner {
  width: 1rem;
  height: 1rem;
  border-radius: 9999px;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-top-color: #fff;
  animation: gc-spin 700ms linear infinite;
}
@keyframes gc-spin { to { transform: rotate(360deg); } }

/* Success checkmark draw-in */
@keyframes gc-pop {
  0%   { transform: scale(0.6); opacity: 0; }
  60%  { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.gc-pop { animation: gc-pop 420ms cubic-bezier(0.34, 1.56, 0.64, 1) both; }

@media (prefers-reduced-motion: reduce) {
  .gc-card,
  .gc-card-check,
  .gc-choice,
  .gc-step-enter,
  .gc-reveal,
  .gc-pop {
    animation: none !important;
    transition: none !important;
  }
  .gc-card-option:hover .gc-card { transform: none; }
  .gc-scroller { scroll-behavior: auto; }
}
