/* ─── Fawatery Marketing & Public Design System ────────────────────────────
   World-Class Fintech & B2C SaaS Visual Engine (Apple / Linear Aesthetic)
   - Deep Emerald / Sage Green Accents & High-Trust Slate Foundations
   - Bento Grid Responsive Layout System
   - Outcome-First UX & Friction-Killer Visual Micro-Artifacts
   - 100% Logical CSS Properties (RTL Arabic by Default / LTR English)
   ────────────────────────────────────────────────────────────────────────── */

* { box-sizing: border-box; }

html {
  --m-nav-h: 69px;
  scroll-padding-top: calc(var(--m-nav-h) + var(--space-3));
  scroll-behavior: smooth;
}

html, body {
  margin: 0;
  padding: 0;
  overflow-x: clip;
}

[dir="ltr"] body { font-family: "Outfit", "Cairo", sans-serif; }
body {
  font-family: var(--font-app);
  background: var(--gradient-page);
  color: var(--color-text);
  line-height: 1.7;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.wrap {
  max-width: 720px;
  margin: 0 auto;
  padding-inline: var(--space-5);
}

.wrap-wide {
  max-width: 1080px;
  margin: 0 auto;
  padding-inline: var(--space-5);
}

a {
  color: var(--color-brand);
  text-decoration: none;
  transition: color var(--transition-fast);
}

a:hover {
  color: var(--color-brand-hover);
}

/* ─── Navigation Bar ────────────────────────────────────────────────────── */

.m-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--color-surface-nav);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--color-border);
  padding-inline: var(--space-5);
  padding-block: var(--space-3);
  /* The marketing pages never loaded style.css's body inset, so this sticky
     bar sat under the notch on an installed iPhone rather than below it. Sum,
     not max: the bar keeps its own 12px above the inset. */
  padding-top: calc(var(--space-3) + env(safe-area-inset-top));
  transition: background var(--transition-base), border-color var(--transition-base);
}

.m-nav-inner {
  max-width: 1080px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Wraps rather than pushing a link off the screen edge: at the largest
     system font scale on the narrowest phone the brand and the two links stop
     fitting one row, and a nav bar is the one place a user cannot scroll to
     recover what fell off. */
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}

.m-brand {
  min-height: var(--control-height);
  font-weight: 700;
  font-size: 1.18rem;
  color: var(--color-text);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}

[dir="ltr"] .m-brand {
  letter-spacing: -0.01em;
}

.m-brand-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-sm);
  /* The mark is sky, not emerald: --color-brand is sky, the Android widget's
     stamp is sky, and green already means "a positive number" on the pricing
     pills and the money-found copy. One hue, one meaning. */
  background: var(--color-brand-chip);
  border: 1px solid var(--color-sky-600);
  /* sky-400 raw, NOT --color-brand: the light theme resolves that to
     #0369a1, which is dark ink on this dark plate (1.99:1). The chip is
     a dark ground in BOTH themes, so it takes the bright token in both —
     exactly what --color-accent-chip does for the emerald chips. */
  color: var(--color-sky-400);
  box-shadow: var(--glow-brand);
}

.m-nav-links {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.m-nav-link {
  color: var(--color-text-muted);
  text-decoration: none;
  font-size: var(--font-size-md);
  font-weight: 600;
  padding: 0.5rem 0.85rem;
  border-radius: var(--radius-sm);
  min-height: var(--control-height);
  display: inline-flex;
  align-items: center;
  transition: all var(--transition-fast);
}

.m-nav-link:hover {
  color: var(--color-text);
  background: var(--color-surface-hover);
}

.m-lang-switch {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-height);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  padding: 0.35rem 0.75rem;
  color: var(--color-text-muted);
  background: var(--color-surface-subtle);
}

.m-lang-switch:hover {
  border-color: var(--color-brand-border);
  color: var(--color-brand);
}

/* The switch is set in the face of the language it leads TO — «English» in
   Outfit on the Arabic page, «العربية» in Cairo on the English one — so it
   reads as "the other language" before it is read at all. Both faces are on
   every page already (the app stack names both), so this costs no request.
   Keyed on the lang attribute the anchors already carry for hreflang. */
.m-nav [lang="en"] { font-family: "Outfit", "Cairo", sans-serif; }
.m-nav [lang="ar"] { font-family: "Cairo", "Outfit", sans-serif; }

.m-nav-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding-inline: 1.15rem;
  border-radius: var(--radius-md);
  font-size: var(--font-size-md);
  font-weight: 700;
  color: var(--color-on-brand);
  background: var(--color-brand);
  text-decoration: none;
  white-space: nowrap;
  box-shadow: var(--glow-brand);
  transition: all var(--transition-base);
}

.m-nav-cta:hover {
  background: var(--color-brand-hover);
  color: var(--color-on-strong);
  box-shadow: var(--glow-brand-strong);
  transform: translateY(-1px);
}

/* ─── Hero Section ──────────────────────────────────────────────────────── */

.m-hero-grid {
  display: grid;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: center;
  padding-block: clamp(1.25rem, 6vw, 4rem) 1.5rem;
}

@media (min-width: 880px) {
  .m-hero-grid {
    grid-template-columns: 1.1fr 0.9fr;
  }
}

.m-hero-copy {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  min-width: 0;
}

.m-hero-copy h1 {
  margin: 0;
  font-size: clamp(2.1rem, 6vw, 3.2rem);
  font-weight: 900;
  line-height: 1.2;
  text-wrap: balance;
}

[dir="ltr"] .m-hero-copy h1 {
  font-weight: 700;
  letter-spacing: -0.02em;
}

.m-hero-copy .lede {
  margin: 0;
  color: var(--color-text-muted);
  font-size: clamp(1rem, 3vw, 1.12rem);
  line-height: 1.7;
  text-wrap: pretty;
  max-width: 52ch;
}

.m-eyebrow {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  /* It WRAPS. The nowrap this carried was bought with a narrow-viewport font
     size, and that trade only holds while the font size is ours to choose:
     Android scales every size by the system font setting while the viewport
     stays put, so the ~48-character English string ran off the page — 355px
     of badge on a 280px screen at 1.3x, dragging the hero grid with it. The
     "a wrapped badge loses its left edge" worry is about display:inline; this
     is an inline-flex box, so its pill background wraps around both lines and
     it still reads as one object. */
  white-space: normal;
  text-wrap: balance;
  gap: 0.4rem;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  padding: 0.45rem 0.95rem;
  border-radius: var(--radius-pill);
  color: var(--color-sky-400);
  background: var(--color-accent-chip);
  border: 1px solid var(--color-accent-chip-border);
  box-shadow: var(--glow-accent);
}

[dir="ltr"] .m-eyebrow {
  letter-spacing: 0.06em;
}

.m-hero-solo {
  padding-block: clamp(1.5rem, 6vw, 3.5rem) 0;
  animation: fw-enter-rise 320ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

/* ─── CTA Row & Button System ───────────────────────────────────────────── */

.m-cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem;
  margin-block: var(--space-3) var(--space-1);
}

.btn.m-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding-inline: var(--space-8);
  border-radius: var(--radius-lg);
  font-size: 1.05rem;
  font-weight: 700;
  box-shadow: var(--glow-brand);
  transition: all var(--transition-base);
}

.btn.m-cta:hover {
  transform: translateY(-2px);
  box-shadow: var(--glow-brand-strong);
}

.m-trust {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  line-height: 1.6;
  margin: 0;
}

/* ─── Hero Quick-Action Preview Pills ───────────────────────────────────── */

.m-hero-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: var(--space-1);
}

.m-pill-action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.45rem 0.85rem;
  border-radius: var(--radius-pill);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  box-shadow: var(--shadow-sm);
}

.m-pill-action strong {
  color: var(--color-text);
  font-weight: 700;
}

.m-pill-dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--color-sky-400);
  box-shadow: 0 0 8px var(--color-sky-400);
}

/* ─── Master Visual Card: The Thermal Receipt & Safe Metric ─────────────── */

