/* IN2Fitness — shared design system for the WP block theme.
   Dark athletic editorial: #0a0a0a base, gold accent, Archivo + JetBrains Mono.
   Arabic/RTL via body.rtl class (font-family swap + direction flip).
   Fonts load via inc/enqueue.php as a single Google Fonts call — no @import
   here so the editor stylesheet doesn't trigger a remote fetch on every save. */

/* ===== CSS OWNERSHIP MAP (2026-08-08) ======================================
   Six lanes edit the join flow, the plans page and the hero/banner at once.
   This file is the ONLY shared style surface, so it is single-owner.
   Line ranges are as of this revision — re-derive after any large insertion.

   RULE OF THUMB: a cluster may move to a block-level style.css ONLY if every
   element that carries its classes is emitted by that one block. Patterns
   (theme/patterns/*.php) are raw wp:html and NEVER load a block stylesheet, so
   any cluster a pattern touches is permanently shared and stays here.

   ---- 1. TOKENS & PRIMITIVES ------------- L125-303  | SINGLE-OWNER
     :root alias bridge, --space-*, --fs-*, reset, .container, .eyebrow, .btn.
     Everything downstream resolves through here.

   ---- 2. NAV / HEADER ------------------- L305-351
   ---- 3. SECTION HEAD ------------------- L353-380

   ---- 4. PAGE-HERO ---------------------- L382-461  | STAYS HERE
     .page-hero__* is emitted by NINE raw-HTML patterns (faqs-hero, gx-hero,
     locations-hero, privacy-hero, promotions-hero, pt-hero, terms-hero,
     customer-protection-hero, single-branch/single-gx-class) as well as
     blocks/page-hero/. A block-level style.css would load only on pages that
     use the BLOCK and would silently unstyle all nine patterns.
     VERDICT: the hero lane extends page-hero HERE, not in a block file.

   ---- 5. LEGAL PAGES -------------------- L463-479
   ---- 6. FOOTER / BOTTOM-BAR / COOKIE --- L481-543
   ---- 7. PAGE-CTA / FACILITIES / STEP-VIDEO / ABOUT --- L545-744
       NB .step-video__* shares a prefix with the wizard's .step — never
       find/replace on ".step".
   ---- 8. MARQUEE + shared responsive ---- L746-851

   ---- 9. RTL / ARABIC BLOCK ------------- L853-1149  | SINGLE-OWNER
     Cross-cuts every lane. Carries the 2026-07-19 join-flow fixes (commit
     f689c56) and the Tajawal weight remap. Any lane that RENAMES a class must
     say so, or its RTL fix silently detaches with no error. Paired with the
     ARABIC LABEL TRACKING list at the foot of the file — the two are edited
     together, and the split between them is documented at the head of each.

   ---- 10. SCROLLBARS / EDGE-ARROWS ------ L1151-1215
   ---- 11. GX CLASSES / PT / FAQ --------- L1217-1336
     .class-card: NO hover-revealed description rules (meeting 2026-08-03).

   ---- 12. CONTACT FORM + .field --------- L1338-1399  | STAYS HERE
     .field / .field--row / .phone-row are shared by blocks/contact-form/
     (which HAS its own style.css) and the join plugin's form-skeleton.php.

   ---- 13. COUNTRY-CODE PICKER ----------- L1401-1514  | STAYS HERE
     .cc-picker__* used by blocks/contact-form/{render.php,view.js} AND the
     join plugin. Documented as shared at the head of the cluster.
     The tail of this range (.contact-form__submit / __feedback and the
     contact 900px media query) belongs with cluster 12 conceptually; it sits
     after the picker only because that is the file's existing order.

   ---- 14. PLANS GRID -------------------- L1516-1621  | STAYS HERE
     .plans__grid / .plan / .plan__* are emitted by blocks/plans-grid/render.php
     AND patterns/promotions-plans-loop.php. plans-grid must not take these
     rules over in a block stylesheet — the pattern would render unstyled.
     Related fragments elsewhere that move WITH it if it ever does: the RTL
     bullet + bidi-isolate rules and the AR tracking entries in clusters 9/21.
     WARNING: .plan-opt__* in cluster 16 is the WIZARD's plan card, a different
     component. Do not merge or cross-edit the two.

   ---- 15. AMENITIES / LOCATIONS / APP-CTA  L1623-1814

   ---- 16. JOIN WIZARD (PHASE 6) --------- L1816-2280  | MOVE OUT (later)
     Sole consumer is the in2fitness-join-us plugin, which registers NO
     stylesheet at all — the whole wizard is styled from this theme file, which
     is the structural reason its typography drifted from the design system and
     therefore the root cause of meeting item A6. The fix is
     plugins/in2fitness-join-us/assets/css/join.css, enqueued with
     ['in2fitness-site'] as a dependency so the tokens above load first.
     DEFERRED by the 2026-08-08 reconciliation: it is a ~300-line move across a
     plugin/theme boundary and must not run while four lanes are adding
     join-flow selectors. Until it happens, the wizard lane sends selector
     requests here rather than editing this file.
     STAYS HERE regardless: .field*, .cc-picker__*, .hint (shared with contact).

   ---- 17. STATUS SCREEN ----------------- L2282-2321  | MOVE OUT (later)
     .in2-status* is emitted only by JoinFormBlock.php and goes with the wizard.
     Its .in2-status__meta* rules currently live in an inline <style> in that
     PHP file, which prints inside <body> and therefore beats this file at equal
     specificity — do not try to restyle them from here.

   ---- 18. BRAND ACCENTS ----------------- L2323-2404  | SINGLE-OWNER
   ---- 19. ACCENT BUDGET ----------------- L2406-2437  | SINGLE-OWNER
     A standing constraint on every lane: accent is for actions, active states,
     authored <em>, and the teal/lime semantic marks. Repeated per-item
     decoration is what the rule exists to stop.

   ---- 20. INK HEADROOM ------------------ L2439-2485  | SINGLE-OWNER
     Any lane adding a display heading with line-height < 1 must get it added
     to this list. Do not re-solve it locally with margins.

   ---- 21. ARABIC LABEL TRACKING --------- L2487-2538  | SINGLE-OWNER
     Paired with cluster 9.

   HERO / BANNER — NOT IN THIS FILE. Already correctly block-owned:
     blocks/hero-video-slider/style.css  (.hero__*)
     blocks/banner-slider/style.css      (.banner*)
   This file holds only five cross-references into them: body.rtl .hero__title
   and body.rtl .hero__kicker (cluster 9), .hero__title ink headroom
   (cluster 20), and .hero__kicker / .hero__scroll AR tracking (cluster 21).
   Renaming any of .hero__title / .hero__kicker / .hero__scroll detaches all
   five with no error and silently reintroduces the Arabic hero-clipping bug
   from the 2026-07-29 review. Announce such a rename before making it.

   Blocks that already own a style.css and are self-contained: banner-slider,
   contact-form, faq-accordion, hero-video-slider, home-classes-strip,
   language-switcher, locations-map, marquee, stat-counter.
   ========================================================================= */

/* Top-level <main> wraps full-bleed pattern <section>s that own their own
   vertical padding. Zero out theme.json's blockGap on the main group so
   adjacent sections butt up flush, matching the demo_3 layout. */
main.wp-block-group { --wp--style--block-gap: 0px; }
main.wp-block-group > * + * { margin-block-start: 0; }

/* ---------- TOKEN ALIAS BRIDGE ---------------------------------------------
   theme.json emits design tokens as --wp--preset--color--* / --wp--custom--*.
   The legacy demo CSS below uses the short names (--bg, --gold, --font-display,
   --nav-h, …). The aliases below let editors tweak the palette from the Site
   Editor's Style Book and have those changes flow through unchanged. The
   hard-coded fallbacks match the demo defaults so the theme still renders
   correctly even before theme.json is parsed. */
