/* ==========================================================================
   MySubShare — design system
   --------------------------------------------------------------------------
   Loads after every component stylesheet. Everything here is a token or a
   refinement of an existing component; nothing new is invented that the
   markup doesn't already use.

   The palette is the product's own: signal orange (#fe6401) against deep
   navy (#040a30), with a separate green reserved exclusively for money that
   has actually landed. Colour is never decoration here — orange means "act",
   green means "credited", amber means "waiting on the bank".
   ========================================================================== */

:root {
  /* ---- brand ------------------------------------------------------------ */
  --ms-orange-50:  #fff3ea;
  --ms-orange-100: #ffe0cc;
  --ms-orange-300: #ff9a52;
  --ms-orange-500: #fe6401;   /* signature */
  --ms-orange-600: #e05500;
  --ms-orange-700: #b34400;

  --ms-ink-900: #040a30;      /* deep navy, the product's ground colour */
  --ms-ink-800: #0b1444;
  --ms-ink-700: #17205c;
  --ms-ink-600: #2b3574;

  /* ---- neutrals: cooled toward the navy, never pure grey ---------------- */
  --ms-n-0:   #ffffff;
  --ms-n-25:  #fbfcfe;
  --ms-n-50:  #f5f7fb;
  --ms-n-100: #edf0f7;
  --ms-n-200: #dfe4ef;
  --ms-n-300: #c6cede;
  --ms-n-400: #9aa4bd;
  --ms-n-500: #6f7a96;
  --ms-n-600: #515b76;
  --ms-n-700: #3a4358;
  --ms-n-800: #232a3d;

  /* ---- semantic: money and state ---------------------------------------- */
  --ms-credit:     #0e9f6e;   /* funds confirmed and in the wallet */
  --ms-credit-bg:  #e7f8f1;
  --ms-credit-700: #07784f;
  --ms-pending:    #b7791f;   /* submitted, waiting on the bank */
  --ms-pending-bg: #fdf6e3;
  --ms-danger:     #d92d20;
  --ms-danger-bg:  #fdeceb;
  --ms-info:       #2563eb;
  --ms-info-bg:    #eaf1fe;

  /* ---- type ------------------------------------------------------------- */
  --ms-font-display: 'Plus Jakarta Sans', 'DM Sans', 'Segoe UI', system-ui, sans-serif;
  --ms-font-body:    'Inter', 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --ms-font-mono:    'SF Mono', 'JetBrains Mono', Monaco, 'Courier New', monospace;

  --ms-text-xs:   0.75rem;
  --ms-text-sm:   0.8125rem;
  --ms-text-base: 0.9375rem;
  --ms-text-md:   1.0625rem;
  --ms-text-lg:   1.25rem;
  --ms-text-xl:   1.5rem;
  --ms-text-2xl:  1.9375rem;
  --ms-text-3xl:  2.5rem;

  /* ---- space: 4px base -------------------------------------------------- */
  --ms-1: 4px;  --ms-2: 8px;  --ms-3: 12px; --ms-4: 16px;
  --ms-5: 20px; --ms-6: 24px; --ms-8: 32px; --ms-10: 40px; --ms-12: 48px;

  /* ---- radii ------------------------------------------------------------ */
  --ms-r-sm: 8px; --ms-r-md: 12px; --ms-r-lg: 16px; --ms-r-xl: 22px;
  --ms-r-pill: 999px;

  /* ---- elevation: tinted with the navy, never neutral black ------------- */
  --ms-shadow-xs: 0 1px 2px rgba(4, 10, 48, .06);
  --ms-shadow-sm: 0 1px 2px rgba(4, 10, 48, .06), 0 2px 6px rgba(4, 10, 48, .05);
  --ms-shadow-md: 0 2px 4px rgba(4, 10, 48, .05), 0 8px 20px rgba(4, 10, 48, .08);
  --ms-shadow-lg: 0 4px 8px rgba(4, 10, 48, .05), 0 18px 44px rgba(4, 10, 48, .12);
  --ms-shadow-orange: 0 6px 18px rgba(254, 100, 1, .28);

  /* ---- motion ----------------------------------------------------------- */
  --ms-ease: cubic-bezier(.32, .72, .35, 1);
  --ms-fast: 130ms;
  --ms-mid:  220ms;
}

/* ==========================================================================
   1. Icon alignment
   The icon set is masked SVG at 1em, so it inherits colour and size from the
   text beside it. These rules stop it colliding with adjacent glyphs.
   ========================================================================== */

.tcsi { color: inherit; }