.m-hero-visual {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

/* The offer page drops this card straight into a prose section, where the
   wrap is wider than the card's 500px cap — so unlike the landing's hero
   grid (whose column IS the card's width, making the centring above a
   no-op) the alignment is visible here, and a centred card under flush-start
   text is the only object on the page that does not share its start edge.
   The margin restores what the inline style this class replaced carried. */
.m-section > .m-hero-visual {
  align-items: flex-start;
  margin-block-start: var(--space-6);
  /* THE BADGE IS ABSOLUTE AGAINST THIS BOX, so the box has to be the card.
     `.m-hero-visual` is a flex column that fills its section — 680px at 1280px
     — while `.insight-hero` inside it caps at 500px, and the badge's
     `inset-inline-end: 16px` therefore anchored 180px clear of the card it
     labels, floating in the margin beside it. It is invisible on a phone,
     where the two boxes are the same width, and it is the first thing you see
     on a desktop. Capping the container at the card's own width makes the two
     coincide at every width, and `margin-inline-end: auto` keeps it on the
     text's start edge rather than centring it (which is what this rule was
     originally written to fix). */
  max-width: 500px;
  margin-inline-end: auto;
}

.m-hero-visual-badge {
  position: absolute;
  top: -14px;
  inset-inline-end: 16px;
  z-index: 10;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.8rem;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: 700;
  color: var(--color-sky-400);
  background: var(--color-badge-chip);
  border: 1px solid var(--color-sky-600);
  box-shadow: var(--shadow-md);
}

/* ─── Authentic In-App Insight Hero Card (Inlined, Zero-Dependency) ──────
   D5: The embedded insight hero card MUST stay dark in both themes. Its
   hex literals and rgba values are deliberately NOT tokenised so that it
   acts as an authentic product showroom floating on the page ground.
   Do not replace these hexes with semantic tokens. */

.insight-hero {
  --hero-accent: var(--color-emerald-400);
  /* D5: the card is immune to its surroundings, and that has to include the
     INHERITED colour. Every run inside sets its own today, so a light page
     showed nothing wrong — but one span added later without a colour would
     inherit --color-text and go slate-900 on slate-900, invisible. */
  color: #cbd5e1;
  position: relative;
  background: linear-gradient(145deg, #1e293b 0%, #0f172a 100%);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-card);
  padding: 1.25rem 1.4rem;
  margin-bottom: 0;
  width: 100%;
  max-width: 500px;
  box-shadow: 0 20px 50px -10px rgba(2, 6, 23, 0.85), 0 0 30px -10px rgba(16, 185, 129, 0.15);
  overflow: hidden;
  text-align: start;
}

.m-hero-visual .insight-hero {
  background: linear-gradient(145deg, #1e293b 0%, #0f172a 100%);
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 24px 50px -12px rgba(2, 6, 23, 0.9), 0 0 36px -8px rgba(16, 185, 129, 0.2);
}

/* The app maps this state onto the shared token (style.css: `hero-state-green
   { --hero-accent: var(--green) }`). The whole reason the landing renders the
   real card is fidelity, so a hex here quietly makes the marketing screenshot
   a different green than the product it is a screenshot of — and, since the
   meter is tinted from --green, two different greens inside one card. */
.insight-hero.hero-state-green {
  --hero-accent: var(--color-emerald-400);
}

.insight-hero::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 4px;
  background: var(--hero-accent);
}

.insight-hero-glance {
  font-size: 0.72rem;
  font-weight: 700;
  color: #8899a6;
  opacity: 0.9;
  margin-bottom: 0.55rem;
}

[dir="ltr"] .insight-hero-glance {
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.insight-hero-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.8rem;
}

.insight-hero .ih-value {
  font-size: clamp(1.75rem, 5vw, 2.25rem);
  font-weight: 900;
  line-height: 1.15;
  color: #ffffff;
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.35rem;
}

[dir="ltr"] .insight-hero .ih-value {
  letter-spacing: -0.02em;
}

[dir="rtl"] .insight-hero .ih-value {
  line-height: 1.2;
}

.insight-hero .hero-week-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.3rem 0.8rem;
  font-size: 0.84rem;
  color: #8899a6;
  margin-top: 0.35rem;
  font-variant-numeric: tabular-nums;
}

.insight-hero .hero-week-meta span:first-child {
  color: #cbd5e1;
}

.insight-hero-budget {
  margin-top: var(--space-4);
  padding-top: 0.9rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.insight-hero .ih-brow {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.88rem;
  color: #cbd5e1;
  margin-bottom: 0.45rem;
  font-variant-numeric: tabular-nums;
}

.insight-hero .ih-brow-end {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.insight-hero .hero-budget-pct {
  color: var(--hero-accent);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-size: 0.92rem;
}

.insight-hero .budget-edit-affordance {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 0.78rem;
  font-weight: 700;
  color: #8899a6;
}

.ins-meter {
  height: 8px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.09);
  overflow: hidden;
  margin-bottom: var(--space-3);
}

.ins-meter > span {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--hero-accent);
}

.insight-hero .hero-proj {
  font-size: 0.84rem;
  line-height: 1.5;
  margin-top: var(--space-2);
}

.insight-hero .hero-verdict {
  color: var(--hero-accent);
  font-weight: 700;
  font-size: 0.92rem;
  line-height: 1.4;
  margin-bottom: 0.2rem;
  font-variant-numeric: tabular-nums;
}

.insight-hero .hero-proj-note {
  color: #8899a6;
  font-size: 0.8rem;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}

.insight-hero .hero-context {
  margin-top: 0.9rem;
  padding-top: 0.85rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  font-size: 0.84rem;
  color: #8899a6;
}

.insight-hero .hero-sofar {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem;
  font-size: 0.88rem;
  color: #cbd5e1;
}

.insight-hero .hero-sofar-val {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #ffffff;
  font-size: 0.95rem;
}

.insight-hero .hero-trend,
.insight-hero .hero-bills,
.insight-hero .hero-moved,
.insight-hero .hero-forecast {
  font-size: 0.82rem;
  color: #8899a6;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
}

.m-receipt {
  position: relative;
  background: var(--color-receipt);
  padding: 1.6rem 1.25rem 1.75rem;
  width: 100%;
  max-width: 420px;
  filter: drop-shadow(var(--shadow-receipt));
  /* So the total below can be sized against the slip rather than the window:
     a figure is one unbreakable run and vw cannot see a system font scale. */
  container-type: inline-size;
}

.m-receipt {
  --tooth: 11px;
  --tooth-h: 7px;
  -webkit-mask:
    radial-gradient(circle at 50% 0, transparent 0 5px, #000 5.5px)
      repeat-x top / var(--tooth) var(--tooth-h),
    radial-gradient(circle at 50% 100%, transparent 0 5px, #000 5.5px)
      repeat-x bottom / var(--tooth) var(--tooth-h),
    linear-gradient(#000 0 0) no-repeat 0 var(--tooth-h)
      / 100% calc(100% - var(--tooth-h) * 2);
  mask:
    radial-gradient(circle at 50% 0, transparent 0 5px, #000 5.5px)
      repeat-x top / var(--tooth) var(--tooth-h),
    radial-gradient(circle at 50% 100%, transparent 0 5px, #000 5.5px)
      repeat-x bottom / var(--tooth) var(--tooth-h),
    linear-gradient(#000 0 0) no-repeat 0 var(--tooth-h)
      / 100% calc(100% - var(--tooth-h) * 2);
}

.m-receipt-head {
  text-align: center;
  padding-block-end: 0.9rem;
}

.m-receipt-brand {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink);
}

[dir="ltr"] .m-receipt-brand {
  letter-spacing: 0.32em;
  text-transform: uppercase;
}

.m-receipt-meta {
  display: block;
  margin-block-start: 0.3rem;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.m-receipt-perf {
  border: 0;
  border-top: 1px dashed var(--color-rule);
  margin-block: 0.85rem;
}

.m-receipt-rule {
  border: 0;
  border-top: 1px solid var(--color-rule);
  margin-block: 0.85rem;
}

.m-receipt-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: 0.32rem;
  font-size: var(--font-size-md);
  color: var(--color-text-muted);
}

.m-receipt-line span:first-child { min-width: 0; }

.m-receipt-fig {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  color: var(--color-ink);
  font-variant-numeric: tabular-nums;
  direction: ltr;
  unicode-bidi: isolate;
}

.m-receipt-line-sub { font-size: var(--font-size-xs); }

.m-receipt-total {
  padding-block: 0.3rem 0.8rem;
}

.m-receipt-total-label {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-accent-on-page);
}

.m-receipt-total-fig {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  margin-block-start: 0.15rem;
  font-family: var(--font-mono);
  /* min(...) against the slip's own width: «٣٥٬٠٠٠» at the clamp's 2.2rem
     floor is 200px inside a 186px slip once a 1.3x system scale multiplies
     it, and a monospace figure has nowhere to break. */
  font-size: min(clamp(2.2rem, 11vw, 2.9rem), 20cqi);
  font-weight: 700;
  line-height: 1.05;
  color: var(--color-stamp);
  font-variant-numeric: tabular-nums;
  unicode-bidi: isolate;
}

.m-receipt-cur {
  font-family: var(--font-app);
  font-size: 0.95rem;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
}

.m-receipt-foot {
  margin-block-start: var(--space-3);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font-variant-numeric: tabular-nums;
}

.m-stamp {
  align-self: flex-start;
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--color-brand-border);
  border-radius: var(--radius-xs);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-stamp);
  background: var(--color-brand-soft);
}

/* ─── Progress Meter ────────────────────────────────────────────────────── */

.m-meter {
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--color-accent-chip);
  overflow: hidden;
}

.m-meter-fill {
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--color-sky-400);
  box-shadow: var(--glow-accent);
  animation: fillMeter 900ms cubic-bezier(0.22, 0.61, 0.36, 1) 250ms both;
  transform-origin: left;
}

[dir="rtl"] .m-meter-fill {
  transform-origin: right;
}

@keyframes fillMeter { from { transform: scaleX(0); } }

/* ─── Ambient Spotlight ─────────────────────────────────────────────────── */

/* A blurred pool of the brand hue behind the hero, and only there: an ambient
   light everywhere is an ambient light nowhere, and emphasis is contrast.

   It is a radial-gradient rather than a blurred element, deliberately.
   `filter: blur()` promotes what it touches to its own compositing layer, and
   038 took exactly one such layer OFF every button in the app because this
   market runs low-end Android; re-adding one here to draw something a gradient
   paints for free would undo that for nothing. A gradient also needs no size
   maths — the box is positioned by logical insets, so it leans toward the
   start edge in both directions with no RTL mirror to keep in step.

   The negative insets push past the wrap on a narrow viewport; `overflow-x:
   clip` on `html` (declared at the top of this file, for the full-bleed band's
   own vw measurement) already absorbs that. */
.m-hero-grid,
.m-hero-solo {
  position: relative;
}

.m-hero-grid::before,
.m-hero-solo::before {
  content: '';
  position: absolute;
  z-index: -1;
  pointer-events: none;
  inset-block: -22% 4%;
  inset-inline: -18% 22%;
  background: radial-gradient(ellipse at 50% 45%, var(--glow-ambient) 0%, transparent 65%);
}

/* ─── Full-Bleed Section Bands ──────────────────────────────────────────── */

.m-band {
  position: relative;
  padding-block: clamp(1.75rem, 8vw, 4.5rem);
  margin-block: clamp(1.15rem, 6vw, 3.75rem);
}

.m-band::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline: calc(50% - 50vw);
  background: var(--color-surface-band);
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  
}