:root {
  --bg:        var(--wp--preset--color--bg,        #0a0a0a);
  --bg-2:      var(--wp--preset--color--bg-2,      #111111);
  --bg-3:      var(--wp--preset--color--bg-3,      #181818);
  --ink:       var(--wp--preset--color--ink,       #f4f1ea);
  --ink-dim:   var(--wp--preset--color--ink-dim,   #a8a39a);
  --ink-mute:  var(--wp--preset--color--ink-mute,  #6a655c);
  /* Brand accents. The primary is the logo orange (#EC6331 — the same value
     used in in2fitness-logo.svg); teal and lime are the brand doc's supporting
     accents, applied narrowly: teal = Ladies, lime = recovery/wellness.
     The *-rgb triplets exist so translucent glows/borders can follow the token
     instead of hard-coding the colour (see the ~41 rgba() call sites below).
     NOTE: the theme.json palette slugs are still "gold"/"gold-deep" so stored
     block content and global styles keep resolving; only the values changed.
     Read --accent/--accent-deep in new rules — --gold/--gold-deep are aliases
     kept for the existing call sites. */
  --accent:      var(--wp--preset--color--gold,      #EC6331);
  --accent-deep: var(--wp--preset--color--gold-deep, #D9542A);
  --accent-rgb:  var(--wp--custom--accent-rgb, 236, 99, 49);

  --teal:        var(--wp--preset--color--teal, #2BB3A3);
  --teal-rgb:    var(--wp--custom--teal-rgb, 43, 179, 163);
  /* Ink for anything painted on a teal ground. Named separately from
     --on-accent because two selectors need it from OUTSIDE .is-ladies:
     the locations segment switch paints teal without entering that scope. */
  --on-teal:     #04201d;
  --lime:        var(--wp--preset--color--lime, #B4E33D);
  --lime-rgb:    var(--wp--custom--lime-rgb, 180, 227, 61);

  --gold:      var(--accent);
  --gold-deep: var(--accent-deep);

  /* Foreground for anything painted ON the accent (gold buttons, active pills,
     step numerals, badges). 15 rules hard-coded `color: #000`, which is why
     .locations__tab[data-seg="ladies"].active had to hand-write #04201d as a
     one-off — black is wrong on teal. Tokenising it lets .is-ladies flip the
     whole funnel's button foreground in one declaration (see the .is-ladies
     block near the end of this file). */
  --on-accent: var(--wp--custom--on-accent, #0a0a0a);

  /* Error/validation red. The only colour family in this file with no token —
     it appeared literally as #ff7a7a / rgba(255,122,122,…) in 4 rules across
     the contact form and the join summary. */
  --danger:     var(--wp--custom--danger, #ff7a7a);
  --danger-rgb: var(--wp--custom--danger-rgb, 255, 122, 122);

  --line:      var(--wp--custom--line,      rgba(244, 241, 234, 0.08));
  --line-2:    var(--wp--custom--line-2,    rgba(244, 241, 234, 0.14));
  --gold-soft: var(--wp--custom--gold-soft, rgba(var(--accent-rgb), 0.14));
  --nav-h:     var(--wp--custom--nav-h,     76px);

  --font-display: var(--wp--preset--font-family--display, 'Archivo', system-ui, sans-serif);
  --font-narrow:  var(--wp--preset--font-family--narrow,  'Archivo Narrow', 'Archivo', sans-serif);
  --font-mono:    var(--wp--preset--font-family--mono,    'JetBrains Mono', ui-monospace, monospace);
  /* Arabic face — Tajawal (Website Review 2026-07-29, section 2). Declared
     once here rather than repeated per rule, so a future swap is one line. */
  --font-arabic:  var(--wp--preset--font-family--arabic,  'Tajawal', system-ui, sans-serif);

  /* ---------- SPACING SCALE ------------------------------------------------
     Website Review 2026-07-29, section 3: "pair the bold, geometric brand
     identity with more breathing room."

     Before this, vertical spacing was ad-hoc — 0, 14, 18, 28, 40, 60, 80, 100
     and 120px all appeared, often asymmetrically (0/60, 100/0, 0/120), so
     sections had no shared rhythm and several butted straight together.

     One doubling scale, used everywhere. These are consumed only by this
     stylesheet (not by Site Editor controls), so they live here rather than
     round-tripping through theme.json like the colour and font tokens. */
  --space-4xs:  4px;
  --space-3xs:  8px;
  --space-2xs: 12px;
  --space-xs:  16px;
  --space-sm:  24px;
  --space-md:  32px;
  --space-lg:  48px;
  --space-xl:  64px;
  --space-2xl: 96px;
  --space-3xl: 128px;

  /* ---------- UI TYPE SCALE ------------------------------------------------
     theme.json's fontSizes preset has four entries (13 / 16 / large / x-large)
     and is aimed at editor-authored prose. It cannot express the mono
     micro-label sizes this UI is built from, and nothing in this file consumed
     it — every size below 26px was a literal.

     The join flow alone used 9, 10, 11, 12, 13, 14, 15, 17, 18, 20 and 22px,
     with four different sizes (9/10/11/12) doing the same job: an uppercase
     mono micro-label. That is the "inconsistent font" half of meeting item A6.

     Two label sizes, not four. Same rationale as the --space-* scale above:
     consumed only by this stylesheet, so it lives here rather than
     round-tripping through theme.json and appearing in the Site Editor's size
     picker, where a 10px mono label has no business being. */
  --fs-label-xs: 10px;  /* meta / secondary: step meta, hints, badges, dist  */
  --fs-label:    11px;  /* interactive / primary: buttons, pills, sub-labels */
  --fs-ui:       13px;  /* body-ish UI copy: summary rows, list items        */
  --fs-ui-lg:    14px;  /* emphasised UI copy: card titles, method labels    */
  --fs-title-sm: 18px;  /* panel titles: .summary__title, .terms-modal__title*/
  --fs-title:    20px;  /* step titles                                       */

  /* Section rhythm. Fluid so the extra air on desktop doesn't become dead
     space on a phone — the review's mobile scroll-depth finding (section 6)
     means vertical padding is expensive on small screens. */
  /* Ink headroom for display headings.
     Every display heading here sets line-height < 1 for the stacked, tight
     look. That makes the line box SMALLER than the em box, so glyph ink rises
     above the element's own top edge — and several of these sit inside an
     overflow:hidden section, which then clips it.

     Arabic makes it bite: the hamza on أ and the alif-madda آ push ink to
     ~0.87em above the baseline, where Latin caps reach ~0.72em. That is the
     whole of the homepage-hero bug in the 2026-07-29 review — the headline
     overlapped the breadcrumb by 4px with the old font.

     0.18em clears the worst case (line-height 0.85, Arabic ink at 0.87em) with
     margin to spare, and being em-based it scales with the heading instead of
     shrinking as the font grows. */
  --ink-headroom: 0.18em;

  --section-y:    clamp(72px, 8vw, 112px);
  --section-y-lg: clamp(96px, 11vw, 152px);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { background: var(--bg); color: var(--ink); font-family: var(--font-display); -webkit-font-smoothing: antialiased; }
body { overflow-x: hidden; }
a { color: inherit; text-decoration: none; }
img, svg, video { max-width: 100%; display: block; }

::selection { background: var(--gold); color: var(--on-accent); }

.container { max-width: 1400px; margin: 0 auto; padding: 0 48px; }
.eyebrow {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 0.25em; text-transform: uppercase;
  color: var(--ink-dim);
  display: inline-flex; align-items: center; gap: 10px;
}
.eyebrow::before { content: ''; width: 22px; height: 1px; background: var(--gold); }

.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 22px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em;
  text-transform: uppercase; font-weight: 500;
  border: 1px solid transparent;
  cursor: pointer; transition: all 0.2s;
  white-space: nowrap; background: transparent;
}
.btn--gold { background: var(--gold); color: var(--on-accent); }
.btn--gold:hover { background: #fff; transform: translateY(-1px); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line-2); }
.btn--ghost:hover { border-color: var(--gold); color: var(--gold); }

/* Language toggle button: in LTR the label is Arabic ("عربي"), so load
   Tajawal first in the stack so the glyphs render correctly.
   In RTL the label is Latin ("English"), so swap to the display font.
   Mirrors the live site's .header__cta--outline rule.
   Compound selector (.btn[data-lang-toggle]) ensures this beats any
   inline .btn font-family that appears later in the cascade. */
.btn[data-lang-toggle],
a[data-lang-toggle],
[data-lang-toggle] {
  font-family: var(--font-arabic);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: none;
}
.btn__arrow { transition: transform 0.2s; }
.btn:hover .btn__arrow { transform: translateX(3px); }

/* ===== NAV / HEADER ===== */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  height: var(--nav-h);
  display: flex; align-items: center;
  background: rgba(10,10,10,0.75);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
  transition: background 0.3s, border-color 0.3s;
}
.nav--scrolled { background: rgba(10,10,10,0.95); }
.nav--solid { background: rgba(10,10,10,0.95); }

/* When the WP admin bar is showing on the front-end (logged-in admins), push
   the fixed nav below it. WP exposes 32px on >782px screens and 46px below. */
body.admin-bar .nav { top: 32px; }
@media screen and (max-width: 782px) {
  body.admin-bar .nav { top: 46px; }
}
.nav__inner { width: 100%; max-width: 1400px; margin: 0 auto; padding: 0 48px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.nav__logo { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 5px 0; }
/* Wordmark, circle removed (Website Review 2026-07-29, section 3). The mark
   went from 1.74:1 to ~6.2:1, so height comes down — the letterforms are still
   larger than before, because the circle used to eat most of the box.
   The brightness(0) invert(1) filter that forced the mark to solid white is
   gone: it was erasing the brand orange from the header on every screen. */
.nav__logo img { height: 26px; width: auto; }
.nav__links { display: flex; gap: 28px; }
.nav__links a {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink-dim);
  padding: 14px 0; position: relative; display: inline-flex; align-items: center; min-height: 44px;
  transition: color 0.2s;
}
.nav__links a:hover { color: var(--ink); }
.nav__links a.active { color: var(--gold); }
.nav__links a.active::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 1px; background: var(--gold);
}
.nav__cta { display: flex; align-items: center; gap: 14px; }
.nav__burger { display: none; flex-direction: column; gap: 5px; padding: 10px; background: transparent; border: 0; cursor: pointer; }
.nav__burger span { width: 22px; height: 1.5px; background: var(--ink); transition: transform 0.3s, opacity 0.3s; }
.nav.open .nav__burger span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav.open .nav__burger span:nth-child(2) { opacity: 0; }
.nav.open .nav__burger span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* ===== SECTION HEAD (ghost numeral + editorial title) ===== */
.section-head { position: relative; padding: var(--section-y) 0 var(--space-lg); }
.section-head__ghost {
  position: absolute; top: 40px; left: -12px;
  font-family: var(--font-display); font-weight: 900;
  font-size: clamp(180px, 22vw, 320px); line-height: 0.85;
  color: transparent; -webkit-text-stroke: 1.5px var(--line-2);
  pointer-events: none; user-select: none; z-index: 0;
  letter-spacing: -0.04em;
}
.section-head__inner { position: relative; z-index: 1; display: flex; justify-content: space-between; align-items: flex-end; gap: 40px; flex-wrap: wrap; }
.section-head h2 {
  font-size: clamp(44px, 6vw, 92px); font-weight: 800;
  letter-spacing: -0.03em; line-height: 0.95;
  margin-top: 16px; text-wrap: balance;
  text-transform: uppercase;
}
.section-head h2 em { font-style: normal; color: var(--gold); font-weight: 300; letter-spacing: -0.02em; }
.section-head__meta {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--ink-dim);
  display: flex; align-items: center; gap: 10px;
}
.section-head__meta::before {
  content: '';
  width: 16px; height: 16px;
  background: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23EC6331'%3E%3Cpath d='M6 3h3v4h6V3h3v8h1v2h-1v8h-3v-4H9v4H6v-8H5v-2h1V3zm-4 7h2v4H2v-4zm18 0h2v4h-2v-4z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* ===== PAGE HERO (subpage banner) ===== */
.page-hero {
  position: relative;
  padding: calc(var(--nav-h) + 90px) 0 90px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.page-hero--tall {
  padding-top: calc(var(--nav-h) + var(--section-y-lg));
  padding-bottom: var(--section-y-lg);
  isolation: isolate;
}
.page-hero--tall::before {
  content: ''; position: absolute; inset: 0;
  background-image: var(--page-hero-image, url('../images/man-dumbbells.webp'));
  background-size: cover; background-position: center;
  filter: grayscale(0.35) brightness(0.35) contrast(1.05);
  z-index: -2;
}
.page-hero--tall::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, var(--bg) 0%, rgba(10,10,10,0.7) 20%, rgba(10,10,10,0.7) 80%, var(--bg) 100%),
    radial-gradient(ellipse at 80% 40%, rgba(var(--accent-rgb), 0.2), transparent 55%);
  z-index: -1;
}
.page-hero__grid {
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line) 1px, transparent 1px);
  background-size: 120px 120px;
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  opacity: 0.6;
}
.page-hero__glow {
  position: absolute; top: 40%; right: 8%;
  width: 420px; height: 420px;
  background: radial-gradient(circle, rgba(var(--accent-rgb), 0.15), transparent 65%);
  pointer-events: none;
}
.page-hero__inner { position: relative; z-index: 1; }
.page-hero__ghost {
  position: absolute; top: -30px; left: -12px;
  font-family: var(--font-display); font-weight: 900;
  font-size: clamp(180px, 22vw, 320px); line-height: 0.85;
  color: transparent; -webkit-text-stroke: 1.5px var(--line-2);
  pointer-events: none; user-select: none;
  letter-spacing: -0.04em;
}
.page-hero__eyebrow { margin-bottom: 20px; position: relative; z-index: 1; }
.page-hero__title {
  position: relative; z-index: 1;
  font-size: clamp(48px, 7.5vw, 120px); font-weight: 900;
  letter-spacing: -0.045em; line-height: 0.92;
  text-transform: uppercase;
  max-width: 14ch;
}
.page-hero__title em { font-style: normal; color: var(--gold); font-weight: 300; }
.page-hero__desc {
  position: relative; z-index: 1;
  margin-top: 28px; max-width: 640px;
  font-size: clamp(15px, 1.3vw, 18px); line-height: 1.6;
  color: var(--ink-dim);
}
.page-hero__cta { position: relative; z-index: 1; margin-top: 32px; }
.page-hero__crumbs {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 10px;
  font-family: var(--font-mono); font-size: 10px;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-mute);
  margin-bottom: 28px;
}
.page-hero__crumbs a { color: var(--ink-mute); transition: color 0.2s; }
.page-hero__crumbs a:hover { color: var(--gold); }
.page-hero__crumbs span.sep { color: var(--line-2); }

.page-section { padding: var(--section-y) 0; background: var(--bg); }
.page-section--alt { background: var(--bg-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }

/* ===== LEGAL PAGES (privacy / terms / customer-protection) ===== */
.legal { padding: var(--section-y) 0 var(--section-y-lg); background: var(--bg); }
.legal__inner { max-width: 820px; }
.legal__section { padding: 28px 0; border-bottom: 1px solid var(--line); }
.legal__section:last-of-type { border-bottom: 0; }
.legal__h {
  font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--gold);
  margin: 0 0 14px;
}
.legal__p {
  font-size: 16px; line-height: 1.75; color: var(--ink-dim); margin: 0;
}
.legal__updated {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--ink-mute); margin-top: 32px;
}

/* ===== FOOTER ===== */
.footer { background: var(--bg); padding: var(--space-2xl) 0 var(--space-lg); border-top: 1px solid var(--line); }
.footer__grid {
  display: grid; grid-template-columns: 1.2fr 1fr 1fr 1fr 1.2fr;
  gap: 40px;
}
.footer__brand { display: flex; flex-direction: column; gap: 24px; }
.footer__brand img.logo { height: 30px; width: auto; }
.footer__brand img.cert { max-width: 120px; height: auto; opacity: 0.8; }
.footer__col h4,
.footer__col-title {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.25em;
  color: var(--gold); text-transform: uppercase;
  margin: 0 0 20px;
  font-weight: 600;
}
.footer__col ul { list-style: none; display: flex; flex-direction: column; gap: 12px; }
.footer__col a {
  font-size: 13px; color: var(--ink-dim);
  transition: color 0.2s;
}
.footer__col a:hover { color: var(--ink); }
.footer__col--right { display: flex; flex-direction: column; gap: 20px; }
.footer__apps { display: flex; gap: 10px; }
.footer__apps img { height: 36px; width: auto; }
.footer__social { display: flex; gap: 10px; }
.footer__social a {
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 1px solid var(--line-2); color: var(--ink-dim);
  transition: all 0.2s;
}
.footer__social a:hover { border-color: var(--gold); color: var(--gold); transform: translateY(-2px); }
.footer__social svg { width: 14px; height: 14px; }

/* ===== BOTTOM BAR ===== */
.bottom-bar { background: var(--bg-2); border-top: 1px solid var(--line); padding: 18px 0; }
.bottom-bar__inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.bottom-bar__payments { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.bottom-bar__payments img {
  height: 22px; width: auto;
  opacity: 0.7;
  filter: grayscale(0.3);
  transition: opacity 0.2s, filter 0.2s;
}
.bottom-bar__payments img:hover { opacity: 1; filter: grayscale(0); }
.bottom-bar__copy {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.18em;
  color: var(--ink-dim); text-transform: uppercase;
}

/* ===== COOKIE NOTICE ===== */
.cookie {
  position: fixed; left: 20px; right: 20px; bottom: 20px; z-index: 200;
  max-width: 640px; margin: 0 auto;
  padding: 18px 22px;
  background: rgba(20,20,20,0.92); backdrop-filter: blur(14px);
  border: 1px solid var(--line-2);
  display: flex; gap: 20px; align-items: center;
  transform: translateY(200%); transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.cookie.show { transform: translateY(0); }
.cookie p { font-size: 13px; color: var(--ink-dim); line-height: 1.5; flex: 1; }
.cookie__actions { display: flex; gap: 10px; flex-shrink: 0; }

/* ===== CTA BANNER (shared between several subpages) ===== */
.page-cta {
  position: relative;
  padding: var(--section-y) 0;
  background: linear-gradient(135deg, #141414 0%, #080808 100%);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.page-cta::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 80% 50%, rgba(var(--accent-rgb), 0.15), transparent 60%);
}
.page-cta__inner {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1.3fr 1fr; gap: 48px; align-items: center;
}
.page-cta__heading {
  font-size: clamp(36px, 5vw, 72px); font-weight: 900;
  letter-spacing: -0.035em; line-height: 0.95; text-transform: uppercase;
}
.page-cta__heading em { font-style: normal; color: var(--gold); font-weight: 300; }
.page-cta__desc { margin-top: 20px; color: var(--ink-dim); font-size: 16px; line-height: 1.6; max-width: 520px; }
.page-cta__actions { display: flex; gap: 14px; flex-wrap: wrap; justify-content: flex-end; }

/* ===== FACILITIES ===== */
.facilities { padding-bottom: var(--space-2xl); background: var(--bg); }
.facilities__grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 20px; margin-top: 48px;
}
.facility-card {
  position: relative; aspect-ratio: 3/4; overflow: hidden;
  background: #1a1a1a;
  cursor: pointer;
  transition: transform 0.4s;
}
.facility-card:hover { transform: translateY(-4px); }
.facility-card__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(0.25) brightness(0.7);
  transition: filter 0.4s, transform 0.6s;
}
.facility-card:hover .facility-card__img { filter: grayscale(0) brightness(0.8); transform: scale(1.04); }
.facility-card::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 40%, rgba(10,10,10,0.92) 100%);
}
.facility-card__label {
  position: absolute; bottom: 24px; left: 24px; right: 24px; z-index: 2;
  font-weight: 800; font-size: 20px; text-transform: uppercase; letter-spacing: -0.01em;
  line-height: 1.1;
}
.facility-card__num {
  position: absolute; top: 20px; left: 24px; z-index: 2;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em;
  color: var(--ink-dim);
}

/* ===== STEP VIDEO SECTION ===== */
.step-video {
  position: relative; height: 68vh; min-height: 520px;
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.step-video__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  filter: brightness(0.45) contrast(1.1) saturate(0.8);
}
.step-video__grade {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse at center, transparent 0%, rgba(10,10,10,0.55) 60%, var(--bg) 100%),
    linear-gradient(120deg, rgba(var(--accent-rgb), 0.08), transparent 60%);
}
.step-video__content {
  position: relative; z-index: 2; height: 100%;
  display: flex; flex-direction: column; justify-content: center;
  padding: 0 48px; max-width: 1400px; margin: 0 auto;
}
.step-video__eyebrow { margin-bottom: 24px; }
.step-video__title {
  font-size: clamp(52px, 7.5vw, 120px); font-weight: 900; line-height: 0.9;
  letter-spacing: -0.04em; text-transform: uppercase; max-width: 12ch;
}
.step-video__title em { font-style: normal; color: var(--gold); }

/* ===== ABOUT =====
   demo_3 wraps row + stats + facilities in ONE <section class="about">; the
   block theme splits them across THREE sections (row | stat-counter block |
   facilities). flow-root contains the inner margin-top values (64px on
   .about__stats, 88px on .about__facilities) so they stay inside the bg-2
   region instead of escaping into the body bg between sections. */
.about { background: var(--bg-2); padding: var(--section-y) 0 var(--section-y-lg); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); display: flow-root; }
.about__row { display: grid; grid-template-columns: 1fr 1.2fr; gap: var(--space-lg); margin-top: var(--space-lg); align-items: start; }
.about__photo { position: relative; aspect-ratio: 4/5; overflow: hidden; border: 1px solid var(--line); }
.about__photo img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(0.4) brightness(0.8) contrast(1.1); }
.about__photo::after { content: ''; position: absolute; inset: 0; background: linear-gradient(210deg, transparent 55%, rgba(10,10,10,0.6)); }
.about__body { display: flex; flex-direction: column; gap: var(--space-sm); }
.about__heading { font-size: clamp(38px, 4.2vw, 64px); font-weight: 800; letter-spacing: -0.03em; line-height: 0.95; text-transform: uppercase; }
.about__heading em { font-style: normal; color: var(--gold); }
.about__desc { font-size: 16px; line-height: 1.65; color: var(--ink-dim); max-width: 620px; }
.about__stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; margin-top: var(--space-xl); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.stat { padding: var(--space-md) var(--space-sm); border-right: 1px solid var(--line); }
.stat:last-child { border-right: 0; }
.stat__num {
  font-size: 54px; font-weight: 900; letter-spacing: -0.03em;
  line-height: 1;
  color: var(--ink);
}
.stat__num .plus { color: var(--ink-mute); font-weight: 400; }
.stat__label {
  display: block; margin-top: 10px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.22em;
  color: var(--ink-mute); text-transform: uppercase;
}

/* About: gold-accent facilities strip (header + icon-card grid + CTA). */
.about__facilities {
  margin-top: 88px;
  position: relative;
  padding: var(--space-lg);
  background: linear-gradient(180deg, var(--bg-3) 0%, var(--bg-2) 100%);
  border: 1px solid var(--line);
  overflow: hidden;
}
.about__facilities::before {
  content: '';
  position: absolute; top: -80px; right: -80px;
  width: 340px; height: 340px;
  background: radial-gradient(circle, rgba(var(--accent-rgb), 0.12), transparent 65%);
  pointer-events: none;
}
.about__fac-head {
  display: grid; grid-template-columns: 1fr auto; gap: 20px;
  align-items: end;
  margin-bottom: 36px;
  padding-bottom: 24px; border-bottom: 1px solid var(--line);
  position: relative; z-index: 1;
}
.about__fac-title {
  font-size: clamp(26px, 2.8vw, 40px); font-weight: 800;
  line-height: 1.1; letter-spacing: -0.02em; max-width: 18ch;
  text-transform: uppercase;
}
.about__fac-title em { font-style: normal; color: var(--gold); font-weight: 300; }
.about__fac-count {
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: 0.25em; color: var(--ink-mute);
  text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 10px;
  white-space: nowrap;
}
.about__fac-count strong { color: var(--gold); font-weight: 700; font-size: 14px; }
.about__fac-list {
  list-style: none;
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  position: relative; z-index: 1;
}
.about__fac-list li {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 18px 18px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-2);
  font-size: 13.5px; color: var(--ink); line-height: 1.45;
  transition: border-color 0.25s, transform 0.25s, background 0.25s;
}
.about__fac-list li:hover { transform: translateY(-2px); border-color: rgba(var(--accent-rgb), 0.35); border-left-color: var(--accent); background: var(--bg-3); }
.about__fac-list li::before {
  content: '';
  flex: 0 0 auto;
  width: 24px; height: 24px; margin-top: 1px;
  background: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23EC6331'%3E%3Cpath d='M6 3h3v4h6V3h3v8h1v2h-1v8h-3v-4H9v4H6v-8H5v-2h1V3zm-4 7h2v4H2v-4zm18 0h2v4h-2v-4z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.about__fac-list li:nth-child(3n+2)::before {
  background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23EC6331'%3E%3Cpath d='M10 2h4c1.1 0 2 .9 2 2 0 .9-.4 1.6-.9 2.2 2.3 1.4 3.9 4 3.9 6.8 0 4.4-3.6 8-8 8s-8-3.6-8-8c0-2.8 1.6-5.4 3.9-6.8C6.4 5.6 6 4.9 6 4c0-1.1.9-2 2-2h2zm4 2.5h-4c-.3 0-.5.2-.5.5s.2.5.5.5h4c.3 0 .5-.2.5-.5s-.2-.5-.5-.5z'/%3E%3C/svg%3E");
}
.about__fac-list li:nth-child(3n)::before {
  background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23EC6331'%3E%3Cpath d='M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 4a6 6 0 110 12 6 6 0 010-12zm0 3.5a2.5 2.5 0 100 5 2.5 2.5 0 000-5z'/%3E%3C/svg%3E");
}
.about__fac-cta {
  margin-top: 32px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
  padding: 22px 28px;
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.12), rgba(var(--accent-rgb), 0.02));
  border: 1px solid rgba(var(--accent-rgb), 0.28);
  position: relative; z-index: 1;
}
.about__fac-cta-text {
  font-size: 15px; color: var(--ink); line-height: 1.45;
  max-width: 68ch;
}
.about__fac-cta-text strong { color: var(--gold); font-weight: 700; }
.about__fac-cta .btn { flex-shrink: 0; }