h1 > .tcsi, h2 > .tcsi, h3 > .tcsi, h4 > .tcsi {
  --tcsi-size: .92em;
  margin-inline-end: .38em;
  opacity: .85;
}

button > .tcsi, .button > .tcsi, a.button > .tcsi,
.btn-primary > .tcsi, .nav-btn > .tcsi {
  margin-inline-end: .45em;
  vertical-align: -.14em;
}

/* an icon on its own in a control is a graphic, not a prefix */
button > .tcsi:only-child,
.button > .tcsi:only-child { margin-inline-end: 0; --tcsi-size: 1.1em; }

/* status icons take the colour of the state they report */
.tcsi-check-circle, .tcsi-check { color: var(--ms-credit); }
.tcsi-close-circle, .tcsi-close, .tcsi-siren, .tcsi-stop { color: var(--ms-danger); }
.tcsi-alert { color: var(--ms-pending); }
.tcsi-hourglass, .tcsi-clock, .tcsi-alarm, .tcsi-timer { color: var(--ms-pending); }
.tcsi-info, .tcsi-help { color: var(--ms-info); }
.tcsi-bolt, .tcsi-spark, .tcsi-fire { color: var(--ms-orange-500); }

/* inherit again wherever the surrounding element already sets a colour */
button .tcsi, .button .tcsi, .btn-primary .tcsi,
.badge .tcsi, .pill .tcsi, [class*="status-"] .tcsi { color: inherit; }

/* ==========================================================================
   2. Typography
   One display face for headings, one body face for everything else. The
   existing sheets reach for four different families; this settles it.
   ========================================================================== */

.totp-wrapper, #totp-subscription-portal, .totp-credentials-wrapper,
.totp-portal, .totp-dashboard {
  font-family: var(--ms-font-body);
  font-size: var(--ms-text-base);
  line-height: 1.6;
  color: var(--ms-n-800);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-variant-numeric: tabular-nums;
}

.totp-wrapper h1, #totp-subscription-portal h1, .totp-credentials-wrapper h1,
.totp-wrapper h2, #totp-subscription-portal h2, .totp-credentials-wrapper h2,
.totp-wrapper h3, #totp-subscription-portal h3, .totp-credentials-wrapper h3 {
  font-family: var(--ms-font-display);
  color: var(--ms-ink-900);
  letter-spacing: -.021em;
  line-height: 1.2;
  text-wrap: balance;
}

.totp-wrapper h1, #totp-subscription-portal h1 { font-size: var(--ms-text-2xl); font-weight: 800; }
.totp-wrapper h2, #totp-subscription-portal h2 { font-size: var(--ms-text-xl);  font-weight: 750; }
.totp-wrapper h3, #totp-subscription-portal h3 { font-size: var(--ms-text-md);  font-weight: 700; }

/* an amount is data: monospaced figures so columns of naira line up */
.wallet-balance, .balance-amount, .payment-amount, .plan-price,
.txn-amount, .amount, [class*="-amount"] {
  font-family: var(--ms-font-display);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  font-weight: 750;
}

code, kbd, pre, .otp-code, .totp-code, [class*="code-display"] {
  font-family: var(--ms-font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}

/* ==========================================================================
   3. Controls
   ========================================================================== */

.totp-wrapper button, #totp-subscription-portal button,
.totp-credentials-wrapper button, .btn-primary, .nav-btn {
  font-family: var(--ms-font-body);
  font-weight: 650;
  letter-spacing: -.005em;
  border-radius: var(--ms-r-md);
  transition: background-color var(--ms-fast) var(--ms-ease),
              border-color var(--ms-fast) var(--ms-ease),
              box-shadow var(--ms-mid) var(--ms-ease),
              transform var(--ms-fast) var(--ms-ease);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  cursor: pointer;
}

.btn-primary {
  background: var(--ms-orange-500);
  border: 1px solid var(--ms-orange-600);
  color: var(--ms-n-0);
  padding: var(--ms-3) var(--ms-5);
  box-shadow: var(--ms-shadow-xs);
}
.btn-primary:hover:not(:disabled) {
  background: var(--ms-orange-600);
  box-shadow: var(--ms-shadow-orange);
  transform: translateY(-1px);
}
.btn-primary:active:not(:disabled) { transform: translateY(0); box-shadow: var(--ms-shadow-xs); }
.btn-primary:disabled { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }

/* every interactive element gets the same visible keyboard ring */
.totp-wrapper :is(button, a, input, select, textarea, [tabindex]):focus-visible,
#totp-subscription-portal :is(button, a, input, select, textarea, [tabindex]):focus-visible,
.totp-credentials-wrapper :is(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--ms-orange-500);
  outline-offset: 2px;
  border-radius: var(--ms-r-sm);
}