.m-band > * { position: relative; }

.m-band h2 {
  font-size: clamp(1.4rem, 5vw, 1.95rem);
  font-weight: 700;
  line-height: 1.3;
  margin: 0 0 0.85rem;
}

.m-band p {
  color: var(--color-text-muted);
  font-size: 1.02rem;
  line-height: 1.8;
  max-width: 760px;
  margin: 0 0 var(--space-5);
}

/* ─── Micro-Leaks Chips Cloud ───────────────────────────────────────────── */

.m-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  padding-block: var(--space-2) var(--space-4);
}

.m-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.45rem;
  padding: 0.5rem 0.9rem;
  border-radius: var(--radius-pill);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  white-space: nowrap;
  transition: all var(--transition-fast);
}

.m-chip:hover {
  border-color: var(--color-danger-border);
  background: var(--color-danger-soft);
  color: var(--color-text);
  transform: scale(1.03);
}

.m-chip b {
  color: var(--color-text);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  unicode-bidi: isolate;
}

.m-chip-total {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-5);
  padding: 1.1rem 1.35rem;
  border-radius: var(--radius-lg);
  background: var(--color-surface-input);
  border: 1px solid var(--color-border-strong);
  font-variant-numeric: tabular-nums;
  max-width: 780px;
  box-shadow: var(--shadow-md);
}

.m-chip-total span:first-child {
  font-size: var(--font-size-md);
  color: var(--color-text-muted);
  font-weight: 500;
}

.m-chip-total span:last-child {
  font-size: 1.45rem;
  font-weight: 700;
  color: var(--color-danger);
  unicode-bidi: isolate;
}

/* ─── Bento Grid Architecture ───────────────────────────────────────────── */

.m-bento-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  margin-block: var(--space-8);
}

@media (min-width: 768px) {
  .m-bento-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .m-bento-span-2 {
    grid-column: span 2;
  }
}

.m-bento-card {
  position: relative;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  padding: clamp(1.4rem, 4vw, 1.8rem);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-5);
  overflow: hidden;
  transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.m-bento-card:hover {
  border-color: var(--color-sky-600);
  box-shadow: var(--glow-accent);
  transform: translateY(-2px);
}

.m-bento-card::before {
  content: '';
  position: absolute;
  top: 0;
  inset-inline-start: 0;
  inset-inline-end: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--color-sky-600), transparent);
  opacity: 0;
  transition: opacity var(--transition-base);
}

.m-bento-card:hover::before {
  opacity: 1;
}

.m-bento-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.m-bento-tag {
  align-self: flex-start;
  font-size: var(--font-size-xs);
  font-weight: 700;
  color: var(--color-sky-400);
  background: var(--color-accent-chip);
  border: 1px solid var(--color-accent-chip-border);
  padding: 0.25rem 0.65rem;
  border-radius: var(--radius-pill);
}

[dir="ltr"] .m-bento-tag {
  letter-spacing: 0.08em;
}

.m-bento-card h3 {
  margin: 0;
  font-size: clamp(1.15rem, 3.2vw, 1.35rem);
  font-weight: 700;
  line-height: 1.35;
  color: var(--color-text);
}

.m-bento-card p {
  margin: 0;
  font-size: 0.95rem;
  color: var(--color-text-muted);
  line-height: 1.7;
}

.m-bento-preview {
  margin-top: auto;
}

/* ─── Capability Rows & Slip Components ─────────────────────────────────── */

.m-rows {
  display: flex;
  flex-direction: column;
}

.m-row {
  padding-block: var(--space-6);
  border-top: 1px solid var(--color-border);
}

.m-row:first-child { border-top: 0; }

.m-row-label {
  display: inline-block;
  margin-block-end: 0.45rem;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-accent-on-page);
}

[dir="ltr"] .m-row-label {
  letter-spacing: 0.06em;
}

[dir="ltr"] .m-row-label {
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.m-row h3 {
  margin: 0 0 var(--space-2);
  font-size: 1.18rem;
  font-weight: var(--font-weight-bold);
  line-height: 1.4;
}

.m-row p {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.98rem;
  line-height: 1.75;
}

.m-slip {
  margin-block-start: var(--space-4);
  padding: 1rem 1.15rem;
  background: var(--color-receipt);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  max-width: 420px;
  box-shadow: var(--shadow-md);
}

.m-slip-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.2rem 0.9rem;
  font-size: var(--font-size-md);
  color: var(--color-text-muted);
}

.m-slip-fig {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  color: var(--color-ink);
  font-variant-numeric: tabular-nums;
  unicode-bidi: isolate;
  direction: ltr;
}

.m-slip-total {
  color: var(--color-ink);
  font-weight: var(--font-weight-bold);
}

.m-slip-rule {
  height: 1px;
  background: var(--color-rule);
  margin-block: 0.2rem;
}

.m-slip-arrow {
  color: var(--color-accent-on-page);
  text-align: center;
  font-size: 1.15rem;
  line-height: 1;
  margin-block: 0.2rem;
}

/* ─── Voice Waveform Animation ──────────────────────────────────────────── */

.m-wave {
  display: inline-flex;
  align-items: flex-end;
  gap: 3.5px;
  height: 20px;
}

.m-wave i {
  display: block;
  width: 3.5px;
  height: 19px;
  border-radius: var(--radius-pill);
  background: var(--color-sky-400);
  animation: soundWave 900ms ease-in-out infinite;
  transform-origin: bottom;
  transform: scaleY(0.368);
}

.m-wave i:nth-child(2) { animation-delay: 150ms; }
.m-wave i:nth-child(3) { animation-delay: 300ms; }

@keyframes soundWave {
  0%, 100% { transform: scaleY(0.368); }
  50% { transform: scaleY(1); }
}

/* ─── Feature & Content Sections ────────────────────────────────────────── */

/* VERTICAL RHYTHM IS MOBILE-FIRST NOW, and the clamp floors were the bug.
   Every one of these was `clamp(<a desktop figure>, N vw, <a bigger desktop
   figure>)`, and at 390px the vw term lands BELOW the floor — 8vw is 31px
   against a 48px minimum — so the floor governs and the fluid step is inert on
   the one viewport almost every reader arrives on. A phone was therefore
   paying desktop air between every block: 160px of it around each band, on a
   page whose whole content budget is about 1,400px.

   Lowering the floor hands the vw term back the phone range and changes
   nothing at or above ~600px, where the same expressions already resolved to
   the same numbers. Measured on /expense-tracker-egypt at 390px, together with
   the FAQ card below: 4,209px -> 4,040px. Less than the arithmetic suggests,
   and the reason is worth knowing before anyone tries to buy more here —
   adjacent vertical margins COLLAPSE, so a block's top margin and its
   neighbour's bottom margin are already one gap, and halving both only ever
   saves that gap once. The air between sections is close to spent; what is
   left on these pages is in the blocks themselves. */
.m-section {
  margin-block: clamp(1.15rem, 6vw, 3.5rem);
}

.m-section h2 {
  font-size: clamp(1.35rem, 4.5vw, 1.85rem);
  margin: 0 0 0.85rem;
  font-weight: 700;
  line-height: 1.3;
}

.m-section p {
  color: var(--color-text-muted);
  font-size: var(--font-size-base);
  line-height: 1.8;
  margin: 0 0 1.15rem;
}

/* TWO UP ON THE PHONE, and the old rule had it exactly backwards: one column
   below 640px and two above, so the viewport almost every reader arrives on
   got the tallest layout the component can produce. Four cards stacked full
   width measure 794px — nearly a whole phone screen to say four short things —
   against 460px two-up, and a card is a title and one sentence, which is
   precisely the content that does not need the width.

   Below 380px it goes back to one column: a 170px track is narrower than the
   longest unbreakable word in either script, and a card that cannot hold its
   own heading is worse than a tall one. */
.m-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  margin-block: var(--space-6);
}

@media (max-width: 379px) {
  .m-cards { grid-template-columns: minmax(0, 1fr); }
}