/* ===== MARQUEE — truly infinite loop =====
   Track holds N identical copies of the item sequence. Each child (word or
   icon) owns its own margin-right, so every set's width is uniform.
   site.js clones more sets at runtime until track_width ≥ viewport + set_width,
   then sets `--marquee-shift` to exactly one set's width in px. The keyframe
   translates by that pixel amount, so the wrap-around is seamless AND the
   viewport always stays filled — no empty gap after the last item. */
.marquee {
  padding: var(--space-xs) 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  overflow: hidden; background: var(--bg);
}
.marquee__track {
  display: flex; align-items: center;
  width: max-content;
  animation: ticker 32s linear infinite;
  white-space: nowrap;
}
.marquee__word {
  font-size: clamp(20px, 2.4vw, 36px); font-weight: 900; letter-spacing: -0.02em;
  text-transform: uppercase;
  margin-right: 32px;
  flex: 0 0 auto;
  line-height: 1;
}
.marquee__word.outline { color: transparent; -webkit-text-stroke: 1px var(--ink); }
.marquee__word.fill    { color: var(--ink); }
.marquee__word.gold    { color: var(--gold); }
.marquee__icon {
  width: 36px; height: 36px; object-fit: contain;
  margin-right: 32px; flex: 0 0 auto;
}
@keyframes ticker {
  from { transform: translateX(0); }
  to   { transform: translateX(var(--marquee-shift, -50%)); }
}

/* Reusable "gym-dot" — mini gym icon replacement for diamond bullets.
   Attach as ::before via .gym-dot on any inline container, or use the
   .gym-icon class on a span that should render a kettlebell / plate variant. */
.gym-dot::before {
  content: '';
  display: inline-block;
  width: 14px; height: 14px; vertical-align: middle;
  margin-right: 8px;
  background: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23EC6331'%3E%3Cpath d='M6 3h3v4h6V3h3v8h1v2h-1v8h-3v-4H9v4H6v-8H5v-2h1V3zm-4 7h2v4H2v-4zm18 0h2v4h-2v-4z'/%3E%3C/svg%3E") center / contain no-repeat;
}
body.rtl .gym-dot::before { margin-right: 0; margin-left: 8px; }

/* ===== RESPONSIVE (shared) ===== */
@media (max-width: 960px) {
  .container, .nav__inner { padding-left: 24px; padding-right: 24px; }
  .nav__links { display: none; }
  .nav__cta .btn--ghost { display: none; }
  .nav__burger { display: flex; }
  .nav.open .nav__links {
    display: flex; flex-direction: column; gap: 0;
    position: absolute; top: var(--nav-h); left: 0; right: 0;
    background: rgba(10,10,10,0.98); padding: 20px 24px;
    border-bottom: 1px solid var(--line);
  }
  .nav.open .nav__links a { padding: 14px 0; border-bottom: 1px solid var(--line); }
  /* Mobile language-toggle clone injected by site.js: sits at the bottom
     of the burger menu as a pill, separate from the plain nav links. */
  .nav__lang-mobile {
    display: inline-flex !important;
    margin-top: 16px; padding: 10px 18px !important;
    border: 1px solid var(--line-2) !important;
    background: transparent !important;
    color: var(--ink) !important;
    align-self: flex-start;
    border-bottom: 1px solid var(--line-2) !important;
  }
  .footer__grid { grid-template-columns: 1fr 1fr; }
  .page-cta__inner { grid-template-columns: 1fr; }
  .page-cta__actions { justify-content: flex-start; }
  .bottom-bar__inner { justify-content: center; text-align: center; }
  .cookie { flex-direction: column; align-items: stretch; }
  .facilities__grid { grid-template-columns: repeat(2, 1fr); }
  .about__row { grid-template-columns: 1fr; }
  .about__stats { grid-template-columns: repeat(2, 1fr); }
  .stat:nth-child(2) { border-right: 0; }
  .about__facilities { padding: 32px 24px; }
  .about__fac-list { grid-template-columns: 1fr 1fr; }
  .about__fac-head { grid-template-columns: 1fr; }
  .app-cta__inner { grid-template-columns: 1fr; text-align: center; }
  .app-cta__badges { justify-content: center; }
}
@media (max-width: 560px) {
  .footer__grid { grid-template-columns: 1fr; }
  .facilities__grid { grid-template-columns: 1fr; }
  .about__stats { grid-template-columns: 1fr; }
  .stat { border-right: 0; border-bottom: 1px solid var(--line); }
  .about__fac-list { grid-template-columns: 1fr; }
  .about__fac-cta { flex-direction: column; align-items: flex-start; }
}

/* Mobile language-toggle clone: hidden by default (desktop). The
   @media (max-width: 960px) block above flips it to inline-flex.
   Selector chained through .nav__links to out-specific inline
   .btn { display: inline-flex } rules that load after this file. */
.nav__links .nav__lang-mobile,
.nav .nav__lang-mobile { display: none !important; }
@media (max-width: 960px) {
  .nav__links .nav__lang-mobile,
  .nav .nav__lang-mobile { display: inline-flex !important; }
}

/* ===== ARABIC / RTL ============================================
   body.rtl flips direction and swaps the primary font to Noto Sans
   Arabic. Display face (Archivo) remains for headings in Latin
   scripts; Arabic headings use Tajawal's heavier
   weights. Individual components that rely on physical direction
   (ghost numerals, section heads, footer grid) get explicit
   overrides below. */
body.rtl {
  direction: rtl;
  font-family: var(--font-arabic);

  /* Website Review 2026-07-29, section 5, bug 3 — "Group classes page renders
     as mirrored/garbled text rather than legible Arabic strings."

     Cause: JetBrains Mono and Archivo contain NO Arabic glyphs. Any Arabic in
     an element using them falls back to a system font — on Windows that is
     Courier New, which draws Arabic with broken, disconnected letterforms.
     Confirmed via Chrome's own font reporting:

       .class-card__num  →  JetBrains Mono (5 glyphs) | Courier New (8 glyphs)
       .class-card__tag  →  JetBrains Mono (4 glyphs) | Courier New (3 glyphs)

     An audit across 8 Arabic pages found 21 affected elements, not the 2 in the
     review — plan CTAs, city/FAQ/segment tabs, the contact submit button, map
     pin labels and more.

     Fixing the TOKENS rather than listing selectors means Latin and digits keep
     their intended face while Arabic resolves to Tajawal, and any element added
     later is covered automatically. */
  --font-mono:    'JetBrains Mono', var(--font-arabic), ui-monospace, monospace;
  --font-display: 'Archivo', var(--font-arabic), system-ui, sans-serif;
}
body.rtl .eyebrow,
body.rtl .page-hero__crumbs,
body.rtl .section-head__meta,
body.rtl .btn,
body.rtl .nav__links a,
body.rtl .stat__label,
body.rtl .footer__col h4,
body.rtl .footer__col-title,
body.rtl .bottom-bar__copy {
  /* Keep the monospace label rhythm; Tajawal handles
     Arabic glyphs while JetBrains Mono renders Latin numerals. */
  font-family: var(--font-arabic), var(--font-mono);
}

/* Arabic nav link sizing: Tajawal at 11px reads too tight against
   JetBrains Mono Latin at the same size — bump to 14px for legibility. */
body.rtl .nav__links a {
  font-size: 14px;
  letter-spacing: 0.04em;
}
/* Arabic headings: face + tracking only.
   The weight ladder (900 hero / 800 section / 700 card / 400 body) is NOT set
   here — it lives in the base styles and theme.json so both languages inherit
   one scale. Duplicating it per-direction is what let English and Arabic drift
   apart in the first place. */
body.rtl h1, body.rtl h2, body.rtl h3, body.rtl h4,
body.rtl .page-hero__title,
body.rtl .section-head h2,
body.rtl .hero__title,
body.rtl .page-cta__heading,
body.rtl .amenities__title,
body.rtl .plan__duration {
  font-family: var(--font-arabic);

  /* Arabic is cursive: adjacent letters join along a shared baseline stroke.
     theme.json applies Latin display tracking to headings (h1 -0.04em ≈
     -3.24px at hero size), which pulls glyphs off their join points and
     visually breaks each word into detached letters. Latin tracking is
     meaningless here regardless — reset it.
     The same fix was already applied to eyebrow/label text in the 2026-07-19
     Arabic review; headings were missed because Noto Sans Arabic's longer
     connectors masked the damage. Tajawal's shorter joins expose it. */
  letter-spacing: normal;
}

/* Tajawal ships no 600 weight (200/300/400/500/700/800/900). These active
   states asked for 600; left alone the browser would silently pick 500 or 700
   per-platform. Pin them to 700 so the emphasis is deliberate and identical
   everywhere. */
body.rtl .faq-cat-tab.active,
body.rtl .city-tab.active,
body.rtl .locations__tab.active,
body.rtl .pill.active,
body.rtl .plan__cta:hover,
body.rtl .faq__q,
body.rtl .contact-info__value,
/* Added 2026-08-08 (A6): the footer column headings are in2fitness-authored
   Arabic text that was resolving to a browser-picked weight. The three primary
   submit buttons are deliberately NOT here — .proceed / .summary__cta /
   .contact-form__submit were dropped to weight 500, which Tajawal does ship
   (inc/enqueue.php loads 300;400;500;700;800;900), and 500 is the weight .btn
   actually specifies. Fixing the weight beats remapping it.
   .step__num stays at 600: it renders "01"-"04" in JetBrains Mono, which has a
   real 600. */
body.rtl .footer__col h4,
body.rtl .footer__col-title,
body.rtl .summary__row strong { font-weight: 700; }

/* Flip ghost numerals to the right edge in RTL */
body.rtl .page-hero__ghost,
body.rtl .section-head__ghost {
  left: auto;
  right: -12px;
}

/* Page-hero crumbs: arrow separators still read naturally */
body.rtl .page-hero__crumbs .sep { transform: scaleX(-1); display: inline-block; }

/* Section head: swap side-by-side to mirrored alignment */
body.rtl .section-head__inner { direction: rtl; }
body.rtl .section-head__meta::before {
  /* the gold diamond marker sits before text in LTR; in RTL it
     should still visually precede the text, which means "after"
     in source order relative to flex direction */
  /* flexbox already mirrors via direction: rtl, no change needed */
}

/* Nav: .nav__inner is a flex row; direction: rtl swaps logo/links/
   CTA automatically. We just need to keep the burger on the
   trailing edge on mobile. */
body.rtl .nav__links a.active::after { /* underline stays centered */ }

/* Hero kicker line on the main rebuild — flip so line sits on the
   near edge of the text */
body.rtl .hero__kicker { flex-direction: row-reverse; }

/* Footer: keep grid columns but right-align text */
body.rtl .footer__col { text-align: right; }
body.rtl .footer__col--right { align-items: flex-end; }
body.rtl .footer__brand { align-items: flex-end; }
body.rtl .footer__social { direction: ltr; }  /* keep icon order */
body.rtl .footer__apps { direction: ltr; }

/* Bottom bar: payments row stays LTR for consistent icon reading */
body.rtl .bottom-bar__payments { direction: ltr; }

/* Plan card list bullets — flip the short hairline to the right */
body.rtl .plan__features li { padding-left: 0; padding-right: 20px; }
body.rtl .plan__features li::before { left: auto; right: 0; }

/* About / amenities grids with right-side borders — swap */
body.rtl .stat { border-right: 0; border-left: 1px solid var(--line); }
body.rtl .stat:last-child { border-left: 0; }
body.rtl .amenity { border-right: 0; border-left: 1px solid var(--line); }
body.rtl .amenity:nth-child(3n) { border-left: 0; }

/* Locations page: keep map LTR (pins are absolutely-positioned by
   explicit coords; RTL would otherwise flip them). Panel content
   flips to RTL naturally. */
body.rtl .locations__map,
body.rtl .ksa-map-inline,
body.rtl #pins,
body.rtl .pin,
body.rtl .pin__label,
body.rtl .marquee__track { direction: ltr; }
body.rtl .branch { direction: rtl; }
body.rtl .branch__hours,
body.rtl .branch__link { font-family: var(--font-arabic), var(--font-mono); }

/* Forms: right-align text but keep numeric/tel fields LTR */
body.rtl .field input,
body.rtl .field select,
body.rtl .field textarea { text-align: right; }
/* Email/date keep LTR digits but stay aligned to the start of the line in
   RTL (= right edge). Tel mirrors that and additionally right-aligns its
   placeholder so "5XXXXXXXX" sits next to the country code. */
body.rtl .field input[type="email"],
body.rtl .field input[type="tel"],
body.rtl .field input[type="date"] { direction: ltr; text-align: right; }
body.rtl .field input[type="tel"]::placeholder { text-align: right; direction: ltr; }

/* FAQ accordion — the "+" glyph sits on the opposite side */
body.rtl .faq__q { direction: rtl; }

/* Saudi Riyal symbol (the new SAMA-designed glyph from 2025). The font ships
   the symbol on Unicode U+00EA so we render it via `<span class="riyal-icon">ê</span>`
   — the literal "ê" gets replaced by the glyph at draw time and falls back
   to the body font (still legible) if the file fails to load.
   Source: github.com/abdulrysrr/new-saudi-riyal-symbol */
