/*
 * English Bujhbo paywall + legal pages, served from the same NestJS process
 * as the GraphQL API. Replaces the standalone `web-premium` Next.js app.
 * Ported from web-premium/app/globals.css (which was Tailwind-based) — only
 * the rules actually used by /premium /checkout /privacy-policy /terms-of-
 * service are recreated here as hand-written CSS.
 */

:root {
  --foreground: #0f172a;
  --background: #f8fafc;
  --surface: #ffffff;
  --border: #e2e8f0;
  --border-strong: #cbd5e1;
  --muted: #475569;
  --tertiary: #64748b;
  --brand: #2563eb;
  --brand-dark: #1d4ed8;
  --brand-light: #dbeafe;
  --brand-tint: #eff6ff;
  --accent: #f97316;
  --accent-light: #fed7aa;
  --success: #16a34a;
  --success-bg: #dcfce7;
  --danger: #dc2626;
  --danger-bg: #fee2e2;
  --warning-text: #b45309;
  --warning-bg: #fef3c7;
  --radius-sm: 0.5rem;
  --radius-md: 0.75rem;
  --radius-lg: 1rem;
  --radius-xl: 1.5rem;
}

* { box-sizing: border-box; }

html, body {
  min-height: 100%;
  margin: 0;
  padding: 0;
  color: var(--foreground);
  background: var(--background);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

/* Bangla content: Tiro Bangla + extra line-height + 2px top pad so
   matras don't clip. Mirrors mobile's `bnText()` helper. */
:lang(bn), .font-bn {
  font-family: 'Tiro Bangla', 'Kohinoor Bangla', 'Noto Sans Bengali', serif;
  line-height: 1.5;
  padding-top: 2px;
}

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

button {
  font-family: inherit;
  cursor: pointer;
  border: 0;
  background: transparent;
  font-size: inherit;
}

button:disabled { cursor: not-allowed; opacity: 0.5; }

.container {
  max-width: 640px;
  margin: 0 auto;
  padding: 1.5rem 1rem;
}

.container-wide {
  max-width: 800px;
}

/* Card surfaces (paywall pricing, checkout shell, etc.). */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04);
}

.card-flat { box-shadow: none; }

/* Primary CTA button (the "Buy 6 months" / "Continue" affordances). */
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.875rem 1.25rem;
  background: var(--brand);
  color: #ffffff;
  border-radius: var(--radius-md);
  font-weight: 700;
  min-height: 48px;
  width: 100%;
  transition: background 120ms;
}
.btn-primary:hover { background: var(--brand-dark); text-decoration: none; }
.btn-primary:disabled { background: var(--border-strong); }

.btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.75rem 1.25rem;
  background: var(--surface);
  color: var(--foreground);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-md);
  font-weight: 600;
  min-height: 44px;
}
.btn-secondary:hover { background: var(--background); text-decoration: none; }

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.75rem;
  color: var(--muted);
  font-weight: 600;
  min-height: 40px;
}

/* Form fields (promo code input, etc.). */
.field {
  display: block;
  width: 100%;
  padding: 0.75rem 1rem;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  font-size: 1rem;
  color: var(--foreground);
  outline: none;
  transition: border-color 120ms;
}
.field:focus { border-color: var(--brand); }
.field-label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  margin-bottom: 0.375rem;
  color: var(--foreground);
}

/* Status banners (success, danger, info). */
.banner {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border-radius: var(--radius-md);
  border: 1px solid;
  font-size: 0.9375rem;
}
.banner-danger {
  background: var(--danger-bg);
  border-color: var(--danger);
  color: var(--danger);
}
.banner-success {
  background: var(--success-bg);
  border-color: var(--success);
  color: var(--success);
}
.banner-warning {
  background: var(--warning-bg);
  border-color: var(--warning-text);
  color: var(--warning-text);
}
.banner-info {
  background: var(--brand-tint);
  border-color: var(--brand);
  color: var(--brand-dark);
}