@media (min-width: 640px) {
  .m-cards { gap: var(--space-4); margin-block: var(--space-8); }
}

.m-card {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  /* Tighter on the phone, where the padding is a share of a 180px track
     rather than of a 360px one, and the 24px the full rule spends on each
     side is 13% of the card. */
  padding: 0.95rem 0.9rem;
  box-shadow: var(--shadow-md);
  transition: all var(--transition-base);
}

@media (min-width: 640px) {
  .m-card { padding: 1.3rem 1.4rem; }
}

.m-card:hover {
  border-color: var(--color-sky-600);
  box-shadow: var(--shadow-lg);
  transform: translateY(-2px);
}

.m-card .m-icon {
  font-size: 1.35rem;
  margin-bottom: 0.35rem;
  display: block;
  line-height: 1;
}

.m-card h3 {
  font-size: 0.95rem;
  margin: 0 0 0.3rem;
  font-weight: 700;
  line-height: 1.35;
}

.m-card p {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.84rem;
  /* 1.65 is a reading measure for a full-width paragraph. In a 180px track the
     same sentence is four or five short lines, where that leading reads as gaps
     rather than as rhythm and costs 30px a card. */
  line-height: 1.5;
}

@media (min-width: 640px) {
  .m-card .m-icon { font-size: 1.8rem; margin-bottom: 0.6rem; }
  .m-card h3 { font-size: 1.05rem; margin-bottom: 0.45rem; }
  .m-card p { font-size: 0.92rem; line-height: 1.65; }
}

/* ─── Plans & Pricing Table (CRO Optimized) ─────────────────────────────── */

/* minmax(0, 1fr), never a bare 1fr: a grid item's automatic minimum size is
   min-content, so three `1fr` tracks size to the widest unbreakable thing in
   any card rather than to a third of the row each. The CTA carried
   white-space: nowrap, which made each card's min-content the full width of
   "Start 30 Days Free" — so the pricing block outgrew the page at 280px, at
   320px in English, and at any phone width under an Android system font
   scale, pushing a whole card off the screen edge (measured 513px of grid in
   a 390px viewport at 1.3x). Same defect the Overview's chart grid had. */
.m-plans {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.1rem;
  margin-block: var(--space-8);
}

/* Stacked, source order buries the recommendation: the reader meets the
   monthly plan — the worst per-month value — first, and has to scroll past
   two cards to reach the one the page recommends. Three across reads
   correctly as a price ladder, so this reorders ONLY while the grid is a
   single column, and the desktop order is untouched.

   It was written at 719px on that reasoning while `.m-plans` stayed
   `repeat(3, …)` at every width — so the condition the comment describes was
   never true and the rule fired on the three-across layout instead, putting
   the yearly card at the head of the row between 561 and 719px and breaking
   the very ladder it defends. The grid genuinely collapses at 560px now
   (below), so the two numbers are one number. */
@media (max-width: 560px) {
  .m-plan-featured {
    order: -1;
  }
}

.m-plan {
  position: relative;
  border-radius: var(--radius-card);
  border: 1px solid var(--color-border);
  background: var(--color-surface-raised);
  box-shadow: var(--shadow-md);
  padding: 1.5rem 1.4rem;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  transition: all var(--transition-base);
}

.m-plan:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-lg);
  transform: translateY(-2px);
}

/* The featured plan keeps the accent glow AND takes the same drop shadow as
   its neighbours — a glow alone is a tint, not elevation, so without the
   shadow the recommended card sat FLATTER than the two it is meant to lead. */
.m-plan-featured {
  border-color: var(--color-sky-600);
  background: var(--color-featured-soft);
  box-shadow: var(--shadow-md), var(--glow-accent);
}

.m-plan-featured:hover {
  border-color: var(--color-sky-400);
  box-shadow: var(--shadow-lg), var(--glow-accent-strong);
}

.m-plan-eyebrow {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-accent-on-page);
}

[dir="ltr"] .m-plan-eyebrow {
  letter-spacing: 0.08em;
}

.m-plan h3 {
  margin: 0;
  font-size: 1.18rem;
  font-weight: var(--font-weight-bold);
}

.m-plan-price {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
  font-variant-numeric: tabular-nums;
  unicode-bidi: isolate;
  margin-block: 0.2rem;
}

.m-plan-price b {
  font-size: 2.2rem;
  font-weight: 900;
  line-height: 1.1;
  color: var(--color-text);
}

.m-plan-price span {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.m-plan-compare {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.m-plan-was {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  text-decoration: line-through;
  unicode-bidi: isolate;
}

.m-plan-save {
  padding: 0.25rem 0.65rem;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  /* Brand, not accent: the text is --color-accent-on-page, which is sky in
     both themes, and it used to sit on --color-accent-soft — a tint that
     resolved violet in dark and sky in light, so the pill paired two
     different families depending on the theme. "Accent" means the purple
     admin realm everywhere else in this system. */
  color: var(--color-accent-on-page);
  background: var(--color-brand-soft);
  border: 1px solid var(--color-brand-border);
}

.m-plan p {
  margin: 0 0 var(--space-4);
  font-size: 0.92rem;
  color: var(--color-text-muted);
  line-height: 1.6;
}

.m-plan-cta {
  margin-top: auto;
  width: 100%;
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.65rem 1.2rem;
  border-radius: var(--radius-md);
  font-size: 0.95rem;
  font-weight: 700;
  text-decoration: none;
  transition: all var(--transition-base);
}

/* ── Narrow viewports: the badge and the plan row have to fit ──────────
   The eyebrow is nowrap, so at 12px its longest string overflows a 390px
   viewport and `overflow-x: clip` on <html> silently CUTS it off rather than
   scrolling. Shrinking it is what buys the single line. And the three plans
   stay on one row here, so the card has to give up everything that is not the
   offer: the prose description goes, the price steps down, and the CTA takes
   the smallest size that still keeps its label on one line. */
@media (max-width: 560px) {
  .m-eyebrow {
    /* Flat, not fluid. The clamp existed to keep a ~48-character badge on ONE
       line, and its floor was 8px — below the size at which Arabic renders its
       diacritics at all. The badge wraps now (see the base rule), so there is
       nothing left for the fluid step to buy, and a font size chosen in vw
       could not have survived a system font scale anyway. */
    /* 0.7rem: 0.68 is 10.88px and this stylesheet's own floor for Arabic
       diacritics is about 11px. */
    font-size: 0.7rem;
    padding: 0.35rem 0.6rem;
    gap: 0.25rem;
  }

  /* THREE PLANS ACROSS A PHONE IS A DESKTOP GRID DUMPED INTO A PHONE, and
     the measurement is the argument: at 390px each card is 92px wide, so the
     container query below bottomed the eyebrow out at 7.34px and the CTA at
     8.26px — on the one block of this page that has to be read before anybody
     pays, in a script whose diacritics stop rendering at all below about 11px.
     The previous pass fixed the OVERFLOW (059) and left the type at the floor,
     because it kept asking how to fit three cards into 390px rather than
     whether three cards belong there. Almost every visitor is on a phone.

     So the grid is one column here and each plan is a two-line ROW — name and
     tier on the reading side, price and saving on the other — which needs no
     fluid step at all: at full width every size is the one we actually wanted,
     and it survives an Android system font scale because nothing is measured
     in the viewport.

     It is TALLER, and that is the trade rather than a regression: measured on
     /expense-tracker-egypt at 390px the band goes 714px -> 840px, because three
     two-line rows and one button cost more than three cards crushed into 92px
     each. The block that decides whether somebody pays is the last place to buy
     126px with type nobody can read. The expert's own answer goes further and
     condenses the three plans into one card — that is a change to what the page
     SAYS about the offer, so it belongs in the page rewrites, not here. */
  .m-plans {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
    margin-block: var(--space-6);
  }

  .m-plan {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 0.75rem;
    row-gap: 0.1rem;
    padding: 0.75rem 0.9rem;
    border-radius: var(--radius-md);
    text-align: start;
    /* The card is full width now, so the container query almost never binds —
       and it stays, because the case it was written for is the one a width
       breakpoint cannot see: the price is one unbreakable run, and an Android
       system font scale grows it while the viewport stands still. At 1.0x it
       is dead weight; at 1.5x on a 280px screen it is the only thing keeping
       «١٬٦٠٠» inside its own row. */
    container-type: inline-size;
  }

  /* Grid line numbers follow the writing direction, so one placement serves
     both scripts and nothing needs an RTL mirror. */
  .m-plan-eyebrow  { grid-area: 1 / 1; justify-self: start; font-size: 0.7rem; }
  .m-plan h3       { grid-area: 2 / 1; font-size: 1.02rem; }
  .m-plan-price    { grid-area: 1 / 2; justify-content: flex-end; margin-block: 0; gap: 0.3rem; }
  .m-plan-compare  { grid-area: 2 / 2; justify-content: flex-end; gap: 0.35rem; }

  .m-plan-price b    { font-size: min(1.45rem, 13cqi); }
  .m-plan-price span { font-size: 0.72rem; }
  .m-plan-was        { font-size: 0.72rem; }
  /* 0.7rem, not 0.66: 0.66rem is 10.56px and this file's own comments put
     the floor at which Arabic still renders its diacritics at about 11px. */
  .m-plan-save       { font-size: 0.7rem; padding: 0.1rem 0.45rem; }

  /* The sentence under each price is the one thing the row cannot hold, and
     the one thing the block does not need: the tier, the price and the saving
     already say it. */
  .m-plan p { display: none; }

  /* ONE button, not three. The three carry the same label to the same URL, so
     stacked they ask the same question three times and cost 132px doing it;
     the one that survives is on the plan the page recommends. It is not a
     claim that only the yearly plan is buyable — the label starts a trial and
     the plan is chosen in the app — and every other CTA on the page is
     untouched. */
  .m-plan .m-plan-cta { display: none; }

  .m-plan-featured .m-plan-cta {
    display: inline-flex;
    grid-area: 3 / 1 / 4 / 3;
    margin-top: 0.6rem;
    font-size: 0.95rem;
    min-height: var(--control-height);
    border-radius: var(--radius-sm);
    white-space: normal;
    line-height: 1.25;
    padding: 0.5rem 0.9rem;
  }
}

.m-plan .btn-secondary.m-plan-cta {
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text);
}

.m-plan .btn-secondary.m-plan-cta:hover {
  background: var(--color-surface-hover);
  border-color: var(--color-brand-border);
  color: var(--color-brand);
  transform: translateY(-1px);
}

.m-plan-featured .btn-primary.m-plan-cta {
  background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%);
  border: 1px solid #38bdf8;
  color: var(--color-slate-950);
  box-shadow: 0 4px 16px rgba(16, 185, 129, 0.4);
}