@font-face {
  font-family: 'SaudiRiyalSymbol';
  src: url('../fonts/saudiriyalsymbol.woff2') format('woff2'),
       url('../fonts/saudiriyalsymbol.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}
.riyal-icon {
  font-family: 'SaudiRiyalSymbol', var(--font-arabic);
  font-style: normal;
  font-weight: inherit;
  display: inline-block;
  line-height: 1;
}

/* Join-Now wizard steps: the head bar's text-align is hardcoded to left in
   the LTR base rule, so the AR step title sat on the left. Mirror to right,
   match the typography of .summary__title for visual parity in AR, and flip
   the meta margin so it stays opposite the title in RTL. */
body.rtl .step__head { text-align: right; }
body.rtl .step__title {
  text-align: right;
  font-family: var(--font-arabic);
  /* The comment above says this exists to "match the typography of
     .summary__title for visual parity in AR". .summary__title is 18px — 16px
     was never parity, and it inverted the hierarchy: in Arabic the wizard's
     own step titles rendered SMALLER than the sidebar panel title, while in
     English they are larger (20 vs 18). Honour the stated intent. */
  font-size: var(--fs-title-sm);
  letter-spacing: normal;  /* Arabic is cursive — no Latin tracking */
}
body.rtl .step__meta { margin-right: 0; margin-left: 14px; }

/* --- Brand + Arabic review (2026-07-19), finding #1 -------------------------
   The join UI styles labels / buttons / meta in the Latin mono face
   (JetBrains Mono) with Latin letter-spacing. Arabic has no glyphs in that
   face — so it fell back to a system monospace — and the tracking broke
   Arabic's cursive letter-joins (letters rendered visibly detached). In RTL,
   render these UI strings in the Arabic brand face and drop the tracking.
   Latin data values (city / plan names, prices, step numbers) keep their own
   class styles and are intentionally untouched.

   Extended 2026-08-08 (meeting item A6): the 2026-07-19 audit was taken on
   steps 1-3 and the summary panel. It never covered step 4 (payment methods),
   the branch-card meta added afterwards, or the plan-card CTA. The split
   between this list and the ARABIC LABEL TRACKING list at the foot of the file
   is deliberate and reproducible: an element whose content is always
   in2fitness UI copy belongs HERE (whole element in the Arabic face); an
   element that carries DATA — city or plan names, distances, payment-brand
   names — gets tracking-only treatment there, because body.rtl's --font-mono
   redefinition above already resolves its Arabic run to Tajawal per glyph
   while leaving the Latin run on JetBrains Mono. */
body.rtl .pay-opt__sub,
body.rtl .pay-opt__soon,
body.rtl .pay-logos__label,
body.rtl .nearest-toggle,
body.rtl .plan-opt__cta,
body.rtl .sub-label,
body.rtl .join label,
body.rtl .gender-card__title,
body.rtl .gender-card__desc,
body.rtl .hint,
body.rtl .terms-read,
body.rtl .terms-modal__title,
body.rtl .proceed,
body.rtl .proceed-hint,
body.rtl .summary__title,
body.rtl .summary__cta,
body.rtl .summary__ssl,
body.rtl .summary__ssl *,
body.rtl .summary__freeze,
body.rtl .summary__note,
body.rtl .summary__error {
  font-family: var(--font-arabic);
  letter-spacing: normal;
}

/* --- Brand + Arabic review (2026-07-19), findings #2 & #3 -------------------
   Latin data that contains digits reorders under the RTL bidi algorithm:
   a plan name authored "6 Impact" rendered "Impact 6", and the dial code
   "+966" rendered "966+". Isolate each as its own LTR run so the token order
   is preserved. Pure-word Latin (branch/city names) already renders correctly
   as a single LTR run and is left alone. */
body.rtl .plan-opt__name    { direction: ltr; unicode-bidi: isolate; text-align: right; }
body.rtl .summary__row strong { direction: ltr; unicode-bidi: isolate; }
body.rtl .cc-picker__dial   { direction: ltr; unicode-bidi: isolate; }

/* --- Brand + Arabic review (2026-07-19), finding #4 -------------------------
   The plan card's secondary caption (.plan-opt__sub — the plan's short text)
   reordered the same way the name did, so after fixing the name the card read
   "6 IMPACT" on top but "Impact 6" below it. Isolate the caption to match. */
body.rtl .plan-opt__sub     { direction: ltr; unicode-bidi: isolate; text-align: right; }

/* --- Brand + Arabic review (2026-07-19), finding #5 -------------------------
   The collapsed-step meta (.step__meta) echoes the step's selection. For the
   plan step that is a digit-led Latin name that reordered ("IMPACT 6") —
   inconsistent with the "6 IMPACT" card. `plaintext` resolves each meta by its
   own content: the (English) plan name renders LTR ("6 IMPACT"), while the
   step-1 breadcrumb (city · segment · branch) still reads naturally with the
   Arabic segment embedded. */
body.rtl .step__meta { unicode-bidi: plaintext; }

/* Cookie banner arrangement */
body.rtl .cookie__actions { direction: rtl; }
body.rtl .cookie { direction: rtl; }

/* In RTL, the language-toggle label is "English" — swap back to the
   display font so the Latin word doesn't render in Tajawal. */
body.rtl .btn[data-lang-toggle],
body.rtl a[data-lang-toggle],
body.rtl [data-lang-toggle] {
  font-family: var(--font-display), sans-serif;
  font-weight: 400;
  font-size: 14px;
  letter-spacing: 0.08em;
}

/* ===== SEAMLESS GOLD SCROLLBAR (shared) =====
   Used on scrollable panels (Locations list, any tall overflow-y area) so the
   default browser scrollbar blends into the dark theme with a gold thumb. */
.scroll-gold {
  scrollbar-width: thin;
  scrollbar-color: var(--gold) transparent;
}
.scroll-gold::-webkit-scrollbar { width: 6px; height: 6px; }
.scroll-gold::-webkit-scrollbar-track { background: transparent; }
.scroll-gold::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--gold), var(--gold-deep));
  border-radius: 999px;
}
.scroll-gold::-webkit-scrollbar-thumb:hover { background: #fff; }

/* ===== GLOBAL PAGE SCROLLBAR =====
   Replaces the OS default (light grey on dark bg) with a theme-consistent
   gold-on-near-black scrollbar so the page chrome matches the editorial dark
   palette. Firefox uses scrollbar-* properties; WebKit/Blink use ::-webkit-*. */
html {
  scrollbar-width: auto;
  scrollbar-color: var(--gold) var(--bg-2);
}
html::-webkit-scrollbar { width: 16px; height: 16px; }
html::-webkit-scrollbar-track {
  background: var(--bg-2);
  border-left: 1px solid var(--line);
}
html::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--gold), var(--gold-deep));
  border-radius: 999px;
  border: 3px solid var(--bg-2);
}
html::-webkit-scrollbar-thumb:hover { background: #fff; }
html::-webkit-scrollbar-corner { background: var(--bg-2); }

/* ===== SLIDER EDGE ARROWS (reusable legacy placement) =====
   Vertically-centred circular prev/next buttons on the left/right edge of a
   slider — matches the original in2fitness.sa site and the previous demo_1. */
.edge-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 48px; height: 48px; border-radius: 50%;
  background: rgba(10,10,10,0.45);
  border: 1px solid var(--line-2);
  color: var(--ink);
  display: grid; place-items: center; cursor: pointer;
  z-index: 5;
  transition: background 0.2s, border-color 0.2s, color 0.2s, transform 0.2s;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.edge-arrow:hover { background: var(--gold); border-color: var(--gold); color: var(--on-accent); }
.edge-arrow svg { width: 18px; height: 18px; }
.edge-arrow--prev { left: 20px; }
.edge-arrow--next { right: 20px; }
body.rtl .edge-arrow--prev { left: auto; right: 20px; }
body.rtl .edge-arrow--next { right: auto; left: 20px; }
body.rtl .edge-arrow svg { transform: scaleX(-1); }
@media (max-width: 640px) {
  .edge-arrow { width: 40px; height: 40px; }
  .edge-arrow--prev { left: 10px; }
  .edge-arrow--next { right: 10px; }
  body.rtl .edge-arrow--prev { right: 10px; }
  body.rtl .edge-arrow--next { left: 10px; }
}

/* =============================================================
   PHASE 2 — page-specific styles (gx-classes, personal-training,
   faqs, contact). Lifted from each demo_3 page's inline <style>.
   ============================================================= */

/* ---------- GX Classes ---------- */
.classes__intro { margin-top: 20px; max-width: 760px; color: var(--ink-dim); font-size: 16px; line-height: 1.6; }
.classes__intro em { font-style: normal; color: var(--gold); }
.classes__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 56px; }
.class-card {
  padding: 180px 24px 32px;
  background: var(--bg-2); border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 14px;
  transition: transform 0.35s, border-color 0.35s, background 0.35s;
  position: relative;
  overflow: hidden;
  min-height: 460px;
  isolation: isolate;
}
.class-card:hover { transform: translateY(-4px); border-color: rgba(var(--accent-rgb), 0.35); }
.class-card::before {
  content: '';
  position: absolute; inset: 0;
  background-image: var(--card-bg, url('../images/facility-strength.webp'));
  background-size: cover; background-position: center;
  filter: grayscale(0.4) brightness(0.5) contrast(1.05);
  transition: filter 0.45s, transform 0.6s;
  z-index: -2;
}
.class-card::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,10,10,0.25) 0%, rgba(10,10,10,0.75) 55%, rgba(10,10,10,0.95) 100%);
  z-index: -1;
}
.class-card:hover::before { filter: grayscale(0) brightness(0.6) contrast(1.1); transform: scale(1.05); }
.class-card__num   { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.25em; color: var(--ink-dim); position: relative; z-index: 1; }
.class-card__name  { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; text-transform: uppercase; line-height: 1; position: relative; z-index: 1; color: var(--ink); text-shadow: 0 2px 24px rgba(0,0,0,0.6); }
.class-card__desc  { color: var(--ink-dim); font-size: 13px; line-height: 1.55; position: relative; z-index: 1; }
.class-card__list  { display: flex; flex-wrap: wrap; gap: 8px; margin-top: auto; padding-top: 8px; position: relative; z-index: 1; }
.class-card__tag {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.15em;
  padding: 5px 10px; border: 1px solid rgba(244,241,234,0.25);
  color: var(--ink); text-transform: uppercase;
  background: rgba(10,10,10,0.55); backdrop-filter: blur(6px);
}

.why__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; margin-top: 48px; }
.why-card { padding: 32px 28px; background: var(--bg-3); border-left: 2px solid var(--gold); }
.why-card__num   { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.25em; color: var(--gold); }
.why-card__title { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; margin-top: 14px; text-transform: uppercase; line-height: 1.1; }
.why-card__desc  { color: var(--ink-dim); font-size: 13px; line-height: 1.55; margin-top: 12px; }

@media (max-width: 960px) { .classes__grid, .why__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .classes__grid, .why__grid { grid-template-columns: 1fr; } }

/* ---------- Personal Training ---------- */
.pt-subtitle { padding: var(--section-y) 0 var(--space-sm); }
.pt-subtitle__text { font-size: clamp(20px, 2vw, 28px); font-weight: 500; line-height: 1.45; color: var(--ink); max-width: 920px; letter-spacing: -0.01em; }
.pt-subtitle__text em { font-style: normal; color: var(--gold); font-weight: 300; }

.pt-benefits { padding: var(--section-y-lg) 0; }
.pt-benefits__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 48px; }
.pt-benefit {
  position: relative; padding: 40px 32px;
  background: rgba(17,17,17,0.78);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--line-2);
  display: flex; flex-direction: column; gap: 18px;
  transition: transform 0.35s, border-color 0.35s, background 0.35s;
}
.pt-benefit:hover { transform: translateY(-4px); border-color: rgba(var(--accent-rgb), 0.5); background: rgba(17,17,17,0.9); }
.pt-benefit__big-num {
  font-size: clamp(70px, 9vw, 120px); font-weight: 900;
  letter-spacing: -0.04em; line-height: 0.85;
  color: transparent; -webkit-text-stroke: 1.5px rgba(var(--accent-rgb), 0.55);
}
/* Card photo (live-site parity). Bleeds to the card edges; replaces the big number. */
.pt-benefit--photo { padding-top: 0; }
.pt-benefit__img {
  display: block; width: calc(100% + 64px); max-width: none; margin: 0 -32px 6px;
  aspect-ratio: 3 / 2; object-fit: cover;
  border-bottom: 1px solid var(--line-2);
}
.pt-benefit__title { font-size: 22px; font-weight: 700; letter-spacing: -0.015em; text-transform: uppercase; line-height: 1.1; }
.pt-benefit__desc  { color: var(--ink-dim); font-size: 14px; line-height: 1.55; }
@media (max-width: 960px) { .pt-benefits__grid { grid-template-columns: 1fr; } .pt-benefits { padding: 80px 0; } }

/* ---------- FAQs ---------- */
.faqs { padding: var(--section-y) 0 var(--section-y-lg); }
.faq-cat-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin: 40px 0 32px; }
.faq-cat-tab {
  padding: 10px 18px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--ink-dim);
  background: transparent; border: 1px solid var(--line); cursor: pointer;
  transition: all 0.2s;
}
.faq-cat-tab:hover { color: var(--ink); }
.faq-cat-tab.active { background: var(--gold); color: var(--on-accent); border-color: var(--gold); font-weight: 600; }
.faq-cat-tab[disabled] { opacity: 0.45; cursor: not-allowed; }

.faq-list { display: flex; flex-direction: column; gap: 0; border: 1px solid var(--line); border-bottom: 0; }
.faq { border-bottom: 1px solid var(--line); background: var(--bg-2); transition: background 0.2s; }
.faq:hover { background: var(--bg-3); }
.faq__q {
  width: 100%;
  padding: 22px 24px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  text-align: left;
  font-family: var(--font-display); font-size: 15px; font-weight: 600;
  color: var(--ink); background: transparent; border: 0; cursor: pointer;
  letter-spacing: -0.005em;
}
.faq__q::after {
  content: '+'; font-family: var(--font-mono); font-weight: 300;
  font-size: 24px; color: var(--gold);
  transition: transform 0.3s;
  flex-shrink: 0;
}
.faq.open .faq__q::after { transform: rotate(45deg); }
.faq__a {
  max-height: 0; overflow: hidden;
  padding: 0 24px;
  color: var(--ink-dim); font-size: 14px; line-height: 1.6;
  transition: max-height 0.4s ease, padding 0.4s ease;
}
.faq.open .faq__a { max-height: 420px; padding: 4px 24px 22px; }

/* ---------- Contact ---------- */
.contact-layout { padding: var(--section-y) 0 var(--section-y-lg); display: grid; grid-template-columns: 1fr 1.3fr; gap: 48px; align-items: start; }
.contact-info { display: flex; flex-direction: column; gap: 0; border: 1px solid var(--line); }
.contact-info__row {
  padding: 22px 24px;
  border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 6px;
  background: var(--bg-2);
}
.contact-info__row:last-child { border-bottom: 0; }
.contact-info__label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.25em; color: var(--gold); text-transform: uppercase; }
.contact-info__value { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; }
.contact-info__value a { color: var(--ink); transition: color 0.2s; }
.contact-info__value a:hover { color: var(--gold); }
.contact-info__small { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.15em; color: var(--ink-mute); text-transform: uppercase; }

.contact-form { padding: 40px; background: var(--bg-2); border: 1px solid var(--line); display: flex; flex-direction: column; gap: 22px; }
/* Standalone mode — the block dropped straight onto a page (Personal Training)
   rather than embedded in contact-page-body's two-column layout, which already
   constrains its width. Scoped to .contact-form-section, a class that only
   exists when the `standalone` attribute is set, so the Contact Us page is
   untouched. */
.contact-form-section .contact-form { max-width: 680px; margin-inline: auto; }
/* An INLINE standalone form directly after a page hero is that page's primary
   action — meeting 2026-08-13 item 17, "inquiry form above the fold". At the
   default rhythm the hero's 166px/90px padding plus the section's --section-y
   gutter pushes it under the fold on a 1440x900 desktop, so the pair is
   tightened. Sibling-scoped rather than page-scoped, so every other use of
   either block keeps the normal spacing; :has() is progressive, and without it
   the section rule alone still recovers most of the height.

   `:not([data-in2-modal])` excludes the modal configuration, which does not
   need it — there the hero carries the CTA button, so the hero is what has to
   be above the fold and it should keep its full height. That is the shape the
   PT page ships, which means these two rules currently apply to no live page.
   They are kept because standalone-without-modal is still a supported way to
   place the block, and it is the layout a no-JS visitor to the PT page is one
   attribute away from. */
.page-hero:has(+ .contact-form-section:not([data-in2-modal])) {
  padding-top: calc(var(--nav-h) + 40px);
  padding-bottom: 40px;
}
.page-hero + .contact-form-section:not([data-in2-modal]) { padding-top: 36px; }

/* ---- Modal mode -------------------------------------------------------
   The section is a plain in-page section until view.js adds .is-modal. That
   ordering is deliberate: with JavaScript off nothing below ever applies, the
   form stays inline, and the hero CTA is a real anchor that jumps to it. So
   these rules describe the enhanced state only, never the fallback. */
/* `display:grid` below is a class selector and therefore outranks the UA
   stylesheet's `[hidden] { display: none }`, which would leave the dialog
   painted while the DOM says it is hidden. This restores it. */