/* ==========================================================================
   4. Surfaces
   ========================================================================== */

.subscription-card, .service-card, .plan-card, .wallet-card,
.credential-card, .totp-card, .referral-card {
  background: var(--ms-n-0);
  border: 1px solid var(--ms-n-200);
  border-radius: var(--ms-r-lg);
  box-shadow: var(--ms-shadow-sm);
  transition: box-shadow var(--ms-mid) var(--ms-ease),
              transform var(--ms-mid) var(--ms-ease),
              border-color var(--ms-mid) var(--ms-ease);
}
.subscription-card:hover, .service-card:hover, .plan-card:hover {
  border-color: var(--ms-n-300);
  box-shadow: var(--ms-shadow-md);
  transform: translateY(-2px);
}

/* ==========================================================================
   5. Status
   One shape for state, coloured by meaning. Shape carries the reading for
   anyone who can't separate the hues.
   ========================================================================== */

.status-badge, .badge, .pill, [class*="status-"] {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  padding: .28em .72em;
  border-radius: var(--ms-r-pill);
  font-size: var(--ms-text-xs);
  font-weight: 650;
  letter-spacing: .012em;
  line-height: 1.5;
  border: 1px solid transparent;
  white-space: nowrap;
}
.status-active, .status-approved, .status-completed, .status-success {
  background: var(--ms-credit-bg); color: var(--ms-credit-700); border-color: #bfe9d8;
}
.status-pending, .status-processing, .status-review {
  background: var(--ms-pending-bg); color: #8a5a10; border-color: #f2e0b5;
}
.status-expired, .status-rejected, .status-failed, .status-error {
  background: var(--ms-danger-bg); color: #a91c14; border-color: #f6cdca;
}

/* a live check is the one place motion is earned: it means "we're looking" */
.status-pending .tcsi-hourglass,
.status-processing .tcsi-refresh { animation: ms-breathe 1.9s var(--ms-ease) infinite; }

@keyframes ms-breathe {
  0%, 100% { opacity: .45; }
  50%      { opacity: 1; }
}

/* ==========================================================================
   6. Forms
   ========================================================================== */

.totp-wrapper :is(input[type="text"], input[type="email"], input[type="tel"],
                  input[type="password"], input[type="number"], select, textarea),
#totp-subscription-portal :is(input[type="text"], input[type="email"], input[type="tel"],
                  input[type="password"], input[type="number"], select, textarea) {
  width: 100%;
  font-family: var(--ms-font-body);
  font-size: var(--ms-text-base);
  color: var(--ms-n-800);
  background: var(--ms-n-0);
  border: 1px solid var(--ms-n-300);
  border-radius: var(--ms-r-md);
  padding: var(--ms-3) var(--ms-4);
  transition: border-color var(--ms-fast) var(--ms-ease),
              box-shadow var(--ms-fast) var(--ms-ease);
  box-shadow: var(--ms-shadow-xs) inset;
}
.totp-wrapper :is(input, select, textarea):focus,
#totp-subscription-portal :is(input, select, textarea):focus {
  border-color: var(--ms-orange-500);
  box-shadow: 0 0 0 3px var(--ms-orange-50);
  outline: none;
}
.totp-wrapper ::placeholder, #totp-subscription-portal ::placeholder {
  color: var(--ms-n-400);
}

/* --- field scaffolding used by the registration form ---------------------- */
.ms-field { margin-bottom: var(--ms-4); }
.ms-field > label {
  display: flex;
  align-items: center;
  gap: var(--ms-2);
  font-size: var(--ms-text-sm);
  font-weight: 650;
  color: var(--ms-n-700);
  margin-bottom: var(--ms-2);
}
.ms-field .ms-hint {
  display: block;
  margin-top: var(--ms-2);
  font-size: var(--ms-text-xs);
  color: var(--ms-n-500);
  line-height: 1.5;
}

/* "Optional" is a promise, not an afterthought — it gets a real chip */
.ms-optional {
  font-size: var(--ms-text-xs);
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--ms-n-500);
  background: var(--ms-n-100);
  border: 1px solid var(--ms-n-200);
  border-radius: var(--ms-r-pill);
  padding: .12em .55em;
  margin-inline-start: auto;
}

.ms-split { display: grid; grid-template-columns: 1.35fr 1fr; gap: var(--ms-3); }
@media (max-width: 420px) { .ms-split { grid-template-columns: 1fr; } }