.m-plan-featured .btn-primary.m-plan-cta:hover {
  color: var(--color-slate-950);
  background: linear-gradient(135deg, #38bdf8 0%, #0ea5e9 100%);
  box-shadow: 0 6px 22px rgba(16, 185, 129, 0.6);
  transform: translateY(-1px);
}

.m-plan-note {
  margin: var(--space-5) 0 0;
  max-width: 820px;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  line-height: 1.75;
}

/* ─── Stores & Platform Buttons ─────────────────────────────────────────── */

.m-stores {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-block: var(--space-6);
}

.m-store-btn {
  display: inline-flex;
  flex-direction: column;
  gap: 0.15rem;
  min-height: 60px;
  justify-content: center;
  padding: 0.6rem 1.4rem;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
  transition: all var(--transition-base);
}

.m-store-btn:hover {
  border-color: var(--color-brand);
  background: var(--color-surface-hover);
  color: var(--color-text);
  transform: translateY(-1px);
}

.m-store-btn small {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}

[dir="ltr"] .m-store-btn small {
  letter-spacing: 0.04em;
}

.m-store-btn b {
  font-size: 1.02rem;
  font-weight: var(--font-weight-bold);
}

/* ─── FAQ Section ───────────────────────────────────────────────────────── */

.m-faq {
  margin-block: clamp(1.4rem, 6vw, 4rem);
}

.m-faq h2 {
  font-size: clamp(1.35rem, 4.5vw, 1.85rem);
  font-weight: 700;
  margin: 0 0 var(--space-5);
}

.m-faq-item {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 0.95rem 1rem;
  margin-bottom: 0.55rem;
  background: var(--color-surface-raised);
  box-shadow: var(--shadow-sm);
  transition: border-color var(--transition-fast);
}

.m-faq-item:hover {
  border-color: var(--color-border-strong);
}

.m-faq-item h3 {
  font-size: 1rem;
  margin: 0 0 0.35rem;
  font-weight: 700;
  color: var(--color-text);
}

.m-faq-item p {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.92rem;
  line-height: 1.6;
}

@media (min-width: 640px) {
  .m-faq-item { padding: 1.2rem 1.35rem; margin-bottom: 0.85rem; }
  .m-faq-item h3 { font-size: 1.05rem; margin-bottom: 0.55rem; }
  .m-faq-item p { font-size: 0.95rem; line-height: 1.75; }
}

/* ─── Countries Quick Grid ──────────────────────────────────────────────── */





.m-country:hover {
  color: var(--color-text);
  border-color: var(--color-brand-border);
  background: var(--color-surface-hover);
}

/* ─── Closing Call To Action ────────────────────────────────────────────── */

.m-final {
  text-align: start;
  padding: clamp(2.5rem, 6vw, 4rem) clamp(1.5rem, 5vw, 3rem);
  border-radius: var(--radius-card);
  background: var(--gradient-final);
  border: 1px solid var(--color-sky-600);
  box-shadow: var(--glow-accent);
  margin-block: 3.5rem 2rem;
}

.m-final h2 {
  margin: 0 0 var(--space-3);
  font-size: clamp(1.4rem, 5vw, 2.1rem);
  font-weight: 900;
  line-height: 1.3;
}

.m-final p {
  color: var(--color-text-muted);
  font-size: 1.05rem;
  margin: 0 0 var(--space-6);
  max-width: 620px;
}

/* ─── Thumb-Reach Floating Bottom Dock (Mobile CRO) ─────────────────────── */

.m-dock {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 60;
  display: none;
  padding: 0.75rem clamp(1rem, 4vw, 1.25rem)
           calc(0.75rem + env(safe-area-inset-bottom, 0px));
  background: var(--color-surface-nav);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-top: 1px solid var(--color-border-strong);
  box-shadow: var(--shadow-dock);
  transform: translateY(110%);
  transition: transform var(--transition-slow);
}

.m-dock.is-up { transform: none; }

.m-dock .btn {
  width: 100%;
  min-height: var(--control-height-lg);
}

.m-dock-note {
  margin: 0.4rem 0 0;
  text-align: center;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}

@media (max-width: 768px) {
  .m-dock { display: block; }
  body.has-dock .m-footer { padding-block-end: 7.5rem; }
  .m-dock:not(.is-up) ~ .m-footer { padding-block-end: var(--space-10); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .m-dock { transition-duration: 0.01ms; }
}

/* ─── SaaS Footer ───────────────────────────────────────────────────────── */

.m-footer {
  border-top: 1px solid var(--color-border);
  padding-block: var(--space-10) var(--space-8);
  margin-top: 3.5rem;
  background: var(--color-surface-footer);
}

.m-footer-grid {
  display: grid;
  /* Two columns on a phone rather than one. Fifteen links stacked in a single
     column is a page, not a footer — it scrolled longer than the content above
     it. The brand block spans both so its description keeps its measure. */
  /* ONE column on a phone, now that each of the three is a closed <details>.
     Two columns was the right answer while they were open — fifteen stacked
     links scrolled longer than the content above them — and it is the wrong
     one for three collapsed headers, which leave a 2x2 grid with an empty
     cell and put two tap targets side by side at 44px each. A closed column
     costs one row, so a column IS a row. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-5);
}

.m-footer-brand-col {
  grid-column: 1 / -1;
}

@media (min-width: 640px) {
  .m-footer-grid {
    grid-template-columns: 1.5fr repeat(3, 1fr);
  }

  .m-footer-brand-col {
    grid-column: auto;
  }
}

.m-footer-brand-col {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.m-footer-desc {
  margin: 0;
  font-size: 0.88rem;
  color: var(--color-text-muted);
  line-height: 1.65;
  max-width: 320px;
}

.m-footer-security {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: var(--space-1);
}

.m-badge-security {
  font-size: var(--font-size-xs);
  color: var(--color-sky-400);
  background: var(--color-accent-chip);
  border: 1px solid var(--color-accent-chip-border);
  padding: 0.2rem 0.55rem;
  border-radius: var(--radius-pill);
}

.m-footer-col .m-footer-title {
  margin: 0 0 0.35rem;
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--color-text);
}

[dir="ltr"] .m-footer-col .m-footer-title {
  letter-spacing: 0.02em;
}

/* The three link columns are <details> now (see marketing.js): the marker
   goes, the heading keeps being the heading, and the whole summary is the tap
   target — a 15px triangle is not one. It only ever looks like a control on a
   phone, because that is the only width where the columns are closed. */
.m-footer-fold > summary {
  list-style: none;
  cursor: default;
}

.m-footer-fold > summary::-webkit-details-marker { display: none; }

.m-footer-fold > summary .m-footer-title { margin: 0; }

@media (max-width: 639px) {
  .m-footer-fold > summary {
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    min-height: var(--control-height);
    border-block-end: 1px solid var(--color-border);
  }

  /* A chevron drawn in CSS rather than a glyph: an emoji would be painted by
     whichever font the device happens to have. The two borders are PHYSICAL,
     and that is the one place in this stylesheet where logical properties are
     wrong: `border-inline-end` is the LEFT edge in Arabic, so the L-shape
     forms on the opposite corner and the same 45deg turn points the arrow at
     the side of the screen instead of down. Down means "more" in both
     scripts — the mark has no handedness to mirror, the same argument that
     kept the RTL flip off the language globe. */
  .m-footer-fold > summary::after {
    content: "";
    width: 0.45rem;
    height: 0.45rem;
    border-right: 2px solid var(--color-text-muted);
    border-bottom: 2px solid var(--color-text-muted);
    transform: translateY(-2px) rotate(45deg);
    transition: transform var(--transition-base);
    flex: 0 0 auto;
  }

  .m-footer-fold[open] > summary::after {
    transform: translateY(2px) rotate(225deg);
  }

  .m-footer-fold[open] > .m-footer-links { padding-block-start: var(--space-2); }
}

.m-footer-links {
  display: flex;
  flex-direction: column;
  /* No gap: each link already reserves a 44px tap target, so a gap on top of
     it was spacing the rows twice and stretching the column for nothing. */
  gap: 0;
}

/* The country list is a directory of eight, and eight rows is most of the
   footer's height on a phone. Two columns halves it without shrinking a
   single tap target. */
.m-footer-links-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-4);
}

.m-footer-links a {
  color: var(--color-text-muted);
  font-size: 0.88rem;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: var(--control-height);
  transition: color var(--transition-fast);
}

.m-footer-links a:hover {
  color: var(--color-text);
}

.m-footer-lang-link {
  font-weight: 700;
  color: var(--color-accent-on-page) ;
}

.m-footer-bottom {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}

/* Mobile footer. Declared AFTER the footer's own rules on purpose: these are
   equal-specificity overrides, so a media query placed earlier in the file
   loses to the base rule regardless of the viewport. 36px is still a
   comfortable target and it is what turns fifteen links from a screenful of
   scrolling into a footer. */
@media (max-width: 560px) {
  .m-footer { padding-block: var(--space-8) var(--space-6); margin-top: var(--space-10); }
  .m-footer-grid { gap: var(--space-5) var(--space-4); }
  /* The full 44px, not the small one. The reduced target was bought to keep
     fifteen stacked links from being a screen of footer, and the fold (above)
     buys that instead — a closed column costs one row, so the links only exist
     on screen for a reader who asked for them, and a reader who asked for a
     link should be able to hit it. */
  .m-footer-links a { min-height: var(--control-height); font-size: 0.84rem; }
  .m-footer-desc { font-size: 0.82rem; line-height: 1.5; }
  .m-footer-col .m-footer-title { font-size: 0.86rem; }
  .m-footer-bottom { margin-top: var(--space-4); padding-top: var(--space-3); }
}

.m-theme-toggle {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-height);
  gap: 0.45rem;
  padding: 0.35rem 0.75rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-family: var(--font-app);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  transition: all var(--transition-fast);
}