.contact-form-section.is-modal[hidden] { display: none; }
.contact-form-section.is-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  padding: 0;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, 0.72);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.contact-form-section.is-modal > .container {
  padding: 24px;
  width: 100%;
  max-height: 100dvh;
  overflow-y: auto;
}
.contact-form-section.is-modal .contact-form {
  border-color: var(--line-2);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.55);
}
.contact-form-modal__close {
  position: fixed;
  top: 16px;
  inset-inline-end: 20px;
  z-index: 1;
  width: 44px;
  height: 44px;
  font-size: 30px;
  line-height: 1;
  color: var(--ink);
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  border-radius: 50%;
  cursor: pointer;
}
.contact-form-modal__close:hover { border-color: var(--accent); color: var(--accent); }
/* The close control only means anything once the panel is a dialog; inline it
   would be a stray × floating over the page. */
.contact-form-section:not(.is-modal) .contact-form-modal__close { display: none; }
body.has-modal-open { overflow: hidden; }
.contact-form__title { font-size: 28px; font-weight: 800; letter-spacing: -0.02em; text-transform: uppercase; }
.field { display: flex; flex-direction: column; gap: 8px; }
.field--row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.field label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.22em;
  color: var(--ink-mute); text-transform: uppercase;
}
/* font-family is named, not inherited. `inherit` resolved to the same face
   today (the body font IS --font-display, and body.rtl redefines that token to
   'Archivo', var(--font-arabic), system-ui so Arabic still lands on Tajawal) —
   but it meant any ancestor that set a font-family silently retyped every form
   control on the site with no rule visibly changing. */
/* One height for every control in a .field, because they do not agree on their
   own: a text input renders 41px, a phone input 42px, a native date control
   44px and in2-select's button 48px. Side by side in a .field-row that reads as
   a mistake — nationality against ID type was the case that got reported.
   45px is the smallest value that clears all of them without squashing the
   trigger's Arabic line box (19px at this size, against an input's 15px), and
   it keeps the row at a usable touch height. */
:root { --field-h: 45px; }
/* --field-bg sits just above --bg-3 (#181818), which at 7 points off the .step
   card behind it (#111111) let the inputs read as one flat slab rather than as
   wells you type into. #1f1f1f fixed that but read as too light against the
   rest of the theme, so the definition comes mostly from --field-line instead:
   9 points of fill, and an edge more than twice its previous strength. */
:root { --field-bg: #1a1a1a; --field-line: rgba(244, 241, 234, 0.30); }
.field input, .field select, .field textarea {
  background: var(--field-bg); border: 1px solid var(--field-line);
  color: var(--ink); padding: 12px 14px;
  min-height: var(--field-h);
  font-family: var(--font-display); font-size: var(--fs-ui-lg);
  outline: 0; transition: border-color 0.2s;
}
/* There was no ::placeholder rule for .field inputs at all, so a placeholder
   rendered in --ink — the SAME colour as a real value. An empty field and a
   filled one looked equally filled, which is what made typed text feel like it
   did not stand out. opacity:1 because Firefox dims placeholders by default and
   would otherwise double up on this. */
.field input::placeholder,
.field textarea::placeholder {
  color: var(--ink-mute);
  opacity: 1;
}
/* --ink-mute on --bg-2 is ~3.4:1, under AA for text this size. --ink-dim is
   ~7:1 and still clearly subordinate to the value in the field. */
.field label { color: var(--ink-dim); }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--gold); }
.field textarea { resize: vertical; min-height: 120px; }

/* Chrome paints autofilled inputs with its own light background and dark text,
   and it does so at a priority plain `background-color` cannot beat — on a dark
   form the field flips to white the moment the browser fills a name or email.
   The inset box-shadow is the standard way round it (shadows are not part of
   that override), -webkit-text-fill-color handles the text, and the absurd
   transition delay stops the UA background flashing in before the shadow paints.
   Scoped to .field, which is the shared form primitive — the join wizard, the
   contact form and the PT enquiry form all use it, and all three are dark. */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus,
.field input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 100vmax var(--bg-3) inset;
          box-shadow: 0 0 0 100vmax var(--bg-3) inset;
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
  transition: background-color 100000s ease-in-out 0s;
}

/* in2-select swaps the native <select> for a <button>. Its own min-block-size
   is 48px, which is right on the GX and plans filters where it stands alone,
   but inside a form row it sat 7px proud of the 41px inputs next to it — the
   nationality field against the ID-type select was the visible case. Match the
   inputs instead: same padding, same type size, no floor.

   No !important needed: in2-select.css wraps its own sizing in :where(), which
   zeroes specificity precisely so context can override it. 16px was chosen
   there to stop iOS zooming on focus; that applies to text inputs, and this is
   a button, so 14px here is safe. The panel's search input keeps its own size. */
.field .in2-select__trigger {
  min-block-size: var(--field-h);
  padding: 12px 14px;
  font-size: var(--fs-ui-lg);
  /* Follow the inputs, not in2-select's own --bg-3: side by side in a row, a
     trigger on the old background would read as a different control. */
  background: var(--field-bg);
  border-color: var(--field-line);
}

/* Custom select chevron — replaces the OS-native arrow with a gold caret
   that matches the rest of the form. */
.field select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23EC6331' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='1,1.5 6,6.5 11,1.5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px 8px;
  padding-right: 36px;
  cursor: pointer;
}
.field select::-ms-expand { display: none; }
body.rtl .field select {
  background-position: left 14px center;
  padding-right: 14px;
  padding-left: 36px;
}

/* minmax(0,1fr) lets the number input shrink below its intrinsic min-content —
   a plain 1fr bottoms out at the input's default size and forces the whole
   contact grid wider than a 390px phone viewport. */
.phone-row { display: grid; grid-template-columns: 148px minmax(0, 1fr); gap: 10px; }

/* ===== COUNTRY-CODE PICKER (shared) =====
   Custom-built picker that replaces the native <select> so SVG flags from
   flag-icons render the same on every OS (Windows in particular doesn't
   paint flag emojis). Used by the contact form and the Join Us form; the
   `flag-icons` stylesheet must be enqueued by the consumer block. */
.cc-picker { position: relative; }
.cc-picker__trigger {
  display: flex; align-items: center; gap: 10px;
  width: 100%; height: 100%;
  box-sizing: border-box;
  /* Same tokens as .field input — this trigger sits directly beside the phone
     input in the same row and has to read as one control with it. */
  background: var(--field-bg); border: 1px solid var(--field-line);
  color: var(--ink);
  padding: 12px 14px;
  font-family: var(--font-display); font-size: var(--fs-ui-lg); line-height: 1.2;
  cursor: pointer; outline: 0;
  text-align: left;
  transition: border-color 0.2s;
}
.cc-picker__trigger:focus-visible,
.cc-picker.is-open .cc-picker__trigger { border-color: var(--gold); }
.cc-picker__flag {
  width: 22px; height: 16px;
  flex-shrink: 0;
  border-radius: 2px;
  background-size: cover;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.06);
}
.cc-picker__dial {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--ink);
}
.cc-picker__caret {
  width: 12px; height: 8px;
  margin-left: auto;
  flex-shrink: 0;
  color: var(--gold);
  transition: transform 0.2s;
}
.cc-picker.is-open .cc-picker__caret { transform: rotate(180deg); }
.cc-picker__list {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  z-index: 50;
  background: var(--bg-3);
  border: 1px solid var(--line-2);
  list-style: none;
  margin: 0;
  padding: 4px 0;
  max-height: 280px;
  overflow-y: auto;
  box-shadow: 0 16px 32px rgba(0,0,0,0.55);
  min-width: 280px;
  /* Force the vertical scrollbar to the left in LTR by parking the list's
     own direction in RTL — the scrollbar tracks the inline-start side. Each
     row is flipped back to LTR below so flag/name/dial still read naturally. */
  direction: rtl;
}
.cc-picker__opt { direction: ltr; }
.cc-picker__opt {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.15s;
}
.cc-picker__opt:hover,
.cc-picker__opt.is-active { background: rgba(var(--accent-rgb), 0.12); }
.cc-picker__opt[aria-selected="true"] { background: rgba(var(--accent-rgb), 0.18); }
.cc-picker__opt .cc-picker__name {
  flex: 1;
  color: var(--ink);
  font-family: var(--font-display);
  letter-spacing: 0;
}
.cc-picker__opt .cc-picker__dial {
  color: var(--ink-mute);
  font-size: 12px;
}
body.rtl .cc-picker__trigger { text-align: right; }
body.rtl .cc-picker__caret  { margin-left: 0; margin-right: auto; }
body.rtl .cc-picker__list   { left: auto; right: 0; }
/* In RTL the browser parks the vertical scrollbar on the inline-start side
   (left). Flip the list itself to LTR so the scrollbar sits on the right
   the way Arabic readers expect, then put each row back into RTL so the
   flag/name/dial flex order reads naturally inside the row. */
body.rtl .cc-picker__list   { direction: ltr; }
body.rtl .cc-picker__opt    { direction: rtl; }
@media (max-width: 480px) {
  .cc-picker__list { min-width: 100%; }
}
/* See the note on .proceed (PHASE 6) for why the three primary submit buttons
   were realigned to .btn's typography. Weight 500 also matters in Arabic:
   Tajawal ships no 600, so 600 was resolved per-platform. */
.contact-form__submit {
  margin-top: var(--space-3xs); padding: var(--space-xs);
  min-height: 48px;
  background: var(--gold); color: var(--on-accent); border: 0;
  font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-label);
  letter-spacing: 0.2em; text-transform: uppercase; cursor: pointer;
  transition: background 0.2s;
}
.contact-form__submit:hover { background: #fff; }
.contact-form__submit[disabled] { opacity: 0.65; cursor: progress; }
.contact-form__feedback {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--gold); padding-top: 6px;
}
.contact-form__feedback--error { color: var(--danger); }

@media (max-width: 900px) { .contact-layout { grid-template-columns: 1fr; } .field--row { grid-template-columns: 1fr; } }

/* =============================================================
   PHASE 5 — CPT-driven sections (plans grid, amenities grid,
   gx classes grid, locations map, testimonials marquee).
   Lifted from each demo_3 page's inline <style>.
   ============================================================= */

/* ---------- Promotions: plans grid ----------
   Up to 4 plans per row, always centered. Flex (not grid) so an incomplete
   final row centers naturally via justify-content. Each plan basis is
   (100% - 3*gap) / 4 = (100% - 48px) / 4 at 16px gap. */
.plans__grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px; margin-top: 56px;
}
.plans__grid > .plan {
  flex: 1 1 calc((100% - 48px) / 4);
  max-width: calc((100% - 48px) / 4);
}
.plan {
  position: relative;
  padding: 32px 24px 28px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  display: flex; flex-direction: column;
  min-width: 0;
  transition: transform 0.35s, border-color 0.35s, background 0.35s;
}
.plan::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse at top, rgba(var(--accent-rgb), 0.1), transparent 60%);
  opacity: 0; transition: opacity 0.35s; pointer-events: none;
}
.plan:hover { transform: translateY(-4px); border-color: rgba(var(--accent-rgb), 0.4); background: var(--bg-3); }
.plan:hover::before { opacity: 1; }
.plan--featured {
  background: linear-gradient(180deg, var(--bg-3), var(--bg-2));
  border-color: rgba(var(--accent-rgb), 0.45);
}
.plan--featured::after {
  content: 'BEST VALUE'; position: absolute; top: -10px; right: 20px;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.25em;
  padding: 5px 10px; background: var(--gold); color: var(--on-accent);
}
.plan__label    { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.2em; color: var(--gold); text-transform: uppercase; }
/* Membership card headings — Website Review 2026-07-29, section 5, bug 2:
   "Headings are overly large in size and lines are almost overlapping."

   Measured before: 46.1px type on line-height 1, while the Arabic ink of these
   strings is 50-60px tall — every line overflowed its own box by 4-14px, so
   consecutive lines physically collided. And at that size a title like
   "9 أشهر (عائلة و أصدقاء) – لفترة محدودة" wrapped to SIX lines and swallowed
   the card.

   line-height 1 is survivable for Latin caps. Arabic stacks an ascender
   (ا ل ك), a descender (ج ع ي) and diacritics inside one line, so it needs
   ~1.25 as a floor. Type size comes down too, which is the other half of the
   complaint. Clamped to two lines for uniform cards; the full name stays
   available via the title attribute on hover (set in the render templates). */