/* the birthday row: a gift you can decline, so it reads as an invitation */
.ms-birthday {
  background: linear-gradient(180deg, var(--ms-orange-50), var(--ms-n-0) 70%);
  border: 1px solid var(--ms-orange-100);
  border-radius: var(--ms-r-lg);
  padding: var(--ms-4);
}
.ms-birthday > label { color: var(--ms-ink-800); }
.ms-birthday .ms-hint { color: var(--ms-n-600); }
.ms-birthday .tcsi-cake { color: var(--ms-orange-500); }

/* ==========================================================================
   7. Signature — the credit ticket
   Everything in this product turns on one moment: a bank transfer clearing.
   That moment gets the only ornamented component in the system, borrowing
   from the paper teller slip the transfer replaced — a torn top edge, a
   perforated rule, and figures set like a printed receipt.
   ========================================================================== */

.ms-ticket {
  position: relative;
  background: var(--ms-n-0);
  border: 1px solid var(--ms-n-200);
  border-radius: var(--ms-r-md);
  padding: var(--ms-5) var(--ms-5) var(--ms-4);
  box-shadow: var(--ms-shadow-md);
  overflow: hidden;
}
/* torn edge, drawn rather than imaged so it scales and recolours */
.ms-ticket::before {
  content: '';
  position: absolute;
  inset-block-start: 0; inset-inline: 0;
  block-size: 4px;
  background:
    radial-gradient(circle at 4px 0, transparent 3.4px, var(--ms-orange-500) 3.5px) 0 0 / 8px 4px repeat-x;
}
.ms-ticket__amount {
  font-family: var(--ms-font-display);
  font-size: var(--ms-text-2xl);
  font-weight: 800;
  letter-spacing: -.03em;
  color: var(--ms-ink-900);
  font-variant-numeric: tabular-nums;
}
.ms-ticket__row {
  display: flex;
  justify-content: space-between;
  gap: var(--ms-4);
  padding-block: var(--ms-2);
  font-size: var(--ms-text-sm);
}
.ms-ticket__row dt { color: var(--ms-n-500); }
.ms-ticket__row dd { margin: 0; color: var(--ms-n-800); font-weight: 600; }
.ms-ticket__perf {
  border: 0;
  border-top: 1.5px dashed var(--ms-n-300);
  margin-block: var(--ms-3);
}
.ms-ticket--credited { border-color: #bfe9d8; }
.ms-ticket--credited::before {
  background: radial-gradient(circle at 4px 0, transparent 3.4px, var(--ms-credit) 3.5px) 0 0 / 8px 4px repeat-x;
}

/* ==========================================================================
   8. Empty and loading states — an empty screen should point somewhere
   ========================================================================== */

.ms-empty { text-align: center; padding: var(--ms-10) var(--ms-5); }
.ms-empty .tcsi { --tcsi-size: 40px; color: var(--ms-n-300); }
.ms-empty h3 { margin: var(--ms-4) 0 var(--ms-2); color: var(--ms-ink-900); }
.ms-empty p  { color: var(--ms-n-500); margin: 0 auto var(--ms-5); max-width: 42ch; }

.ms-skeleton {
  background: linear-gradient(90deg, var(--ms-n-100) 25%, var(--ms-n-50) 37%, var(--ms-n-100) 63%);
  background-size: 400% 100%;
  border-radius: var(--ms-r-sm);
  animation: ms-shimmer 1.3s ease-in-out infinite;
}
@keyframes ms-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ==========================================================================
   9. Quality floor
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .btn-primary:hover, .subscription-card:hover,
  .service-card:hover, .plan-card:hover { transform: none; }
}

@media (max-width: 640px) {
  :root { --ms-text-2xl: 1.625rem; --ms-text-3xl: 2rem; }
  .totp-wrapper, #totp-subscription-portal { font-size: var(--ms-text-base); }
  /* controls stay thumb-sized on small screens */
  .btn-primary, .nav-btn { min-block-size: 44px; }
}