.m-theme-toggle:hover {
  color: var(--color-text);
  border-color: var(--color-border-strong);
  background: var(--color-surface-hover);
}

.m-theme-toggle:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* The nav's toggle is the same control as the footer's, minus the word: the
   bar is tight at 390px and the icon already says which way it goes. Square,
   so it keeps a full tap target without a label to stretch it. */
.m-theme-toggle-nav,
.m-nav-menu > summary {
  width: var(--control-height);
  min-height: var(--control-height);
  padding: 0;
  justify-content: center;
  flex: none;
}

.m-theme-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-md);
  line-height: 1;
}

:root[data-theme="light"] .m-theme-icon-light { display: none; }
:root[data-theme="light"] .m-theme-icon-dark { display: inline-flex; }
:root:not([data-theme="light"]) .m-theme-icon-light { display: inline-flex; }
:root:not([data-theme="light"]) .m-theme-icon-dark { display: none; }

/* ─── Motion & Responsive Adjustments ───────────────────────────────────── */

.m-hero-grid > *,
.m-band > * {
  animation: fw-enter-rise 320ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .m-hero-grid > *,
  .m-hero-solo,
  .m-band > *,
  .m-meter-fill { animation-duration: 0.01ms; }
  .m-wave i { animation-iteration-count: 1; animation-duration: 0.01ms; transform: scaleY(0.684); }
}

@media (max-width: 768px) {
  .m-nav-cta { display: none; }
  
  .m-hero-copy,
  .m-hero-solo,
  .m-hero-grid,
  .m-final {
    width: 100%;
  }
  
  .m-hero-actions .btn,
  .m-hero-actions .m-cta {
    width: 100% !important;
    display: flex;
    justify-content: center;
  }
  .m-cta-row {
    width: 100% !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
  }
  .m-cta-row .btn,
  .m-cta-row .m-cta,
  .m-hero-copy .btn.m-cta,
  .m-hero-solo .btn.m-cta,
  .btn.m-cta {
    width: 100% !important;
    max-width: 100% !important;
    display: flex !important;
    justify-content: center !important;
    box-sizing: border-box !important;
    text-align: center !important;
  }
  .m-trust {
    justify-content: center;
    text-align: center;
  }
}

/* Below 960px the three secondary links (course, pricing, premium) leave the
   bar and live in a <details> menu behind the hamburger. Measured: the six
   items plus the CTA wrap the bar to two rows at 800px, and 046's "a
   hamburger for two links is a panel to maintain for nothing" stopped
   holding once the course made it three. <details>, not a JS panel: it
   opens and closes with no script, the summary is keyboard-operable and
   announces its own state, and marketing.js only adds the outside-tap and
   Escape closes. The panel is absolute under the sticky bar so opening it
   never reflows the page. */