.plan__duration {
  font-size: clamp(26px, 2.2vw, 34px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin-top: 8px;
  text-transform: uppercase;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Arabic needs the extra leading — see note above. */
body.rtl .plan__duration { line-height: 1.3; letter-spacing: normal; }
.plan__price    { font-size: 28px; font-weight: 800; letter-spacing: -0.02em; margin-top: 16px; color: var(--ink); }
.plan__price small { font-size: 13px; color: var(--ink-dim); font-weight: 400; font-family: var(--font-mono); letter-spacing: 0.1em; margin-left: 4px; }
.plan__price del   { color: var(--ink-mute); font-size: 14px; font-weight: 400; margin-right: 8px; }
.plan__rule     { height: 1px; background: var(--line); margin: 22px 0; }
.plan__features { list-style: none; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.plan__features li {
  font-size: 13px; color: var(--ink-dim); line-height: 1.5;
  padding-left: 20px; position: relative;
}
.plan__features li::before {
  content: ''; position: absolute; left: 0; top: 7px;
  width: 10px; height: 1px; background: var(--gold);
}
.plan__cta {
  margin-top: 24px; padding: 12px 18px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em;
  text-transform: uppercase;
  background: transparent; color: var(--ink);
  border: 1px solid var(--line-2); text-align: center;
  transition: all 0.2s;
  display: block;
}
.plan__cta:hover { background: var(--gold); border-color: var(--gold); color: var(--on-accent); font-weight: 600; }

@media (max-width: 1024px) {
  .plans__grid > .plan { flex: 1 1 calc((100% - 16px) / 2); max-width: calc((100% - 16px) / 2); }
  .plan--featured::after { right: 14px; }
}
@media (max-width: 560px)  {
  .plans__grid > .plan { flex: 1 1 100%; max-width: 100%; }
}

/* ---------- Promotions: "Every plan comes with" amenities grid ---------- */
.amenities { background: var(--bg-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 80px 0; }
.amenities__title { font-size: clamp(32px, 4vw, 56px); font-weight: 800; letter-spacing: -0.03em; text-transform: uppercase; line-height: 0.95; margin-bottom: 44px; }
.amenities__title em { font-style: normal; color: var(--gold); font-weight: 300; }
.amenities__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; border-top: 1px solid var(--line); }
.amenity {
  padding: 32px 28px;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 10px;
}
.amenity:nth-child(3n) { border-right: 0; }
.amenity__num { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.25em; color: var(--gold); }
.amenity__name { font-weight: 700; font-size: 17px; letter-spacing: -0.01em; text-transform: uppercase; }
.amenity__desc { color: var(--ink-dim); font-size: 13px; line-height: 1.5; }
@media (max-width: 560px) {
  .amenities__grid { grid-template-columns: 1fr; }
  .amenity, .amenity:nth-child(3n) { border-right: 0; }
}

/* ---------- Locations page ---------- */
.locations { background: var(--bg); padding: var(--space-lg) 0 var(--section-y-lg); }
.locations__cities {
  display: flex; align-items: center; gap: 10px;
  padding: 12px; overflow-x: auto;
  border: 1px solid var(--line);
  background: var(--bg-2);
  scrollbar-width: thin;
}
.locations__cities::-webkit-scrollbar { height: 4px; }
.locations__cities::-webkit-scrollbar-thumb { background: rgba(var(--accent-rgb), 0.55); border-radius: 999px; }
.city-tab {
  flex: 0 0 auto;
  padding: 10px 18px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--ink-dim);
  background: transparent; border: 1px solid transparent; cursor: pointer;
  transition: all 0.2s;
}
.city-tab:hover  { color: var(--ink); }
.city-tab.active { background: var(--gold); color: var(--on-accent); font-weight: 600; }

.locations__body {
  display: grid; grid-template-columns: 1.2fr 1fr; gap: 0;
  margin-top: 24px; min-height: 640px;
  border: 1px solid var(--line);
}
.locations__map      { position: relative; background: #0f0f0f; overflow: hidden; border-right: 1px solid var(--line); }
.locations__map-grid {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(to right, var(--line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line) 1px, transparent 1px);
  background-size: 60px 60px;
  opacity: 0.5;
}
.ksa-map-inline { position: absolute; inset: 48px; }
.ksa-map-inline svg { width: 100%; height: 100%; }
.ksa-map-inline svg path {
  fill: #141414 !important;
  stroke: rgba(var(--accent-rgb), 0.22) !important;
  stroke-width: 0.8 !important; stroke-linejoin: round;
  transition: fill 0.4s;
}
.ksa-map-inline svg path:hover { fill: #1c1c1c !important; }

.pin { position: absolute; transform: translate(-50%, -100%); cursor: pointer; z-index: 3; }
.pin__dot {
  display: block;
  width: 14px; height: 14px; background: var(--gold); border-radius: 50%;
  box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.22), 0 0 22px rgba(var(--accent-rgb), 0.45);
  position: relative; transition: all 0.3s;
}
.pin__dot::after {
  content: ''; position: absolute; inset: -6px; border: 1px solid var(--gold);
  border-radius: 50%; animation: pin-pulse 2s infinite;
}
@keyframes pin-pulse { 0% { transform: scale(1); opacity: 1; } 100% { transform: scale(2.4); opacity: 0; } }
.pin__label {
  position: absolute; bottom: 22px; left: 50%; transform: translateX(-50%);
  font-family: var(--font-display); font-weight: 700; font-size: 12px;
  white-space: nowrap;
  background: rgba(10,10,10,0.85); backdrop-filter: blur(8px);
  padding: 4px 10px; border: 1px solid var(--line-2);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.pin.active .pin__dot   { background: #fff; box-shadow: 0 0 0 6px rgba(255,255,255,0.22), 0 0 28px var(--gold); }
.pin.active .pin__label { background: var(--gold); color: var(--on-accent); border-color: var(--gold); font-weight: 800; }

.locations__panel {
  padding: 40px 36px; background: var(--bg-2);
  overflow-y: auto; max-height: 720px;
  scrollbar-width: thin; scrollbar-color: var(--gold) transparent;
}
.locations__panel::-webkit-scrollbar { width: 6px; }
.locations__panel::-webkit-scrollbar-track { background: transparent; margin: 12px 0; }
.locations__panel::-webkit-scrollbar-thumb { background: linear-gradient(180deg, var(--gold), var(--gold-deep)); border-radius: 999px; }
.locations__panel-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding-bottom: 20px; border-bottom: 1px solid var(--line);
  margin-bottom: 28px;
}
.locations__panel-city  { font-size: 40px; font-weight: 900; letter-spacing: -0.02em; text-transform: uppercase; line-height: 1; }
.locations__panel-count { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em; color: var(--gold); text-transform: uppercase; margin-top: 6px; }

.locations__tabs { display: flex; gap: 4px; margin-bottom: 20px; }
.locations__tab {
  flex: 1; padding: 10px 14px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink-dim);
  background: transparent; border: 1px solid var(--line); cursor: pointer;
  transition: all 0.2s;
}
.locations__tab.active { background: var(--gold); color: var(--on-accent); border-color: var(--gold); font-weight: 600; }

.branch-list { display: flex; flex-direction: column; gap: 1px; background: var(--line); }
.branch-list:empty::after {
  content: 'No branches yet in this segment.';
  display: block; padding: 20px; background: var(--bg-2);
  font-family: var(--font-mono); font-size: 11px; color: var(--ink-mute);
  letter-spacing: 0.12em; text-transform: uppercase;
}
.branch {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 20px; background: var(--bg-3);
  transition: background 0.2s;
}
/* The view.js filter toggles the [hidden] attribute to filter by city +
   gender. `.branch` declares display:flex which would otherwise win over
   the attribute's implicit display:none, so re-assert it here. */
.branch[hidden] { display: none; }
.branch:hover  { background: #1f1f1f; }
.branch__name  { font-weight: 700; font-size: 15px; letter-spacing: -0.01em; }
.branch__hours { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em; color: var(--ink-mute); text-transform: uppercase; margin-top: 4px; }
.branch__address { font-size: 13px; line-height: 1.45; color: var(--ink-dim); margin-top: 6px; overflow-wrap: anywhere; }
.branch__badge {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.18em;
  padding: 4px 8px; border: 1px solid var(--line-2); color: var(--ink-dim);
  text-transform: uppercase;
}
.branch__badge--24 { color: var(--gold); border-color: rgba(var(--accent-rgb), 0.4); }
.branch__link {
  color: var(--ink-dim); font-family: var(--font-mono); font-size: 10px;
  letter-spacing: 0.18em; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 6px;
  transition: color 0.2s;
}
.branch__link:hover { color: var(--gold); }

@media (max-width: 960px) {
  .locations__body { grid-template-columns: 1fr; }
  .locations__map  { min-height: 420px; border-right: 0; border-bottom: 1px solid var(--line); }
  .ksa-map-inline  { inset: 24px; }
}

/* ===== APP CTA ===== */
.app-cta {
  position: relative; overflow: hidden;
  background: linear-gradient(135deg, #151515 0%, #0c0c0c 100%);
  padding: var(--section-y) 0;
}
.app-cta__bg {
  position: absolute; inset: 0;
  opacity: 0.1;
  background-image: url('../images/app-bg-pattern.png');
  background-size: 400px;
  mix-blend-mode: screen;
}
.app-cta__inner {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 0.8fr 1fr; gap: 48px; align-items: center;
}
.app-cta__phone { position: relative; display: grid; place-items: center; }
.app-cta__phone img {
  max-height: 560px; width: auto;
  filter: drop-shadow(0 40px 80px rgba(var(--accent-rgb), 0.2));
}
.app-cta__heading {
  font-size: clamp(48px, 6vw, 96px); font-weight: 900; line-height: 0.95;
  letter-spacing: -0.04em; text-transform: uppercase;
  margin-bottom: 24px;
}
.app-cta__heading em { font-style: normal; color: var(--gold); }
.app-cta__desc { font-size: 17px; line-height: 1.6; color: var(--ink-dim); max-width: 520px; margin-bottom: 40px; }
.app-cta__badges { display: flex; gap: 20px; flex-wrap: wrap; }
.app-cta__badge {
  display: flex; gap: 14px; align-items: center;
  padding: 14px 18px; background: var(--bg-3); border: 1px solid var(--line-2);
  transition: border-color 0.2s;
}
.app-cta__badge:hover { border-color: var(--gold); }
.app-cta__badge img.qr { width: 60px; height: 60px; object-fit: contain; background: #fff; padding: 3px; }
.app-cta__badge-text { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.18em; color: var(--ink-dim); text-transform: uppercase; }
.app-cta__badge-text strong { display: block; color: var(--ink); font-size: 14px; letter-spacing: 0.05em; font-family: var(--font-display); text-transform: none; font-weight: 700; margin-top: 2px; }

/* =============================================================
   PHASE 6 — Join form (4-step accordion + summary panel).
   Lifted verbatim from demo_3/join-now.html inline <style>.
   ============================================================= */
.join { padding: var(--section-y) 0 var(--section-y-lg); }
.join__grid { display: grid; grid-template-columns: 1.5fr 1fr; gap: 40px; align-items: start; }

.step {
  background: var(--bg-2); border: 1px solid var(--line);
  margin-bottom: 14px;
  transition: border-color 0.25s, opacity 0.25s;
}
.step--locked { opacity: 0.55; }
.step--locked .step__head { cursor: not-allowed; }
.step--complete { border-color: rgba(var(--accent-rgb), 0.35); }
.step__head {
  width: 100%;
  display: flex; align-items: center; gap: 16px;
  padding: 22px 28px;
  background: transparent; border: 0; cursor: pointer;
  text-align: left;
  transition: background 0.2s;
}
.step__head:hover { background: rgba(var(--accent-rgb), 0.04); }
.step--locked .step__head:hover { background: transparent; }
.step__num {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.25em;
  padding: 6px 10px; background: var(--gold); color: var(--on-accent); font-weight: 600;
  flex: 0 0 auto;
}
.step--locked .step__num { background: var(--line-2); color: var(--ink-dim); }
.step__title { font-size: var(--fs-title); font-weight: 800; letter-spacing: -0.015em; text-transform: uppercase; flex: 1; color: var(--ink); }
.step__meta  { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.2em; color: var(--gold); text-transform: uppercase; margin-right: 14px; }
.step__chev  { width: 18px; height: 18px; flex: 0 0 auto; color: var(--ink-mute); transition: transform 0.3s, color 0.2s; }
.step.open .step__chev { transform: rotate(180deg); color: var(--gold); }
.step__body  { padding: 0 28px 28px; display: none; }
.step.open .step__body { display: block; }

.sub-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.22em; color: var(--ink-dim); text-transform: uppercase; margin-bottom: 10px; display: block; }
.sub-label--mt { margin-top: 22px; }

.pill-row { display: flex; flex-wrap: wrap; gap: 10px; }

/* The form-skeleton uses .field-row (single dash) for two-up form pairs
   like First/Last name and DOB/Start date. Defaults to two equal columns;
   the @media (max-width: 900px) block at the bottom collapses to one. */
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.pill {
  padding: 10px 18px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink-dim);
  background: var(--bg-3); border: 1px solid var(--line-2); cursor: pointer;
  transition: all 0.2s;
}
.pill:hover { color: var(--ink); border-color: rgba(var(--accent-rgb), 0.4); }
.pill.active { background: var(--gold); color: var(--on-accent); border-color: var(--gold); font-weight: 600; }
.pill:disabled, .pill.disabled { opacity: 0.4; cursor: not-allowed; }

.reveal { display: none; margin-top: 20px; animation: revealIn 0.4s ease; }
.reveal.show { display: block; }
@keyframes revealIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }

.plan-picker { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.plan-opt {
  position: relative;
  padding: 22px 20px;
  background: var(--bg-3); border: 1px solid var(--line-2); cursor: pointer;
  transition: all 0.2s;
  display: flex; flex-direction: column; gap: 10px;
}
.plan-opt:hover { border-color: rgba(var(--accent-rgb), 0.45); transform: translateY(-2px); }
.plan-opt.active { border-color: var(--gold); background: linear-gradient(180deg, var(--bg-3), rgba(var(--accent-rgb), 0.08)); }
.plan-opt--popular::before {
  content: 'Popular';
  position: absolute; top: -10px; right: 14px;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.25em;
  padding: 4px 10px; background: var(--gold); color: var(--on-accent); text-transform: uppercase;
}
.plan-opt__name { font-weight: 800; font-size: 18px; letter-spacing: -0.01em; text-transform: uppercase; }
.plan-opt__duration { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.22em; color: var(--ink-mute); text-transform: uppercase; }
.plan-opt__price { color: var(--gold); font-weight: 800; font-size: 22px; letter-spacing: -0.01em; }
.plan-opt__price small { color: var(--ink-mute); font-size: 11px; letter-spacing: 0.08em; margin-left: 4px; font-family: var(--font-mono); font-weight: 400; }
.plan-opt__old { text-decoration: line-through; font-size: 12px; color: var(--ink-mute); font-family: var(--font-mono); letter-spacing: 0.08em; }
.plan-opt__badge { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.2em; color: var(--ink-dim); text-transform: uppercase; }

/* Campaign banner — shown above the plan grid when a /c/{slug} offer has
   ended or is not sold at the chosen branch. Informational, not an error:
   the plans below it are real and buyable, so it must not read as a failure. */
.campaign-notice { display: none; margin: 0 0 14px; }
.campaign-notice.show { display: block; }
.campaign-notice__inner {
  padding: 10px 14px;
  border: 1px solid color-mix(in srgb, var(--gold) 35%, transparent);
  border-inline-start-width: 3px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--gold) 8%, transparent);
  color: var(--ink-dim);
  font-size: 14px; line-height: 1.5;
}
.plan-opt__benefits {
  list-style: none; margin: 8px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
  font-size: 14px; line-height: 1.5; color: var(--ink-dim);
}
.plan-opt__benefits li {
  position: relative; padding-inline-start: 16px;
}
.plan-opt__benefits li::before {
  content: ''; position: absolute; inset-inline-start: 0; top: 9px;
  width: 6px; height: 6px; background: var(--gold); border-radius: 50%;
}
[dir="rtl"] .plan-opt__benefits li,
.rtl .plan-opt__benefits li { padding-inline-start: 16px; padding-inline-end: 0; }

/* Explicit per-card action. margin-top:auto is load-bearing, not cosmetic:
   .plan-opt is a flex column and the benefit lists differ in length between
   plans, so without it the buttons land at four different heights across the
   picker row. Typography follows .btn like the other primary actions; the
   rest state stays neutral per the ACCENT BUDGET and fills in on selection. */
.plan-opt__cta {
  margin-top: auto;
  min-height: 44px; padding: var(--space-2xs) var(--space-xs);
  background: transparent; color: var(--ink);
  border: 1px solid var(--line-2);
  font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-label);
  letter-spacing: 0.2em; text-transform: uppercase; cursor: pointer;
  transition: border-color 0.2s, background 0.2s, color 0.2s;
}
.plan-opt__cta:hover { border-color: var(--gold); color: var(--gold); }
.plan-opt.active .plan-opt__cta {
  background: var(--gold); border-color: var(--gold); color: var(--on-accent);
}

.pay-options { display: flex; flex-direction: column; gap: 10px; }
.pay-opt {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 20px;
  background: var(--bg-3); border: 1px solid var(--line-2); cursor: pointer;
  transition: all 0.2s;
}
.pay-opt:hover  { border-color: rgba(var(--accent-rgb), 0.45); }
.pay-opt.active { border-color: var(--gold); }
/* "Coming soon" methods (Tabby/Tamara pre-launch): visible, not selectable. */
.pay-opt--soon { opacity: 0.55; cursor: default; }
.pay-opt--soon:hover { border-color: var(--line); }
.pay-opt__soon {
  flex: 0 0 auto;
  font-family: var(--font-mono); font-size: 9px;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); border: 1px solid rgba(var(--accent-rgb), 0.45);
  padding: 4px 8px; white-space: nowrap;
}
/* Tabby's prescribed refusal sentence, shown in the row body when pre-scoring
   declines them. Deliberately NOT .pay-opt__soon: that badge is mono, uppercase
   and letter-spaced, which would render "SORRY, TABBY IS UNABLE…" and breach the
   same capital-T rule as T-12/T-17. Body font, sentence case, left as written.
   Capped at ~52ch so it wraps to two lines rather than running the row wide. */
.pay-opt__reason {
  margin: 6px 0 0;
  max-width: 52ch;
  font-size: var(--fs-body-sm, 13px);
  line-height: 1.5;
  color: var(--danger);
  text-transform: none;
  letter-spacing: normal;
}

/* Tabby's CHECKOUT card (TabbyCard) on our dark payment row.
   These two custom properties are Tabby's OWN documented hooks — the only
   supported way to recolour the snippet — and they apply only when the widget
   is built with shouldInheritBg:true, which is what refreshTabbyWidgets() does.
   They replace an override of Tabby's private BEM class names inside their
   shadow root (T-09); those were never an API and a rename their end would have
   turned the copy dark-on-dark, i.e. invisible.
   themeTabbyCard() still measures the rendered text afterwards and rebuilds with
   Tabby's own light panel if anything is unreadable — their "View options"
   button is known not to take --snippetTextColor (T-06). */
#in2-tabby-card {
  --snippetTextColor: #f4f1ea;
  --snippetLinkTextColor: #9ec5ff;
}

/* Tabby's approved payment-method description, shown in place of their live
   snippet (below their Pay-over-time floor, or if the snippet cannot paint).
   text-transform MUST stay none: the row's uppercase styling would render
   "Learn more" shouted and break Tabby's capital-T rule the same way T-17 did. */