@media print {
  .nav-btn, .btn-primary, .totp-chatbot-widget { display: none !important; }
  .ms-ticket { box-shadow: none; border: 1px solid #000; }
}

/* ==========================================================================
   10. Desktop layout recovery
   --------------------------------------------------------------------------
   The v12.1.2 "payment instructions redesign" block in subscription-portal.css
   is a phone layout, but it sits outside any media query, so it applies at
   every width: the portal is pinned to 640px and the tab bar is forced into a
   horizontally-scrolling carousel. On a desktop screen that leaves most of the
   viewport empty and clips the tabs.

   These rules re-scope that phone layout to phone widths. Everything below is
   additive and breakpoint-guarded, so small screens are untouched.
   ========================================================================== */

@media (min-width: 900px) {
  .totp-subscription-portal {
    max-width: 1160px !important;
    margin: 28px auto !important;
    padding: 0 24px !important;
  }

  /* the tab bar can simply wrap when there's room; a scroll carousel on a
     wide screen only hides controls the user can't tell are there */
  .portal-navigation {
    flex-wrap: wrap !important;
    overflow: visible !important;
    scroll-snap-type: none !important;
    gap: 10px !important;
    padding: 4px 0 12px !important;
  }

  /* subscription cards stack one-per-row by default; at this width that's a
     long scroll past a lot of empty space */
  .subscriptions-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
    gap: 20px;
    align-items: start;
  }

  /* header reads as a banner rather than a tall stacked block */
  .portal-header { padding: 26px 32px !important; }

  .whatsapp-channel-banner { margin-bottom: 18px !important; }

  /* these inner wrappers were sized for a 640px shell */
  .ks-pay-wrap { max-width: 720px !important; }
  .plans-hero  { padding-inline: 32px !important; }
}

@media (min-width: 1280px) {
  .totp-subscription-portal { max-width: 1280px !important; }
  .subscriptions-list { grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); }
}

/* Between the phone layout and the desktop one, let the shell breathe rather
   than staying locked at 640px on tablets and small laptops. */
@media (min-width: 641px) and (max-width: 899px) {
  .totp-subscription-portal {
    max-width: 92vw !important;
    padding: 0 18px !important;
  }
  .portal-navigation { flex-wrap: wrap !important; overflow: visible !important; }
}

/* ==========================================================================
   11. Dark theme completion
   --------------------------------------------------------------------------
   v13.5.1 ("Soft Vault") turned the portal shell dark:
       #totp-subscription-portal { background:#0a0a0f; color:#f5f5f8 }
   but `.portal-content` kept `background: white` from the original light
   theme at line 108. The result is #f5f5f8 text on a white panel — the
   "My Subscriptions" heading and everything beside it were invisible.

   Letting the panel go transparent hands the surface back to the dark shell,
   which is what the rest of the theme already assumes.
   ========================================================================== */

/* The shimmer placeholder is cleared once JS injects content with
       #totp-subscription-portal:not(:empty) { background: none !important }
   That selector (id + pseudo-class) outranks the plain id selector the Soft
   Vault theme uses, so the dark surface was being wiped on every populated
   portal while the light text colour survived — light text on a light page.
   Re-assert the surface at the same specificity, keeping the shimmer-off
   behaviour the original rule was written for. */
#totp-subscription-portal:not(:empty) {
  background: #0a0a0f !important;
  animation: none !important;
}

#totp-subscription-portal .portal-content {
  background: transparent !important;
  box-shadow: none !important;
  padding: 4px 0 0 !important;
}

/* Headings and body copy inside the dark shell, stated explicitly so they
   don't depend on inheritance surviving a future edit. */
#totp-subscription-portal .portal-content > h3,
#totp-subscription-portal .portal-content > h2 {
  color: #f5f5f8 !important;
}

/* The theme sets a muted grey for <p> across the whole portal, but the header
   sits on saturated orange, where that grey drops to ~2:1. Text on a coloured
   banner takes white regardless of the surrounding theme. */
#totp-subscription-portal .portal-header h2 { color: #fff !important; }
#totp-subscription-portal .portal-header p  { color: rgba(255, 255, 255, .92) !important; }

/* Any panel still painted white by an older rule needs dark text, or it
   inherits the shell's light colour and disappears the same way. */
#totp-subscription-portal .login-form,
#totp-subscription-portal .forgot-form,
#totp-subscription-portal .register-form {
  color: var(--ms-n-800);
}
#totp-subscription-portal :is(.login-form, .forgot-form, .register-form) :is(h3, h4, p, label) {
  color: var(--ms-n-800);
}

/* Nothing in the portal should be able to push the page sideways.
   The shell carries `padding: 0 14px !important` while inheriting content-box
   sizing, so its 28px of padding was added *outside* its full-width box — a
   28px horizontal scroll on every phone. Border-box folds it back in. */
#totp-subscription-portal,
.totp-subscription-portal { box-sizing: border-box; }

.totp-subscription-portal,
.totp-subscription-portal * { min-width: 0; }