.m-nav-menu { display: none; }
.m-nav-menu > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius-pill);
  color: var(--color-text-muted);
}
.m-nav-menu > summary::-webkit-details-marker { display: none; }
.m-nav-menu > summary:hover { color: var(--color-text); }
.m-nav-menu > summary:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.m-nav-menu .m-nav-menu-x { display: none; }
.m-nav-menu[open] .m-nav-menu-x { display: block; }
.m-nav-menu[open] .m-nav-menu-bars { display: none; }
.m-nav-menu-panel {
  position: absolute;
  inset-inline: 0;
  top: 100%;
  display: flex;
  flex-direction: column;
  /* A slip torn off the bar — the same paper, the same teeth and the same
     perforation the landing receipt uses (`.m-receipt`), so the one menu on
     the site is drawn in the site's own material rather than as a generic
     dropdown. Opaque by construction: paper is not translucent, and the
     bar's 75% ground under a LIST of links let the hero's heading show
     through the choices. The teeth are cut by a mask, which clips a
     box-shadow with them, so the shadow is a filter that traces the torn
     silhouette (046's rule). The bottom padding carries the tooth height, or
     the last row's descenders would be cut with the paper. */
  --tooth: 11px;
  --tooth-h: 7px;
  padding: var(--space-2) calc(var(--space-5) - var(--space-2)) calc(var(--space-3) + var(--tooth-h));
  background: var(--color-receipt);
  filter: drop-shadow(var(--shadow-receipt));
  -webkit-mask:
    radial-gradient(circle at 50% 100%, transparent 0 5px, #000 5.5px)
      repeat-x bottom / var(--tooth) var(--tooth-h),
    linear-gradient(#000 0 0) no-repeat 0 0 / 100% calc(100% - var(--tooth-h));
  mask:
    radial-gradient(circle at 50% 100%, transparent 0 5px, #000 5.5px)
      repeat-x bottom / var(--tooth) var(--tooth-h),
    linear-gradient(#000 0 0) no-repeat 0 0 / 100% calc(100% - var(--tooth-h));
}
/* Motion that answers the tap: the slip drops 6px into place. A native
   <details> cannot animate its close, and a snap shut is the right feel for
   dismissal anyway. */
.m-nav-menu[open] > .m-nav-menu-panel {
  animation: m-nav-menu-drop 180ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
@keyframes m-nav-menu-drop {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
.m-nav-menu-panel .m-nav-link {
  display: flex;
  align-items: center;
  min-height: var(--control-height);
  padding-inline: var(--space-2);
  color: var(--color-ink);
  border-radius: var(--radius-sm);
}
.m-nav-menu-panel .m-nav-link:hover { color: var(--color-brand); }
/* The language row is a switch, not a page; the perforation under it is the
   receipt's own way of saying "different kind of line below". */
.m-nav-menu-panel .m-nav-menu-lang {
  margin-block-end: var(--space-2);
  padding-block-end: var(--space-2);
  border-bottom: 1px dashed var(--color-rule);
  border-radius: 0;
}
/* On a phone the bar is brand · log in · menu. The language switch and the
   theme toggle measured 57px and 44px, and with the hamburger beside them
   the five items wrapped the bar to two rows at 390px (425px of content in
   350px). The language link moves INTO the menu (a second anchor, first
   row); the theme toggle does not — the footer already carries one, a third
   would be a third, and switching theme is a rare tap. */
.m-nav-menu-lang { display: none; }
@media (max-width: 560px) {
  .m-nav-phone-hide { display: none; }
  .m-nav-menu-lang { display: flex; }
}
.m-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
@media (max-width: 959px) {
  .m-nav-secondary { display: none; }
  .m-nav-menu { display: block; }
}

@media (max-width: 560px) {
  .m-nav-link { padding-inline: 0.55rem; }
  .m-nav-links { gap: 0.35rem; }
  .m-brand { font-size: 1.05rem; }
}

@media (max-width: 400px) {
  .wrap-wide { padding-inline: var(--space-4); }
  .m-hero-copy h1 { font-size: 1.7rem; }
  /* .m-plan-price b was set to 1.85rem here — LARGER than the 1.4rem the
     compact three-across block above gives it, and declared later in the file
     so it won on exactly the narrowest screens. A 29.6px figure in an 88px
     card is what put «١٬٦٠٠» outside its own card at 320px. Left over from
     when this breakpoint stacked the plans one per row. */
  .m-stores { flex-direction: column; }
  .m-store-btn { width: 100%; }
}

/* Two up on a phone, the footer country list's own shape and for the same
   reason: a feature page's related block is eight links, and eight stacked
   44px rows are 522px — more than the hero and the one section above them
   together. The tap target is untouched; only the column count changes. */
.m-related-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-4);
}

.m-related-links > p { margin: 0; }

/* On a wide screen these are a short directory, not a reading column: one
   link per row left a single 680px-wide stack running down the page with most
   of each row empty. `auto-fill` lets the count follow the width instead of a
   breakpoint guessing it. */
@media (min-width: 640px) {
  .m-related-links {
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    column-gap: var(--space-6);
  }
}

.m-related-link {
  display: inline-flex;
  min-height: var(--control-height);
  font-weight: 600;
}

.m-theme-label { font-size: var(--font-size-xs); }

/* ═══ The motion layer ══════════════════════════════════════════════════════
   The pages were correct and inert. Everything below gives them movement, and
   every rule here obeys three constraints that are worth stating once rather
   than repeating in each block.

   (1) Nothing here invents a colour, a radius or a shadow. Motion is the only
       new thing; the palette, the surfaces and the type are untouched.
   (2) Every hiding rule is scoped to `.m-js`, which the head snippet sets
       before the body paints and drops again on load if `marketing.js` never
       ran. A reveal animation must never be the reason a reader sees nothing.
   (3) The reduced-motion branch ZEROES durations rather than removing
       animations. `fw-enter-rise` in theme.css records why: the fill is
       `both`, so a dropped animation holds the from-state — opacity 0 — and
       blanks the page for exactly the person who asked for less movement.
   ─────────────────────────────────────────────────────────────────────── */

.m-js .m-reveal {
  opacity: 0;
  transform: translateY(14px);
}

.m-js .m-reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 520ms cubic-bezier(0.22, 0.61, 0.36, 1),
              transform 520ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* The stagger is on the CHILDREN of a grid, never on the section, so four
   cards deal themselves out instead of arriving as one slab. Capped at six
   steps: past that the last item waits long enough to read as a fault rather
   than as rhythm — 038's cap, for the same reason. */
.m-js .m-cards > .m-reveal:nth-child(2),
.m-js .m-rows > .m-reveal:nth-child(2),
.m-js .m-plans > .m-reveal:nth-child(2),
.m-js .m-faq > .m-reveal:nth-child(2) { transition-delay: 70ms; }
.m-js .m-cards > .m-reveal:nth-child(3),
.m-js .m-rows > .m-reveal:nth-child(3),
.m-js .m-plans > .m-reveal:nth-child(3),
.m-js .m-faq > .m-reveal:nth-child(3) { transition-delay: 140ms; }
.m-js .m-cards > .m-reveal:nth-child(4),
.m-js .m-rows > .m-reveal:nth-child(4),
.m-js .m-faq > .m-reveal:nth-child(4) { transition-delay: 210ms; }
.m-js .m-cards > .m-reveal:nth-child(n + 5),
.m-js .m-rows > .m-reveal:nth-child(n + 5),
.m-js .m-faq > .m-reveal:nth-child(n + 5) { transition-delay: 280ms; }

/* ─── The hero's capture pills, which are the product demonstrating itself ──
   The mic pill carries real moving bars (`.m-wave`, which predates this), the
   camera pill carries a scan line crossing a receipt, and the tap pill has a
   ring that fires like a tap landing. They are the three doors the page is
   arguing about, so they move rather than sitting there as emoji. */

.m-pill-action {
  position: relative;
  overflow: hidden;
}

.m-pill-action:hover,
.m-pill-action:focus-visible {
  border-color: var(--color-sky-600);
  transform: translateY(-1px);
}

/* The scan sweep. `inset-inline-start` rather than `left`, and the keyframe
   moves `translateX` in the writing direction — an RTL page reads the sweep
   from the right, which is where its eye starts. */
.m-pill-scan::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: -40%;
  width: 40%;
  background: linear-gradient(
    90deg,
    transparent,
    var(--color-brand-soft),
    transparent
  );
  animation: mScan 2600ms ease-in-out infinite;
  pointer-events: none;
}

@keyframes mScan {
  0%   { transform: translateX(0); opacity: 0; }
  12%  { opacity: 1; }
  70%  { transform: translateX(350%); opacity: 1; }
  100% { transform: translateX(350%); opacity: 0; }
}

[dir="rtl"] .m-pill-scan::after {
  animation-name: mScanRtl;
}

@keyframes mScanRtl {
  0%   { transform: translateX(0); opacity: 0; }
  12%  { opacity: 1; }
  70%  { transform: translateX(-350%); opacity: 1; }
  100% { transform: translateX(-350%); opacity: 0; }
}

/* The tap ring. A single expanding circle that repeats on a long cycle, so it
   reads as an occasional tap rather than a throbbing dot. */
.m-pill-tap .m-tap {
  position: relative;
  display: inline-flex;
  width: 14px;
  height: 14px;
  align-items: center;
  justify-content: center;
}

.m-pill-tap .m-tap::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-sky-400);
}

.m-pill-tap .m-tap::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px solid var(--color-sky-400);
  animation: mTap 2600ms ease-out infinite;
}

@keyframes mTap {
  0%   { transform: scale(0.4); opacity: 0.9; }
  45%  { transform: scale(1.35); opacity: 0; }
  100% { transform: scale(1.35); opacity: 0; }
}

/* ─── The in-app card breathes ───────────────────────────────────────────
   It is a real screenshot of a real screen, and a still image of a live
   screen is the flattest thing on the page. The meter fills as the card
   arrives and the headline figure counts up to its real value (marketing.js),
   which is the one moment on a marketing page where a number is allowed to
   move: it is showing you the app working. */

.m-js .m-hero-visual .ins-meter > span {
  animation: none;
  transform: scaleX(0);
  transform-origin: inline-start;
  transition: transform 1100ms cubic-bezier(0.22, 0.61, 0.36, 1) 220ms;
}

.m-js .m-reveal.is-in .ins-meter > span,
.m-js .m-reveal.is-in .m-hero-visual .ins-meter > span {
  transform: scaleX(1);
}

.m-hero-visual .insight-hero {
  transition: transform var(--transition-slow), box-shadow var(--transition-slow);
}

.m-hero-visual .insight-hero:hover {
  transform: translateY(-3px);
}

/* The live badge over the card. It pulses once every few seconds — the
   interval is long on purpose, because a badge that blinks is an advert and
   a badge that breathes is a status light. */
.m-hero-visual-badge {
  animation: mBreathe 3400ms ease-in-out infinite;
}

@keyframes mBreathe {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-2px); }
}

/* ─── The brand mark ─────────────────────────────────────────────────────
   One slow pass of light across the logo plate on load, and nothing after
   that. The nav is on every page and a permanently animated logo is the
   first thing that makes a site feel cheap. */
.m-brand-icon {
  /* One pass on load and nothing after it. A permanently animated logo is the
     first thing that makes a site feel cheap, and a hover state alone is no
     life at all on a phone, which is most of this traffic. The receipt tilts
     once as the page arrives, the way a slip settles. */
  animation: mBrandSettle 900ms cubic-bezier(0.22, 0.61, 0.36, 1) 120ms both;
  transition: transform var(--transition-base);
}

@keyframes mBrandSettle {
  0%   { transform: rotate(-9deg) scale(0.88); opacity: 0; }
  60%  { transform: rotate(2deg) scale(1.03); opacity: 1; }
  100% { transform: none; opacity: 1; }
}

.m-brand:hover .m-brand-icon {
  transform: rotate(-4deg) scale(1.04);
}

/* The two glyphs inside it draw themselves in, once. */
.m-brand-icon svg path {
  stroke-dasharray: 64;
  stroke-dashoffset: 0;
}

.m-js .m-brand-icon svg path {
  animation: mBrandDraw 900ms ease-out 200ms both;
}

@keyframes mBrandDraw {
  from { stroke-dashoffset: 64; }
  to   { stroke-dashoffset: 0; }
}

/* ─── Rows, plans and links answer the cursor ────────────────────────────
   `.m-card` already lifted on hover; the other three surfaces did not, so
   half the page responded to a pointer and half did not. */

.m-row,
.m-plan,
.m-related-link,
.m-store-btn {
  transition: transform var(--transition-base), border-color var(--transition-base),
              box-shadow var(--transition-base);
}

.m-row:hover {
  transform: translateX(2px);
}

[dir="rtl"] .m-row:hover {
  transform: translateX(-2px);
}

.m-plan:hover,
.m-store-btn:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}

.m-related-link:hover {
  transform: translateY(-1px);
}

/* The primary call to action is the one element allowed a resting animation,
   and even that is only a shine on hover. */
.m-cta {
  position: relative;
  overflow: hidden;
}

.m-cta::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: -60%;
  width: 45%;
  /* The button's own ink over the button's own ground, so the sweep is
     theme-correct by construction rather than by a white that happens to
     read on today's brand fill. */
  background: linear-gradient(90deg, transparent,
    color-mix(in srgb, var(--color-on-brand) 26%, transparent), transparent);
  transform: translateX(0);
  opacity: 0;
  pointer-events: none;
}