/* Pricing tiles on /premium. Two side-by-side cards (six-month / twelve-month). */
.tier-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin: 1.25rem 0;
}
.tier {
  position: relative;
  padding: 1.25rem 1rem;
  background: var(--surface);
  border: 2px solid var(--border);
  border-radius: var(--radius-md);
  text-align: center;
  cursor: pointer;
  transition: border-color 120ms, transform 120ms;
}
.tier.selected {
  border-color: var(--brand);
  background: var(--brand-tint);
}
.tier:hover { border-color: var(--brand-dark); }
.tier-name { font-size: 0.875rem; font-weight: 600; color: var(--muted); }
.tier-price { font-size: 1.75rem; font-weight: 800; margin-top: 0.25rem; }
.tier-period { font-size: 0.8125rem; color: var(--tertiary); }
.tier-badge {
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent);
  color: #ffffff;
  font-size: 0.6875rem;
  font-weight: 700;
  padding: 0.125rem 0.625rem;
  border-radius: 999px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

/* Section spacing helpers. */
.stack { display: flex; flex-direction: column; gap: 1rem; }
.stack-sm { display: flex; flex-direction: column; gap: 0.5rem; }
.stack-lg { display: flex; flex-direction: column; gap: 1.5rem; }
.row { display: flex; align-items: center; gap: 0.75rem; }
.muted { color: var(--muted); }
.tertiary { color: var(--tertiary); }
.text-sm { font-size: 0.875rem; }
.text-xs { font-size: 0.75rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
.font-bold { font-weight: 700; }
.font-semibold { font-weight: 600; }
.text-center { text-align: center; }
.hidden { display: none !important; }

/* Page header (logo + brand wordmark). */
.page-header {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.page-header-brand {
  font-size: 1.125rem;
  font-weight: 800;
  letter-spacing: -0.5px;
  color: var(--foreground);
}

/* Footer (legal links). */
.page-footer {
  margin-top: 2rem;
  padding: 1.25rem 1rem;
  text-align: center;
  font-size: 0.8125rem;
  color: var(--tertiary);
  border-top: 1px solid var(--border);
}
.page-footer a { color: var(--brand); }

/* Long-form prose for /privacy-policy and /terms-of-service. */
.prose h1 { font-size: 1.75rem; font-weight: 800; margin: 0 0 0.5rem; }
.prose h2 { font-size: 1.25rem; font-weight: 700; margin: 1.5rem 0 0.5rem; }
.prose h3 { font-size: 1.0625rem; font-weight: 600; margin: 1.25rem 0 0.375rem; }
.prose p { margin: 0.5rem 0; line-height: 1.6; color: var(--foreground); }
.prose ul { padding-left: 1.25rem; line-height: 1.7; }
.prose li { margin: 0.25rem 0; }
.prose .last-updated { color: var(--tertiary); font-size: 0.875rem; margin: 0 0 1.5rem; }

/* ── Paywall (/premium) — banglapay + IAP full-bleed variants. ─────────
   Both variants render as a fixed overlay over the page chrome (matches
   the mobile bottom-sheet aesthetic). Scrollable content area with a
   sticky CTA pinned at the bottom. */
.paywall-overlay {
  position: fixed;
  inset: 0;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  z-index: 50;
  overflow: hidden;
}
.paywall-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 999px;
  background: rgba(241, 245, 249, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  z-index: 10;
}
.paywall-close:hover { background: rgb(226, 232, 240); }
.paywall-scroll {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
  padding: 1.25rem 1.25rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.paywall-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}
/* Gentle idle float on the paywall mascot so the (now shorter) screen feels
   alive rather than static. Disabled for reduced-motion users. */
.paywall-hero .mascot { animation: paywall-mascot-bob 3.2s ease-in-out infinite; }
@keyframes paywall-mascot-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
@media (prefers-reduced-motion: reduce) {
  .paywall-hero .mascot { animation: none; }
}
.paywall-hero-icon {
  width: 5rem;
  height: 5rem;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.paywall-hero-icon-rocket {
  background: #f0f9ff;
  border: 1px solid #e0f2fe;
}
.paywall-hero-icon-crown {
  width: 6rem;
  height: 6rem;
  border-radius: 1.5rem;
  background: linear-gradient(135deg, var(--brand), var(--brand-dark));
  box-shadow: 0 10px 30px rgba(37, 99, 235, 0.3);
}
.paywall-eyebrow {
  display: inline-block;
  padding: 0.25rem 0.75rem;
  background: #f0f9ff;
  border: 1px solid #e0f2fe;
  color: #0369a1;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  border-radius: 999px;
  text-transform: uppercase;
}
.paywall-title {
  font-size: 1.375rem;
  font-weight: 700;
  text-align: center;
  margin: 0;
  line-height: 1.35;
}
.paywall-sub {
  font-size: 0.9375rem;
  color: var(--muted);
  text-align: center;
  margin: 0;
  line-height: 1.55;
  padding: 0 0.5rem;
}
.paywall-price-card {
  background: #f0f9ff99;
  border-radius: 1rem;
  padding: 1rem;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.75rem;
}
.paywall-price-left { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.paywall-price-right { display: flex; flex-direction: column; align-items: flex-end; gap: 0.125rem; flex-shrink: 0; }
.paywall-price-label { font-size: 0.8125rem; font-weight: 700; color: var(--muted); margin: 0; }
.paywall-price-strike { font-size: 0.875rem; color: var(--tertiary); text-decoration: line-through; line-height: 1; }
.paywall-price-final { font-size: 2rem; font-weight: 800; line-height: 1; color: var(--foreground); }
.paywall-savings-pill {
  display: inline-flex;
  align-self: flex-start;
  background: #d1fae5;
  color: #065f46;
  padding: 0.25rem 0.625rem;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 700;
}
.paywall-benefits { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.625rem; }
.paywall-benefit {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  background: #f8fafc;
  border: 1px solid #f1f5f9;
  border-radius: 0.75rem;
  font-size: 0.9375rem;
  font-weight: 600;
}
.paywall-benefit-icon {
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.75rem;
  background: linear-gradient(135deg, #0ea5e9, var(--brand));
  color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.paywall-plans { display: flex; flex-direction: column; gap: 0.625rem; }
.paywall-plan {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border: 1px solid var(--border);
  border-radius: 1rem;
  background: var(--surface);
  position: relative;
}
.paywall-plan-icon {
  flex-shrink: 0;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.75rem;
  background: #f1f5f9;
  color: var(--tertiary);
  display: flex;
  align-items: center;
  justify-content: center;
}
.paywall-plan-text { flex: 1; min-width: 0; }
.paywall-plan-dur { font-size: 0.9375rem; font-weight: 700; margin: 0; line-height: 1; }
.paywall-plan-sub { font-size: 0.6875rem; color: var(--tertiary); letter-spacing: 0.04em; margin: 0.25rem 0 0; }
.paywall-plan-badge {
  background: #fef3c7;
  color: #92400e;
  font-size: 0.625rem;
  font-weight: 700;
  padding: 0.25rem 0.5rem;
  border-radius: 999px;
}
.paywall-cta-wrap {
  border-top: 1px solid #f1f5f9;
  background: var(--surface);
  /* Bottom inset is owned by the RN sheet's paddingBottom; do NOT add
     env(safe-area-inset-bottom) here too or it double-counts (the WebView
     reports the window's bottom inset even though the sheet sits above it),
     leaving a dead band under the CTA. */
  padding: 1rem 1.25rem 1rem;
}
.paywall-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  height: 3.5rem;
  background: linear-gradient(135deg, #0ea5e9, var(--brand-dark));
  color: #ffffff;
  border-radius: 1rem;
  font-size: 1rem;
  font-weight: 600;
  box-shadow: 0 10px 25px rgba(37, 99, 235, 0.3);
  cursor: pointer;
}
.paywall-cta:hover { text-decoration: none; filter: brightness(0.97); }
/* Terms / Privacy links under the CTA — App Store 3.1.2(c) requirement.
   Small, centered, pinned at the very bottom of the sheet. */
.paywall-legal {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  margin: 0.625rem 0 0;
  font-size: 0.6875rem;
  line-height: 1.2;
  text-align: center;
  color: var(--tertiary);
}
.paywall-legal a {
  color: var(--tertiary);
  text-decoration: underline;
}
.paywall-legal a:hover { color: var(--brand-dark); }

/* Card-variant icons (maintenance, custom, contact). Centered round
   badge above the title. */
.paywall-card-icon {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 999px;
  margin: 0 auto 0.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid;
}
.paywall-card-icon-warn { background: #fef3c7; border-color: #fde68a; color: #b45309; }
.paywall-card-icon-info { background: #fef3c7; border-color: #fde68a; color: #b45309; }
.paywall-card-icon-announce { background: #f0f9ff; border-color: #e0f2fe; color: #0369a1; }
.paywall-card-icon-success { background: #d1fae5; border-color: #a7f3d0; color: #15803d; }

/* ── /v1/web/checkout — pricing + promo + total + CTA ─────────────────
   Ported from the original web-premium CheckoutClient layout: tall
   white card holding the plan radios, promo input row, launch-promo
   banner, total + pay button block, and trailing trust strip below
   the card. Sky-blue accent (#0284c7) for selection + the pay CTA. */
.checkout-page {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.checkout-header {
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0 0.25rem;
}
/* Compact header — mascot left, text right. Lifts ~80px of vertical
   real estate compared to the centered-stacked variant, which matters
   inside the mobile WebView where every pixel counts before the user
   has to scroll to see the plan rows. */
.checkout-header-row {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0 0.25rem;
}
.checkout-header-text { flex: 1; min-width: 0; }
.checkout-header-text .checkout-h1 {
  font-size: 1.25rem;
  text-align: left;
  line-height: 1.25;
}
.checkout-header-text .checkout-sub { text-align: left; }
/* Small mascot stage for inline header. Halo + image both shrink in
   proportion to the page-hero default, so the same `.mascot-wrap`
   markup works for both sizes. */
.mascot-wrap.mascot-sm { width: 64px; height: 64px; }
.mascot-wrap.mascot-sm .mascot { width: 56px; height: 56px; }
/* `.mascot-md` — middle ground for premium paywall heroes where the
   mascot is the focal point but shouldn't dominate the viewport on
   mobile WebView. */
.mascot-wrap.mascot-md { width: 96px; height: 96px; }
.mascot-wrap.mascot-md .mascot { width: 80px; height: 80px; }
/* Mascot stage — soft sky-100 halo behind the fish, identical to the
   mobile onboarding/profile treatment so the brand character carries
   across surfaces. Used by the checkout header + success/failure
   pages; reusable anywhere a hero illustration belongs. */
.mascot-wrap {
  position: relative;
  width: 140px;
  height: 140px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mascot-halo {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: #e0f2fe;
  opacity: 0.7;
}
.mascot-halo-warn { background: #fef3c7; }
.mascot {
  position: relative;
  width: 120px;
  height: 120px;
  object-fit: contain;
}

.checkout-h1 {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
  line-height: 1.25;
  color: var(--foreground);
}
.checkout-sub { font-size: 0.875rem; color: var(--tertiary); margin: 0; }
.checkout-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 1rem;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04);
  overflow: hidden;
}
.checkout-section {
  /* Reset the native <fieldset> chrome (default border/margin/min-width),
     otherwise the plan picker shows the browser's grooved box border. */
  border: 0;
  margin: 0;
  min-width: 0;
  padding: 0.875rem 1.25rem 0.5rem;
}

/* Plan radio rows. Hidden native input + custom circle + price block. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.plan-stack { display: flex; flex-direction: column; gap: 0.375rem; }
.plan-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.875rem;
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  background: var(--surface);
  cursor: pointer;
  transition: border-color 120ms, background-color 120ms, box-shadow 120ms;
  /* Tapping the label focuses the underlying radio. Safari draws the
     default user-agent focus ring on the *label* (the row) and it
     reads as a black border. Suppress the default; we draw our own
     focus-visible ring below for keyboard users. */
  outline: none;
  -webkit-tap-highlight-color: transparent;
}
.plan-row:hover { border-color: var(--border-strong); }
.plan-row:focus-within {
  outline: none;
}
.plan-row:has(input:focus-visible) {
  box-shadow: 0 0 0 3px rgba(2, 132, 199, 0.25);
}
.plan-stack input[type="radio"] { outline: none; }
.plan-row.selected {
  border-color: #0284c7;
  background: rgba(186, 230, 253, 0.18);
  box-shadow: inset 0 0 0 1px #0284c7;
}
.plan-row.is-best { padding-top: 1.25rem; }
.plan-best-badge {
  position: absolute;
  top: 0.125rem;
  left: 0.75rem;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #ffffff;
  background: #0284c7;
  padding: 0.125rem 0.5rem;
  border-radius: 0.25rem;
}
.plan-radio {
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 999px;
  border: 2px solid var(--border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 120ms;
}
.plan-row.selected .plan-radio { border-color: #0284c7; }
.plan-radio-dot {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 999px;
  background: #0284c7;
  opacity: 0;
  transition: opacity 120ms;
}
.plan-row.selected .plan-radio-dot { opacity: 1; }
.plan-text { flex: 1; min-width: 0; }
.plan-dur {
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.2;
  margin: 0;
  color: var(--foreground);
  white-space: nowrap;
}
.plan-savings {
  font-size: 0.75rem;
  color: #059669;
  margin: 0.0625rem 0 0;
  white-space: nowrap;
}
.plan-price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  flex-shrink: 0;
}
.plan-price-strike {
  font-size: 0.6875rem;
  text-decoration: line-through;
  color: var(--tertiary);
  line-height: 1;
}
.plan-price-final {
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.15;
  margin-top: 0.125rem;
  color: var(--foreground);
  white-space: nowrap;
}
/* Per-month unit price under each multi-month plan ("৳133/মাস"): the quiet
   anchor that makes longer terms read as the better deal. */
.plan-permonth {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--brand-dark, #1d4ed8);
  line-height: 1;
  margin-top: 0.1875rem;
  white-space: nowrap;
}

/* Promo input row + applied chip. */
.promo-label {
  display: block;
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--tertiary);
}
.promo-label-opt { font-weight: 400; color: #94a3b8; margin-left: 0.25rem; }
.promo-input-row {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.promo-input {
  flex: 1;
  min-width: 0;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--border-strong);
  border-radius: 0.5rem;
  font-size: 0.875rem;
  text-transform: uppercase;
  outline: none;
  transition: border-color 120ms, box-shadow 120ms;
}
.promo-input:focus {
  border-color: #0284c7;
  box-shadow: 0 0 0 2px rgba(2, 132, 199, 0.2);
}
.promo-apply {
  flex-shrink: 0;
  padding: 0.625rem 1rem;
  background: #0284c7;
  color: #ffffff;
  border-radius: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  transition: background 120ms;
}
.promo-apply:hover:not(:disabled) { background: #0369a1; }
.promo-apply:disabled { background: var(--border); color: var(--tertiary); }
.promo-applied {
  margin-top: 0.5rem;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem;
  background: #f0f9ff;
  border: 1px solid #bae6fd;
  border-radius: 0.5rem;
  padding: 0.375rem 0.625rem;
}
.promo-applied-msg { color: #0c4a6e; font-size: 0.6875rem; line-height: 1.4; flex: 1; }
.promo-applied-clear {
  color: #0369a1;
  font-size: 0.625rem;
  font-weight: 500;
  text-decoration: underline;
}
.promo-error {
  margin: 0.5rem 0 0;
  color: #be123c;
  font-size: 0.75rem;
}
/* "Already applied" / informational variant — neutral sky tone, not a red
   error. Matches the applied-promo chip colour. */
.promo-error.promo-notice {
  color: #0369a1;
}

/* Launch promo info banner (green). */
.checkout-launch-banner {
  margin: 0.5rem 1.25rem 0.875rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: #f0fdf4;
  border: 1px solid #d1fae5;
  border-radius: 0.5rem;
  padding: 0.375rem 0.625rem;
}
.checkout-launch-pct {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1rem;
  height: 1rem;
  border-radius: 999px;
  background: #d1fae5;
  color: #047857;
  font-size: 0.5625rem;
  font-weight: 700;
}
.checkout-launch-text { font-size: 0.6875rem; color: #166534; line-height: 1.4; margin: 0; }
/* The paywall hid the price, so when checkout loads the discount banner should
   announce itself: slide + fade in, then a couple of soft pulses draw the eye
   so the reveal lands as a deal, not a surprise. */
.checkout-launch-banner {
  animation: checkout-launch-in 0.5s ease-out both,
             checkout-launch-pulse 1.6s ease-in-out 0.5s 2;
}
@keyframes checkout-launch-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes checkout-launch-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(5, 150, 105, 0); }
  50%      { box-shadow: 0 0 0 6px rgba(5, 150, 105, 0.14); }
}
@media (prefers-reduced-motion: reduce) {
  .checkout-launch-banner { animation: none; }
}

/* Total + pay block. Now sits below the card as its own bar (see
   .checkout-total-sticky) so it can pin to the bottom of the screen. */
.checkout-total-row {
  padding: 1rem 1.25rem 1.25rem;
  margin-top: 0.5rem;
  border-top: 1px solid #f1f5f9;
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
}
/* Lock the total + pay block to the bottom of the viewport so the button
   stays reachable while the plans / promo above scroll — same intent as the
   paywall's pinned CTA. Sticky (not fixed) keeps the form, modals and normal
   document flow intact; it must live OUTSIDE .checkout-card, whose
   overflow:hidden would otherwise scope the sticky to the card. */
.checkout-total-sticky {
  position: sticky;
  bottom: 0;
  z-index: 5;
  background: var(--surface);
  border-radius: 1rem;
  box-shadow: 0 -6px 16px rgba(15, 23, 42, 0.06);
  /* Clear the home indicator / gesture bar in a browser viewport. env() is
     0 where there's no inset, so it's safe across Android nav styles. */
  padding-bottom: calc(1.25rem + env(safe-area-inset-bottom));
}
.checkout-total-block {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}
.checkout-total-label { font-size: 0.875rem; font-weight: 500; color: var(--muted); }
.checkout-total-amount { display: flex; align-items: baseline; gap: 0.5rem; min-width: 0; }
.checkout-total-strike {
  font-size: 0.875rem;
  text-decoration: line-through;
  color: var(--tertiary);
}
.checkout-total-final {
  font-size: 1.75rem;
  font-weight: 800;
  color: var(--foreground);
}
.checkout-pay {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  min-height: 52px;
  padding: 0.875rem 1rem;
  background: #0284c7;
  color: #ffffff;
  border-radius: 0.75rem;
  font-size: 0.9375rem;
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(2, 132, 199, 0.2);
  transition: background 120ms;
}
.checkout-pay:hover { background: #0369a1; }
.checkout-pay:disabled { background: #cbd5e1; cursor: not-allowed; }

/* Payment-method chips. */
/* Methods + disclaimer block — moved out of the pinned pay bar so it scrolls
   below it rather than occupying locked screen space. */
.checkout-payinfo {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
.checkout-methods {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.checkout-methods-row {
  display: flex;
  justify-content: center;
  gap: 0.375rem;
}
.method-chip {
  font-size: 0.625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  background: #f1f5f9;
  border: 1px solid var(--border);
  padding: 0.125rem 0.375rem;
  border-radius: 0.25rem;
}
/* Brand-tinted chips for the dominant BD wallets — recognition + trust without
   shipping third-party logo assets. Visa/Mastercard stay neutral. */
.method-chip-bkash  { color: #e2136e; background: #fdeaf3; border-color: #f8c6dd; }
.method-chip-nagad  { color: #ec1c24; background: #fdeaea; border-color: #f8c4c6; }
.method-chip-rocket { color: #8c3494; background: #f6ecf7; border-color: #e3c9e6; }

.checkout-disclaimer {
  font-size: 0.6875rem;
  color: #94a3b8;
  text-align: center;
  line-height: 1.5;
  margin: 0;
}

/* Trust strip — two cards below the form. */
.checkout-trust {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
  list-style: none;
  padding: 0;
  margin: 0;
}
.trust-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.5rem;
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--muted);
  text-align: center;
}
.trust-item svg { color: var(--tertiary); }

/* Loading overlay shown while the form posts to /v1/web/checkout and
   we wait for the 303 redirect to EPS. Mascot gently bobs, indeterminate
   sky-blue bar sweeps left-to-right so the user has constant feedback
   the system hasn't frozen. Full-screen + high z-index so it sits over
   the form (and over the upsell modal if it's still up). */
.loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: rgba(15, 23, 42, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  animation: loading-overlay-in 200ms ease-out;
}
@keyframes loading-overlay-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.loading-card {
  background: var(--surface);
  width: 100%;
  max-width: 20rem;
  border-radius: 1rem;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
}
.loading-mascot {
  animation: loading-mascot-bob 1.6s ease-in-out infinite;
}
@keyframes loading-mascot-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
.loading-title {
  font-size: 1.0625rem;
  font-weight: 700;
  margin: 0;
  text-align: center;
  line-height: 1.4;
  color: var(--foreground);
}
.loading-body {
  font-size: 0.875rem;
  color: var(--muted);
  margin: 0;
  text-align: center;
}
.loading-bar {
  width: 100%;
  height: 4px;
  background: #e2e8f0;
  border-radius: 999px;
  overflow: hidden;
  margin-top: 0.25rem;
}
.loading-bar-fill {
  width: 40%;
  height: 100%;
  background: linear-gradient(90deg, #0284c7, #38bdf8, #0284c7);
  border-radius: 999px;
  animation: loading-bar-sweep 1.4s ease-in-out infinite;
}
@keyframes loading-bar-sweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

/* YEAR100 upsell modal — intercepts the pay click for 6-month users
   once per page load to offer ৳100 off the 12-month plan. */
.upsell-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(15, 23, 42, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.upsell-modal {
  position: relative;
  background: var(--surface);
  width: 100%;
  max-width: 22rem;
  border-radius: 1rem;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
}
.upsell-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  background: #f1f5f9;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
}
.upsell-close:hover { background: #e2e8f0; }
/* Upsell-modal-sized mascot — smaller than the page-hero default so
   the fish doesn't dominate the limited modal real estate. Halo
   stays sky-100 to keep the visual consistent with the rest of the
   brand. */
.upsell-mascot { width: 110px; height: 110px; margin: 0 auto; }
.upsell-mascot .mascot { width: 110px; height: 110px; }
/* Selim is a full-figure character, not a round head — drop the circular halo
   here so he stands free (the paywall/header fish keep theirs). */
.upsell-mascot .mascot-halo { display: none; }
.upsell-head { text-align: center; display: flex; flex-direction: column; gap: 0.375rem; }
.upsell-title { font-size: 1.125rem; font-weight: 700; margin: 0; line-height: 1.35; color: var(--foreground); }
.upsell-body { font-size: 0.875rem; color: var(--muted); margin: 0; line-height: 1.55; }
/* One 3-col grid, two rows (equation over prices). Shared columns keep the
   left/right values and the center cell aligned — a borderless little table. */
.upsell-price {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  justify-items: center;
  row-gap: 0.375rem;
  column-gap: 0.75rem;
  background: #f8fafc;
  border-radius: 0.75rem;
  padding: 0.625rem 1rem;
}
.upsell-eq-cell { font-size: 0.8125rem; font-weight: 600; white-space: nowrap; }
.upsell-eq-to { font-weight: 700; }
/* The "+ ৫০ টাকা" increment sits in the center column, above the price arrow. */
.upsell-eq-mid { font-size: 0.8125rem; font-weight: 700; color: var(--foreground); white-space: nowrap; }
.upsell-row-arrow {
  color: var(--border-strong);
  animation: upsell-arrow-nudge 1.4s ease-in-out infinite;
}
/* Discount-mode up-sells carry no "+X taka" equation; hide those cells. */
.upsell-overlay[data-mode="discount"] #upsell-eq-from,
.upsell-overlay[data-mode="discount"] #upsell-eq-mid,
.upsell-overlay[data-mode="discount"] #upsell-eq-to { display: none; }

.upsell-price-strike { font-size: 1rem; text-decoration: line-through; color: var(--tertiary); line-height: 1; }
/* Increment mode drops the strike (no "was" price); discount mode keeps it. */
.upsell-price-strike.no-strike { text-decoration: none; color: var(--muted); }
.upsell-price-final { font-weight: 700; line-height: 1; }

/* Left column = the CURRENT plan (১ মাস / ৳২৪৫): bigger + red, gently blinking
   so it reads as "what you'd settle for". Right column = the upgrade
   (২ মাস / ৳২৯৫): green, highlighted by colour only (no box). IDs beat the base
   classes above. */
#upsell-eq-from,
#upsell-orig { color: #dc2626; }
#upsell-orig { font-size: 1.5rem; font-weight: 700; }
#upsell-eq-to,
#upsell-final { color: #059669; }
#upsell-final { font-size: 1.5rem; }
@keyframes upsell-arrow-nudge {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(3px); }
}
/* One-off scale pop on the price card when the modal first opens. */
.upsell-price.appear {
  animation: upsell-price-card-pop 420ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes upsell-price-card-pop {
  0%   { transform: scale(0.92); opacity: 0; }
  60%  { transform: scale(1.03); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.upsell-accept {
  width: 100%;
  padding: 0.75rem 1rem;
  background: #0284c7;
  color: #ffffff;
  border-radius: 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
  transition: background 120ms;
}
.upsell-accept:hover { background: #0369a1; }
.upsell-stay {
  width: 100%;
  padding: 0.75rem 1rem;
  background: var(--surface);
  color: #e11d48;
  border: 1px solid #fda4af;
  border-radius: 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
  transition: background 120ms;
}
.upsell-stay:hover { background: #fff1f2; }

/* Loading spinner. */
.spinner {
  display: inline-block;
  width: 1.25rem;
  height: 1.25rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 720ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Review prompt (/v1/web/review) ─────────────────────────────────────── */
/* Steps toggle via the `hidden` attribute, but each step also carries
   `.stack-lg` (display:flex). `.stack-lg` and the UA `[hidden]{display:none}`
   have equal specificity, so the author rule would win and every step would
   render at once as one long scroll. Force `hidden` to win. */
#review-root [hidden] { display: none !important; }
.rating-stars {
  display: flex;
  justify-content: center;
  gap: 0.25rem;
}
.star {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 2.5rem;
  line-height: 1;
  padding: 0.125rem 0.25rem;
  color: var(--border-strong);
  transition: color 120ms ease, transform 120ms ease;
}
.star:hover { transform: scale(1.08); }
.star.is-on { color: #f6b100; }
.review-textarea {
  width: 100%;
  min-height: 6rem;
  resize: vertical;
  line-height: 1.6;
}
.btn-link-muted {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--tertiary);
  font-size: 0.8125rem;
  padding: 0.25rem 0.5rem;
}
.btn-link-muted:hover { color: var(--muted); }