.pay-opt__desc {
  margin: 6px 0 0;
  max-width: 52ch;
  font-size: var(--fs-body-sm, 13px);
  line-height: 1.5;
  color: var(--muted, #b3b3b3);
  text-transform: none;
  letter-spacing: normal;
}
.pay-opt__more {
  color: inherit;
  text-decoration: underline;
  white-space: nowrap;
  /* This link is the only route to Tabby's payment schedule, so it needs to be
     tappable, not merely clickable. As bare inline text it measured 14px tall on
     a 430px viewport, well under the 44px touch guideline. Padding plus
     inline-block gives it a real hit area; the negative margin keeps the
     sentence's line spacing unchanged, so nothing reflows. */
  display: inline-block;
  padding: 8px 4px;
  margin: -8px -4px;
}
.pay-opt__more:hover,
.pay-opt__more:focus-visible { color: var(--accent, #e2571f); }

/* T-19 — one Tabby logo, not two.
   Our row draws a Tabby badge in its icon slot AND Tabby's snippet draws its own
   wordmark, which on a narrow screen leaves their copy about 228px of a 430px
   viewport and breaks it into six short lines. So at mobile widths we drop OUR
   badge and let theirs identify the brand.
   Keyed on data-painted, which themeTabbyCard() sets only once Tabby's snippet
   has actually rendered text. That matters: when the approved description is
   showing instead (below their floor, or their API down) there is no Tabby mark
   inside the row, so ours is the only one and must stay. Using :has() rather
   than a class on the row keeps the decision in CSS; where :has() is
   unsupported both logos show, which is exactly today's behaviour. */
@media (max-width: 600px) {
  .pay-opt[data-method-id="tabby"]:has(#in2-tabby-card[data-painted="1"]) .pay-opt__icon--logo {
    display: none;
  }
}
/* Embedded Tap card fields (step 4). The inputs are Tap-hosted iframes and
   Tap's v1 widget draws a WHITE card panel — present it as a deliberate
   "bank card" sitting on the dark step, framed by a slim gold-tinted well. */
.card-element-wrap { margin-top: 18px; }
.card-element-wrap .sub-label { margin-bottom: 10px; }
#in2f-card-element {
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.10), rgba(var(--accent-rgb), 0.02));
  border: 1px solid rgba(var(--accent-rgb), 0.35);
  padding: 16px; min-height: 52px;
  max-width: 520px;
}
#in2f-card-element:focus-within { border-color: var(--gold); }
#in2f-card-element iframe { border-radius: 10px; overflow: hidden; }
/* Payment-method name — the "text around the logos" half of the UAT call-out.
   .gender-card__title is the same thing one step earlier: the label of a
   selectable option card, at 14px / 700 / uppercase / 0.04em. This was
   14px / 700 / sentence-case / no tracking, so the two selection controls of
   the same wizard set their option labels differently. Match it. */
.pay-opt__label {
  font-weight: 700; font-size: var(--fs-ui-lg);
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--ink);
}
/* Tabby is exempt from the uppercase treatment. Their brand rules are explicit
   — "Always write Tabby with a capital T: not TABBY, not tabby" — so the row
   above would breach them on styling alone, whatever string we put in it. The
   label text itself comes from i18n.tabby (see methodLabel in frontend.js);
   this rule is the other half, and neither works without the other.
   Scoped by data-method-id so every other method keeps the wizard's styling. */
.pay-opt[data-method-id="tabby"] .pay-opt__label {
  text-transform: none;
  letter-spacing: normal;
}
.pay-opt__sub {
  font-family: var(--font-mono); font-size: var(--fs-label-xs);
  letter-spacing: 0.15em; color: var(--ink-mute);
  text-transform: uppercase; margin-top: var(--space-4xs);
}
.pay-opt__radio { width: 16px; height: 16px; border-radius: 50%; border: 1px solid var(--line-2); flex-shrink: 0; position: relative; }
.pay-opt.active .pay-opt__radio { border-color: var(--gold); }
.pay-opt.active .pay-opt__radio::after {
  content: ''; position: absolute; inset: 3px; background: var(--gold); border-radius: 50%;
}

.terms { display: flex; gap: 12px; padding: 16px; background: var(--bg-3); border: 1px solid var(--line); font-size: 12px; color: var(--ink-dim); line-height: 1.5; margin-top: 20px; }
.terms input { accent-color: var(--gold); margin-top: 2px; flex: 0 0 auto; }
.terms a { color: var(--gold); }

/* Membership agreement (Sentinel GetTerms) — read link + modal */
.terms-read {
  display: block;
  background: none; border: 0; padding: 0; margin: 12px 0 4px;
  color: var(--gold); font-family: var(--font-mono); font-size: 10px;
  letter-spacing: 0.18em; text-transform: uppercase; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.terms-read:hover { color: #fff; }
.terms-modal {
  border: 1px solid var(--line-2); padding: 0;
  background: var(--bg-2); color: var(--ink);
  width: min(760px, 92vw);
  /* The theme's global reset zeroes margins, which kills the UA stylesheet's
     dialog centering (position:fixed; inset:0; margin:auto) — restore it so
     the modal centers on both axes. */
  position: fixed; inset: 0; margin: auto;
  max-height: min(80vh, 720px);
}
.terms-modal::backdrop { background: rgba(0, 0, 0, 0.72); }
.terms-modal__head {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 24px; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--bg-2);
}
.terms-modal__title { font-size: var(--fs-title-sm); font-weight: 800; text-transform: uppercase; letter-spacing: -0.01em; }
.terms-modal__close {
  background: none; border: 1px solid var(--line-2); color: var(--ink-dim);
  width: 32px; height: 32px; cursor: pointer; flex: 0 0 auto;
  transition: color 0.2s, border-color 0.2s;
}
.terms-modal__close:hover { color: var(--gold); border-color: var(--gold); }
.terms-modal__body { padding: 8px 24px 26px; overflow-y: auto; max-height: min(66vh, 640px); }
.terms-modal__heading { font-size: 13px; font-weight: 800; color: var(--ink); margin: 18px 0 4px; white-space: pre-line; }
.terms-modal__item { font-size: 13px; line-height: 1.7; color: var(--ink-dim); margin: 8px 0; white-space: pre-line; }
body.rtl .terms-modal__body,
body.rtl .terms-modal__head { text-align: right; }

/* Wizard primary action. The design system's button is .btn (top of file):
   mono / 11px / 0.2em / weight 500. .proceed and .summary__cta had drifted to
   0.25em and weight 600 and disagreed with each other on size (11 vs 12px) —
   two primary buttons of the same wizard, three typographic differences.
   Aligned to .btn, which is what "in2fitness style" means here.
   Weight 500 also fixes Arabic: Tajawal ships no 600 (only 200/300/400/500/
   700/800/900), so weight 600 was being resolved per-platform.
   min-height is the same 44px touch floor .nav__links a already carries; the
   join flow never got one, and 90% of traffic is mobile. */
.proceed {
  margin-top: var(--space-sm); padding: var(--space-2xs) var(--space-sm);
  min-height: 44px;
  background: var(--gold); color: var(--on-accent); border: 0;
  font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-label);
  letter-spacing: 0.2em; text-transform: uppercase; cursor: pointer;
  transition: background 0.2s, opacity 0.2s;
}
.proceed:hover:not(:disabled) { background: #fff; }
.proceed:disabled { opacity: 0.45; cursor: not-allowed; }

/* Reason line under a disabled .proceed — a greyed-out button with no
   explanation is a dead end, so frontend.js writes what is still missing here
   and hides the node once step 3 is complete. Sits outside .field, so it does
   not inherit the .field .hint rule above and states its own type.
   Logical margin: Arabic mirrors without a second rule. */
.proceed-hint {
  margin-block-start: var(--space-2xs);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em;
  color: var(--ink-mute);
}
.proceed-hint[hidden] { display: none; }

.summary {
  position: sticky; top: calc(var(--nav-h) + 20px);
  background: var(--bg-2); border: 1px solid var(--line);
  padding: 28px 28px 24px;
}
.summary__title { font-size: var(--fs-title-sm); font-weight: 800; letter-spacing: -0.01em; text-transform: uppercase; margin-bottom: 20px; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.summary__row   { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 10px 0; font-size: 13px; color: var(--ink-dim); }
.summary__row strong { color: var(--ink); font-weight: 600; font-family: var(--font-display); text-align: right; }
.summary__row.total  { border-top: 1px solid var(--line); margin-top: 12px; padding-top: 18px; font-size: 20px; color: var(--ink); font-weight: 800; }
.summary__row.total .v { color: var(--gold); }
.summary__fees   { display: none; }
.summary__fees.show { display: block; }
.summary__freeze { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.18em; color: var(--gold); text-transform: uppercase; padding: 10px 12px; background: rgba(var(--accent-rgb), 0.06); border: 1px dashed rgba(var(--accent-rgb), 0.3); margin-top: 16px; display: none; }
.summary__freeze.show { display: block; }
.summary__note   { font-size: 11px; color: var(--ink-mute); padding: 10px 12px; background: var(--bg-3); border-left: 2px solid var(--gold); margin-top: 14px; line-height: 1.5; display: none; }
.summary__note.show { display: block; }
/* Terminal action of the funnel — matches .proceed exactly (see its note),
   with a 48px floor because it is the last tap on a mobile-first flow. */
.summary__cta {
  width: 100%; margin-top: var(--space-xs); padding: var(--space-xs);
  min-height: 48px;
  background: var(--gold); color: var(--on-accent); border: 0;
  font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-label);
  letter-spacing: 0.2em; text-transform: uppercase; cursor: pointer;
  transition: background 0.2s, opacity 0.2s;
}
.summary__cta:hover:not(:disabled) { background: #fff; }
.summary__cta:disabled { opacity: 0.45; cursor: not-allowed; }
/* Trust line under the CTA. Two A6 problems:
   (1) 9px was the smallest type on the site and existed nowhere else except
       two badges — that is not a size, it is a typo in the scale.
   (2) form-skeleton.php renders a literal 🔒 emoji here, i.e. the OS emoji
       font painting a coloured glyph in the middle of the brand's own security
       statement. The meeting's exemption covers third-party widget LOGOS, not
       system emoji. Suppress the emoji span and draw a currentColor padlock
       instead, so it tracks --ink-mute and turns teal inside .is-ladies.
       No plugin markup change required. */
.summary__ssl {
  font-family: var(--font-mono); font-size: var(--fs-label-xs);
  letter-spacing: 0.2em; color: var(--ink-mute); text-transform: uppercase;
  text-align: center; margin-top: var(--space-xs);
  display: flex; align-items: center; justify-content: center; gap: var(--space-3xs);
}
.summary__ssl > span[aria-hidden="true"] { display: none; }
.summary__ssl::before {
  content: '';
  width: 11px; height: 13px; flex: 0 0 auto;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 10V7a6 6 0 1112 0v3h1a1 1 0 011 1v10a1 1 0 01-1 1H5a1 1 0 01-1-1V11a1 1 0 011-1h1zm2 0h8V7a4 4 0 10-8 0v3z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 10V7a6 6 0 1112 0v3h1a1 1 0 011 1v10a1 1 0 01-1 1H5a1 1 0 01-1-1V11a1 1 0 011-1h1zm2 0h8V7a4 4 0 10-8 0v3z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.summary__error  { font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: 0.2em; text-transform: uppercase; color: var(--danger); padding: 10px 12px; background: rgba(var(--danger-rgb), 0.06); border-left: 2px solid var(--danger); margin-top: var(--space-xs); display: none; }
.summary__error.show { display: block; }
/* Provider copy we are not allowed to restyle. The rule above shouts every
   error in mono caps, which is fine for our own strings and a breach for
   Tabby's: their approved decline sentence contains the word "Tabby", and
   "Always write Tabby with a capital T: not TABBY, not tabby" applies to it
   wherever it appears. Same rule already forced the exemption on
   .pay-opt[data-method-id="tabby"] .pay-opt__label — this is the other place
   their name reaches the page. frontend.js adds the class for approved copy
   only, so our own errors keep the wizard's voice. */
.summary__error--verbatim { text-transform: none; letter-spacing: normal; font-family: inherit; }

/* Gender split — full-width 2-column cards (Ladies | Men). Layout pulled
   from demo_1; visuals stay in the dark/gold theme. */
.gender-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.gender-card {
  width: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
  padding: 18px 16px;
  background: var(--bg-3); border: 1px solid var(--line-2);
  cursor: pointer; transition: all 0.2s;
  text-align: center;
}
.gender-card:hover  { border-color: rgba(var(--accent-rgb), 0.45); }
.gender-card.active { border-color: var(--gold); background: linear-gradient(180deg, var(--bg-3), rgba(var(--accent-rgb), 0.08)); }
.gender-card[hidden] { display: none; }
.gender-card__title { font-weight: 700; font-size: 14px; color: var(--ink); letter-spacing: 0.04em; text-transform: uppercase; }
.gender-card__desc  { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.18em; color: var(--ink-mute); text-transform: uppercase; }
.gender-card.active .gender-card__title { color: var(--gold); }

/* Segment a campaign's offer is not sold to — disabled and labelled.
   `not-allowed` rather than the default arrow so the card explains itself on
   hover, and the hover rule above is cancelled so it does not appear to react
   to a click it will not accept. The way out is .campaign-clear below: without
   it this is a lockout, because the campaign cookie outlives the page load and
   applies on /join-now/ too. */
.gender-card--off-offer {
  opacity: 0.5;
  cursor: not-allowed;
}
.gender-card--off-offer:hover { border-color: var(--line-2); }
.gender-card__note {
  margin-top: 6px; padding: 2px 7px;
  border: 1px solid var(--line-2);
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-mute); white-space: nowrap;
}
/* The row under the gender grid. The same .campaign-clear button is also
   appended inline to the club-grid hint, which brings its own spacing — so the
   margin lives on the row, not on the button. */
.campaign-clear-row { margin-top: 10px; }
.campaign-clear {
  padding: 0; background: none; border: 0;
  color: var(--gold); font: inherit; text-decoration: underline;
  text-underline-offset: 3px; cursor: pointer;
}
.campaign-clear:hover { color: var(--ink); }

/* Branch picker — 3-column card grid with image header (placeholder if
   the CPT row has no image_url) and a city pin under the name. */
.branch-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; }
.nearest-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 6px; padding: 7px 12px;
  background: none; border: 1px solid var(--line-2); color: var(--ink-dim);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  cursor: pointer; transition: color 0.2s, border-color 0.2s;
}
.nearest-toggle svg { width: 12px; height: 12px; }
.nearest-toggle:hover { color: var(--gold); border-color: rgba(var(--accent-rgb), 0.45); }
.nearest-toggle[aria-pressed="true"] { color: var(--gold); border-color: var(--gold); }
.nearest-toggle[disabled] { opacity: 0.6; cursor: progress; }
.branch-card__dist { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em; color: var(--gold); white-space: nowrap; }
.branch-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.branch-card {
  display: flex; flex-direction: column;
  background: var(--bg-3); border: 1px solid var(--line-2);
  cursor: pointer; transition: all 0.2s;
  overflow: hidden;
  text-align: left;
  padding: 0;
}
body.rtl .branch-card { text-align: right; }
.branch-card:hover  { border-color: rgba(var(--accent-rgb), 0.45); transform: translateY(-2px); }
.branch-card.active { border-color: var(--gold); background: linear-gradient(180deg, var(--bg-3), rgba(var(--accent-rgb), 0.08)); }
.branch-card__img {
  height: 110px;
  background: rgba(var(--accent-rgb), 0.04);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.branch-card__img-el { width: 100%; height: 100%; object-fit: cover; display: block; }
.branch-card__img-placeholder { color: rgba(var(--accent-rgb), 0.55); display: flex; align-items: center; justify-content: center; }
.branch-card__info { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 6px; }
.branch-card__name { font-weight: 700; font-size: 14px; color: var(--ink); letter-spacing: -0.01em; }
.branch-card.active .branch-card__name { color: var(--gold); }
.branch-card__meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.branch-card__location { display: inline-flex; align-items: center; gap: 4px; color: var(--ink-mute); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; }
.branch-card__location svg { flex: 0 0 auto; }
.branch-card__badge { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.2em; padding: 2px 6px; background: rgba(var(--accent-rgb), 0.12); color: var(--gold); text-transform: uppercase; }

/* Payment row — icon tile + label + radio. Brands inherit currentColor for
   inline SVGs; image icons (when admin sets icon_url) display at natural
   contrast inside a neutral tile. */
.pay-opt { gap: 14px; }
/* Payment-method mark — the "placement" half of the UAT call-out.
   The tile is ours; the mark inside it may be a third-party logo (exempt from
   the brand-style rule). Before: a rigid 44x44 tile holding either a 24px
   inline SVG or an image capped at max-width:28px AND max-height:28px. Those
   two caps do different things to different marks — a square glyph (mada)
   lands at 28x28, ~17% larger than the 24px SVG siblings, while a wordmark at
   roughly 3:1 (Tabby, Tamara) hits the 28px WIDTH cap and renders about 9px
   tall, floating in a 44px box. No two rows shared an optical mark size or
   baseline, which is what reads as inconsistent placement.

   Fix: normalise on HEIGHT only (cap height is what the eye reads), let the
   tile grow horizontally for wordmarks, keep one shared vertical centre. */
.pay-opt__icon {
  min-width: 44px; width: auto; height: 44px;
  padding-inline: var(--space-3xs);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-2); border: 1px solid var(--line); color: var(--gold);
  flex: 0 0 auto;
}
.pay-opt__icon > svg { width: 24px; height: 24px; }
.pay-opt__icon-img {
  height: 20px; width: auto;
  max-width: 72px; max-height: 20px;
  object-fit: contain; display: block;
}
/* Wordmark variant: a full-bleed brand logo needs no tile behind it, and a
   tinted panel under a coloured logo is what makes the row look pasted-in. */