.m-cta:hover::after {
  animation: mShine 720ms ease-out;
}

@keyframes mShine {
  0%   { transform: translateX(0); opacity: 1; }
  100% { transform: translateX(420%); opacity: 0; }
}

[dir="rtl"] .m-cta:hover::after {
  animation-name: mShineRtl;
}

@keyframes mShineRtl {
  0%   { transform: translateX(0); opacity: 1; }
  100% { transform: translateX(-420%); opacity: 0; }
}

/* ─── Reduced motion ─────────────────────────────────────────────────────
   Durations go to nothing; the animations stay declared. Removing them would
   hold each `both`-filled from-state and leave the page blank for the one
   reader who explicitly asked for less movement. */
@media (prefers-reduced-motion: reduce) {
  .m-nav-menu[open] > .m-nav-menu-panel { animation: none; }
  .m-js .m-reveal,
  .m-js .m-reveal.is-in {
    opacity: 1;
    transform: none;
    transition-duration: 0.01ms;
    transition-delay: 0ms;
  }

  .m-pill-scan::after,
  .m-pill-tap .m-tap::after,
  .m-hero-visual-badge,
  .m-brand-icon,
  .m-js .m-brand-icon svg path,
  .m-cta:hover::after {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
  }

  .m-js .m-hero-visual .ins-meter > span {
    transform: scaleX(1);
    transition-duration: 0.01ms;
  }

  .m-row:hover,
  .m-plan:hover,
  .m-store-btn:hover,
  .m-related-link:hover,
  .m-hero-visual .insight-hero:hover {
    transform: none;
  }
}

/* ─── The hero earns its height back ─────────────────────────────────────
   With the live screen restored under it, the hero's own copy is competing
   with the single most persuasive thing on the site for the first viewport.
   Measured on a 420×900 window: the card's top edge sat at 590px in English
   and 620px in Arabic, so on the 667px phones this market still runs it was
   entirely below the fold. These are the only two blocks with slack in them —
   the pills are a row of chips and the gap above the card is a section break
   that no longer separates anything, because the card IS the hero's
   continuation rather than a new argument.
   ─────────────────────────────────────────────────────────────────────── */

.m-hero-pills {
  margin-top: var(--space-3);
}

.m-showcase-hero {
  /* The hero's own bottom padding plus a section's top padding was two gaps
     doing one job. `m-showcase-hero` is emitted only for the card that sits
     directly under a hero, so this cannot reach the mid-page showcase. */
  padding-block-start: var(--space-4);
  margin-block-start: 0;
}

@media (max-width: 480px) {
  .m-hero-solo {
    padding-block-start: var(--space-6);
  }

  .m-hero-copy .lede {
    line-height: 1.6;
  }

  .m-hero-pills {
    gap: 0.45rem;
  }

  .m-pill-action {
    padding: 0.38rem 0.7rem;
    font-size: var(--font-size-xs);
  }
}

/* The product column is nine links now that every feature has a page of its
   own, and nine stacked links is a screen of footer on a phone. It takes the
   country list's own two-up grid below 640px — the rule already existed for
   exactly this shape and was only ever applied to one column. */
@media (max-width: 639px) {
  .m-footer-col .m-footer-links {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* Column gap only. The base rule's own comment says why the row gap is
       zero: every link already reserves a 44px tap target, so a row gap
       spaces the rows twice. */
    column-gap: var(--space-4);
  }
}

/* ─── The money course (content/course/) ───────────────────────────────── */

/* A lesson is 600–900 words of prose, which is the one thing no other
   marketing page is: `.m-section p` is muted because a feature page's
   paragraphs are captions under a heading, and a caption's colour on a
   reading column is a page somebody squints at. The lesson body takes the
   page's own ink; the muted tone survives for the source line and the nav
   labels, where it means what it means everywhere else. */
.m-lesson .m-section p,
.m-lesson .m-section li,
.m-lesson-handoff {
  color: var(--color-text);
  line-height: 1.85;
}

.m-lesson .m-section h2 {
  font-size: clamp(1.2rem, 4vw, 1.5rem);
  margin-top: 0.4rem;
}

.m-lesson .m-section {
  margin-block: clamp(1.15rem, 5vw, 2.4rem);
}

.m-lesson ol {
  margin: 0 0 1.15rem;
  padding-inline-start: 1.4rem;
}

/* The page prints Arabic-Indic digits everywhere else, so the list marker
   does too; a Western "1." beside «١٬٥٠٠» is two digit systems on one line. */
[dir="rtl"] .m-lesson ol {
  list-style-type: arabic-indic;
}

/* Each lesson's own title already carries its number, so the hub list
   draws no marker: «1. الدرس ١.١» says the number twice in two scripts. */
.m-course-list {
  list-style: none;
  margin: 0 0 1.15rem;
  padding-inline-start: 0;
}

.m-lesson ol li,
.m-course-list li {
  margin-bottom: 0.45rem;
}

.m-lesson .m-eyebrow a {
  color: inherit;
  text-decoration: none;
}
.m-lesson .m-eyebrow a:hover,
.m-lesson .m-eyebrow a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* The one closing CTA per lesson, unchanged in anatomy; only its lead-in
   is a sentence the lesson wrote rather than a heading. */
.m-lesson .m-final p:first-child {
  color: var(--color-text);
  font-size: 1.05rem;
  font-weight: 600;
  max-width: 620px;
}

.m-lesson-source {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  line-height: 1.7;
  margin: 0 0 1rem;
}

.m-lesson-handoff {
  margin: 0 0 1.5rem;
}

/* The foot of a lesson opens with the receipt's perforation: what is above it
   is the lesson, what is below it is where to go next. */
.m-lesson-source {
  border-top: 1px dashed var(--color-rule);
  padding-top: 1.1rem;
}

/* One strong card — the next lesson — and a quiet row under it. The card is
   the page's second call to action and the only one for a reader who is not
   signing up tonight, so it takes the brand's border and the title's ink;
   "previous" and "all lessons" are text links, because going back is never
   the thing a course foot should sell. */
.m-lesson-nav {
  display: grid;
  gap: var(--space-3);
  margin-block: 1.5rem 2.5rem;
}

.m-lesson-nav-next {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--color-brand-border);
  border-radius: var(--radius-lg);
  background: var(--color-brand-soft);
  color: var(--color-text);
  text-decoration: none;
  transition: border-color var(--transition-fast);
}

.m-lesson-nav-next:hover { border-color: var(--color-brand); }

.m-lesson-nav-next .m-lesson-nav-title {
  display: flex;
  align-items: baseline;
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.4;
}

/* The arrow is the card's own affordance, drawn once and mirrored with the
   page's direction; it never travels on hover. */
.m-lesson-nav-next .m-lesson-nav-title::after {
  content: "←";
  margin-inline-start: auto;
  padding-inline-start: 0.75rem;
  color: var(--color-brand);
  font-weight: 400;
}
[dir="ltr"] .m-lesson-nav-next .m-lesson-nav-title::after { content: "→"; }

.m-lesson-nav-label {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
}

.m-lesson-nav-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
}

.m-lesson-nav-prev,
.m-lesson-nav-hub {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  min-height: var(--control-height);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
  text-decoration: none;
}

.m-lesson-nav-prev { flex: 1 1 16rem; }
.m-lesson-nav-prev .m-lesson-nav-title { display: flex; align-items: baseline; color: var(--color-text); }
.m-lesson-nav-prev:hover .m-lesson-nav-title,
.m-lesson-nav-hub:hover { color: var(--color-brand); }

/* The last lesson has no next: the hub link sits outside the row and takes
   the card. */
.m-lesson-nav > .m-lesson-nav-hub {
  display: flex;
  padding: 1rem 1.1rem;
  border: 1px solid var(--color-brand-border);
  border-radius: var(--radius-lg);
  background: var(--color-brand-soft);
  color: var(--color-text);
  font-size: 1.15rem;
  font-weight: 700;
}

/* The hub: eight module blocks, each an ordered list of its lessons. The
   module heading takes the same number column its lessons do — «٣» over
   «٣.١», «٣.٢», «٣.٣» — so the numbering reads as one outline. */
.m-course-module h2 {
  display: flex;
  align-items: baseline;
}
/* The module's number is part of its heading — same ink, same weight, same
   size — while the lesson numbers under it stay muted and small: that
   contrast is the outline's hierarchy. The column width is in rem so the
   two sizes still share one edge. */
.m-course-module h2 .m-course-no {
  color: inherit;
  font-weight: inherit;
}

.m-course-list a {
  display: inline-flex;
  align-items: baseline;
  /* 23px line + 2 × 0.65rem = the 44px target, with the number on the first
     line of a title that wraps rather than floating beside its middle. */
  padding-block: 0.65rem;
  font-weight: 600;
  line-height: 1.45;
}

/* The lesson number, set apart from its title the way a receipt sets a line's
   quantity apart from the item: muted, tabular, one fixed column wide. */
.m-course-no {
  flex: none;
  min-width: 2.6rem;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}