.pay-opt__icon--logo {
  background: transparent; border-color: transparent;
  padding-inline: 0;
}
.pay-opt__body { flex: 1; min-width: 0; }
/* Trailing-edge alignment for BOTH row endings. A selectable row ends in
   .pay-opt__radio; a "coming soon" row (Tabby/Tamara pre-launch — i.e. exactly
   the rows reviewed in UAT) ends in .pay-opt__soon instead. Only the radio had
   margin-left:auto, so the badge hugged the method label while the radios
   above and below sat hard against the trailing edge — the payment list
   visibly stepped in and out down the column.
   margin-inline-start also retires the body.rtl physical-property flip. */
.pay-opt__radio,
.pay-opt__soon { margin-inline-start: auto; }

/* Multiple marks on one row (e.g. a card row showing Visa + Mastercard + mada).
   Sits between the label and the trailing radio, so it must not take the
   auto-margin — it wraps instead of pushing the row wider on a phone. */
.pay-opt__logos {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-4xs) var(--space-3xs);
  margin-top: var(--space-4xs);
}
.pay-opt__logo { height: 18px; width: auto; max-width: 52px; object-fit: contain; display: block; }

/* Accepted-methods strip under the payment list. in2fitness-authored label +
   exempt brand marks, so the label follows the wizard's mono micro-label
   treatment and only the marks keep their own colour. */
/* Appended as the last child of .pay-options (a flex column with its own gap),
   so no margin-top here — the container already supplies the separation and a
   margin on top of it would read as a second, wider gap. */
.pay-logos {
  display: flex; flex-direction: column; gap: var(--space-3xs);
  padding-top: var(--space-2xs);
  border-top: 1px solid var(--line);
}
.pay-logos__label {
  font-family: var(--font-mono); font-size: var(--fs-label-xs);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-mute);
}
.pay-logos__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3xs); }
.pay-logos__img { height: 20px; width: auto; max-width: 56px; object-fit: contain; display: block; }

/* The single Tamara promo widget (payment step only — BNPL compliance). The
   custom element defaults to display:inline, so its box would not take part in
   .pay-opt__body's block flow the way the rows around it do. */
.join tamara-widget { display: block; }

.field .hint { font-family: var(--font-mono); font-size: 10px; color: var(--ink-mute); letter-spacing: 0.12em; margin-top: 2px; }
.field .hint--error { color: var(--danger); letter-spacing: 0.08em; }
.field input[aria-invalid="true"] { border-color: rgba(var(--danger-rgb), 0.6); }

@media (max-width: 900px) {
  .join__grid   { grid-template-columns: 1fr; }
  .summary      { position: static; }
  .plan-picker  { grid-template-columns: 1fr; }
  .field-row    { grid-template-columns: 1fr; }
  .branch-grid  { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 600px) {
  .branch-grid { grid-template-columns: 1fr; }
  .gender-grid { grid-template-columns: 1fr; }

  /* 90% of traffic is mobile (UAT walkthrough, 2026-08-03). The wizard's
     chrome never responded: .step__head kept 28px side padding and .step__body
     kept 28px, so on a 390px viewport 56px — 14% of the screen — went to
     padding that only exists to give a 1304px container breathing room. */
  .step__head    { padding: var(--space-xs); gap: var(--space-2xs); }
  .step__body    { padding: 0 var(--space-xs) var(--space-xs); }
  .summary       { padding: var(--space-sm) var(--space-xs) var(--space-xs); }
  .pay-opt       { padding: var(--space-2xs) var(--space-xs); }
  .step__title   { font-size: var(--fs-title-sm); }

  /* Touch targets. .nav__links a already carries min-height:44px (see NAV);
     the join controls never got it — .pill computes to ~37px. */
  .pill,
  .gender-card,
  .nearest-toggle,
  .terms-read    { min-height: 44px; display: inline-flex; align-items: center; }
  /* Restated: the rule above sets display:inline-flex, which would otherwise
     drop .gender-card's column stacking. */
  .gender-card   { flex-direction: column; justify-content: center; }
}

/* ---------- Status shortcode (thank-you / failure pages) ----------
   The card lives inside `wp:post-content`, whose default flow-root parent
   collapses the card's vertical margin out into the document. Wrap it in
   .in2-status-wrap to break margin collapse, give the page a comfortable
   minimum height so the box visually centers between header and footer,
   and add explicit padding instead of relying on margin. */
.in2-status-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 96px 20px;
  min-height: 60vh;
}
.in2-status {
  max-width: 720px;
  width: 100%;
  margin: 0;
  padding: 56px 48px;
  background: var(--bg-2); border: 1px solid var(--line);
  text-align: center;
}
.in2-status__icon  { font-size: 48px; line-height: 1; margin-bottom: 18px; }
.in2-status__title { font-size: clamp(28px, 3.4vw, 48px); font-weight: 900; letter-spacing: -0.02em; text-transform: uppercase; line-height: 1; }
.in2-status__sub   { color: var(--ink-dim); font-size: 15px; line-height: 1.55; margin: 16px auto; max-width: 56ch; }
.in2-status__ref   { font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: 0.22em; color: var(--ink-mute); text-transform: uppercase; padding: var(--space-2xs) var(--space-xs); background: var(--bg-3); border-inline-start: 2px solid var(--gold); display: inline-flex; gap: var(--space-3xs); }
/* JoinFormBlock.php prints a 🔖 emoji before the reference code. Same objection
   as the 🔒 on .summary__ssl: an OS emoji font painting a coloured glyph inside
   in2fitness-authored text. The code itself ("REF: A1B2C3D4") is Latin, so it
   deliberately keeps the mono face and its tracking in Arabic too.
   NOTE: the 48px .in2-status__icon above is left to the plugin — it is
   semantic (success / failure / pending) and needs three real marks, not a
   CSS trick. */
.in2-status__ref > span:first-child { display: none; }

/* The .in2-status__meta* rules stay in JoinFormBlock.php's inline <style> for
   now: that block prints inside <body>, after this file, so it wins the
   cascade at equal specificity, and the wizard lane is actively adding to it
   this pass. Relocating it here is a follow-up, together with the join.css
   extraction. */


/* ===== BRAND ACCENTS — NARROW APPLICATION =================================
   Website Review (2026-07-29), section 1 "Colour System".

   The brand doc lists teal and lime as supporting accents for
   freshness/recovery, but neither appeared anywhere on the site. They are
   introduced here deliberately scoped — orange stays the site-wide action
   colour, and these two only mark meaning:

     teal → Ladies segment
     lime → recovery / wellness

   Do not spread these beyond the selectors below; the same review's section 3
   asks for *restrained* colour application, and a third and fourth accent
   sprayed site-wide is exactly what it warns against. */

/* --- Teal: Ladies -------------------------------------------------------
   Today the only Ladies surface is the locations segment switch. When the
   dedicated Ladies page lands (review section 7, "Menu → Add a Ladies page")
   scope it with a .is-ladies wrapper and re-point --accent inside it, so the
   whole section inherits teal without duplicating every rule. */
.locations__tab[data-seg="ladies"].active {
  background: var(--teal);
  border-color: var(--teal);
  /* NOT var(--on-accent): this tab paints teal without being inside
     .is-ladies, so --on-accent would still resolve to the :root near-black. */
  color: var(--on-teal);
}
.locations__tab[data-seg="ladies"]:not(.active):hover {
  border-color: rgba(var(--teal-rgb), 0.55);
  color: var(--teal);
}
.branch[data-seg="ladies"] .branch__link:hover { color: var(--teal); }

/* Any subtree can opt into teal wholesale. Applied to the join-form root by
   frontend.js once the Ladies segment is picked, and ready for the Ladies page
   when it lands (review section 7).

   --gold/--gold-deep/--gold-soft MUST be redeclared here, not just --accent.
   Custom properties resolve at computed-value time on the element that
   declares them: :root's `--gold: var(--accent)` computes to orange *at :root*
   and descendants inherit that resolved colour, not the var() reference. So
   overriding --accent alone would leave all ~109 existing var(--gold) call
   sites orange. Overriding both is what actually flips the subtree. */
.is-ladies {
  --accent:      var(--teal);
  --accent-deep: #1F8F82;
  --accent-rgb:  var(--teal-rgb);

  --gold:      var(--teal);
  --gold-deep: #1F8F82;
  --gold-soft: rgba(var(--teal-rgb), 0.14);

  /* Black reads as a hole on teal. #04201d is the same value
     .locations__tab[data-seg="ladies"].active already hand-wrote — hoisting it
     into the token means every accent-backed control in the Ladies funnel
     (.pill.active, .step__num, .proceed, .summary__cta, .plan-opt--popular)
     picks it up without a per-selector override. */
  --on-accent: var(--on-teal);
}

/* Ladies segment card in the join form (in2fitness-join-us). The card carries
   data-gender="ladies" already, so this needs no markup change. Selecting it
   also puts .is-ladies on the form root, which turns the rest of the funnel
   teal via the block above. */
.gender-card[data-gender="ladies"]:hover { border-color: rgba(var(--teal-rgb), 0.45); }
.gender-card[data-gender="ladies"].active {
  border-color: var(--teal);
  background: linear-gradient(180deg, var(--bg-3), rgba(var(--teal-rgb), 0.10));
}
.gender-card[data-gender="ladies"].active .gender-card__title { color: var(--teal); }

/* --- Lime: recovery / wellness ------------------------------------------
   Hooked to the GX class post slug (wellness-classes), exposed as
   data-class-slug by blocks/gx-classes-grid/render.php. Substring match so
   a renamed/translated slug that still contains "wellness" keeps the accent. */
.class-card[data-class-slug*="wellness"] .class-card__num { color: var(--lime); }
.class-card[data-class-slug*="wellness"]:hover {
  border-color: rgba(var(--lime-rgb), 0.4);
}
.class-card[data-class-slug*="wellness"] .class-card__tag {
  border-color: rgba(var(--lime-rgb), 0.35);
}

/* ===== ACCENT BUDGET =====================================================
   Website Review 2026-07-29, section 3: "use [the accent] deliberately on key
   actions and moments rather than spreading them evenly across every section,
   which is what currently reads as flat/heavy."

   Measured before this change (AR homepage, % of elements painting accent):
     banner 3.8% · app-cta 5% · hero 10% · facilities 19% · about 55%

   The 55% section wasn't emphasising anything — it painted an orange bar on
   all six list items and an accent number on every card. Repetition at that
   density stops reading as emphasis and starts reading as background.

   THE RULE — accent is allowed on:
     1. Actions        — .btn--gold, .plan__cta, submit buttons
     2. Active states  — current nav item, selected tab/pill/segment, active dot
     3. Authored highlight — <em> in a heading, or a single key figure
     4. Semantic marks  — teal = Ladies, lime = recovery (see accent block above)

   NOT allowed:
     - Repeated per-item decoration (list borders, card index numbers, bullets,
       repeated glyphs) — this is what the rule exists to stop
     - Accent as a default border/rule colour — use --line / --line-2

   Known gap: a few sections still carry two or three <em> highlights in one
   heading. That is authored content (page-content-seeds.php and the Polylang
   string tables), not CSS, so it is a copy edit rather than a style fix — left
   open deliberately rather than silently reported as done.

   Rest state stays neutral; the accent arrives on hover/active, where it means
   something. Re-check with the density probe after touching accent colours.

   Anything below this line should be a deliberate exception with a reason. */

/* ===== DISPLAY-HEADING INK HEADROOM ======================================
   Website Review 2026-07-29, section 5, bug 1 — "Homepage hero: headline text
   is clipped at the top and overlaps the breadcrumb row above it."

   Root cause is structural, not specific to the hero: line-height < 1 makes the
   line box shorter than the em box, so ink sits above the element's own border
   box. Under an overflow:hidden ancestor it gets clipped; against a preceding
   element it collides.

   Measured before this rule (AR, 1728px — worst real clearance):

     .amenities__title    ink +3.6px above box, gap 0px   → clearance -3.6px
     .hero__title         ink  +17px above box, gap 28px  → clearance  11px
     .step-video__title   ink +7.6px above box, gap 24px  → clearance 16.4px
     .page-cta__heading   ink +3.4px above box

   Reserving the headroom on the element removes the dependency on font metrics
   entirely — swapping the Arabic face again cannot reintroduce the bug.

   Excluded deliberately: .section-head__ghost / .page-hero__ghost / the big
   benefit numerals. Those are absolutely-positioned decorative glyphs that are
   MEANT to bleed past their box, and padding would not move them anyway. */
.hero__title,
.page-hero__title,
.section-head h2,
.page-cta__heading,
.step-video__title,
.about__heading,
.amenities__title,
/* Added 2026-08-08: the post-payment status headline is line-height:1 at up to
   48px — the exact geometry this rule exists for — and was never on the list,
   so the Arabic success headline overhung its own box. */
.in2-status__title,
.app-cta__heading {
  padding-top: var(--ink-headroom);
}

/* .amenities__title is the only section heading that sits flush against its
   eyebrow (0px, where the others get 16-28px from .section-head). That is why
   it measured as the worst offender despite a modest overhang. Give it the
   same rhythm as the rest. */
.amenities__title { margin-top: var(--space-2xs); }

/* NOTE: do not "compensate" for the padding with a negative margin. Pulling the
   box up by the same amount the padding pushes the ink down returns the ink to
   exactly where it started, cancelling the fix while looking like it works.
   The headline is meant to sit slightly lower — that gap is the fix. */

/* ===== ARABIC LABEL TRACKING =============================================
   Companion to the --font-mono / --font-display override in body.rtl above.

   Swapping the font fixes the letterforms; the tracking still has to go.
   These labels carry 1.5-3.3px of Latin letter-spacing, which in a cursive
   script pushes glyphs off their join points — the second half of what the
   review saw as "garbled".

   CSS cannot scope tracking per-script, so these are enumerated. The list came
   from an audit of Arabic text sitting in Latin-only fonts across 8 pages; if a
   new small-caps label appears, re-run that audit and add it here.

   Extended 2026-08-08 (meeting item A6) with the join-flow labels that carry
   Latin tracking over Arabic but must KEEP their mono/display face because
   they hold DATA, not UI copy. .step__meta is the clearest case: it carries
   BOTH the Arabic segment name (step 1 breadcrumb) and digit-led Latin plan
   names (step 2), and the body.rtl --font-mono redefinition above already
   gives its Arabic run a Tajawal fallback. Forcing a font-family here would
   take the Latin plan names off JetBrains Mono and would fight the
   unicode-bidi: plaintext rule from the 2026-07-19 review. Same reasoning for
   .branch-card__* (city names, distances), .plan-opt__duration/__badge and
   .pay-opt__label (Sentinel brand names). .step__num is digits only — left
   alone entirely. */
body.rtl .step__meta,
body.rtl .pay-opt__label,
body.rtl .branch-card__name,
body.rtl .branch-card__location,
body.rtl .branch-card__dist,
body.rtl .branch-card__badge,
body.rtl .plan-opt__duration,
body.rtl .plan-opt__badge,
body.rtl .class-card__num,
body.rtl .class-card__tag,
body.rtl .plan__label,
body.rtl .plan__cta,
body.rtl .city-tab,
body.rtl .locations__tab,
body.rtl .faq-cat-tab,
body.rtl .contact-form__submit,
body.rtl .contact-info__label,
body.rtl .contact-info__small,
body.rtl .about__fac-count,
body.rtl .app-cta__badge-text,
body.rtl .hero__scroll,
body.rtl .pin__label,
body.rtl .field label,
body.rtl .hero__kicker,
body.rtl .hero__kicker span,
body.rtl .page-hero__ghost {
  letter-spacing: normal;
}
