/* Imperial Ground — shared styles for sub-pages. Keep in sync with index.html's <style>. */

/* FOUC prevention — pairs with the inline script in every main-site
   page's <head>. When the script detects a non-source locale (anything
   other than English today), it adds .i18n-loading to <html> before
   any body content paints. This rule then hides the body until either
   (a) i18n.js applies the dictionary and removes the class, or
   (b) the 1s safety timeout in the inline script removes it.
   Without this rule, the class would be a no-op and the user would
   see a flash of English text before the dict swap. */
html.i18n-loading body { visibility: hidden; }

/* THE `hidden` ATTRIBUTE MUST ACTUALLY HIDE.
   ---------------------------------------------------------------------------
   `hidden` is only `display: none` in the USER-AGENT stylesheet, so ANY
   author-level `display` declaration beats it, no matter how specific. An
   element with `hidden` and a class that sets `display: grid` is fully visible,
   and nothing warns you: the attribute is right there in the markup, and the
   JS setting `el.hidden = true` runs and does nothing.

   Found 2026-08-27 by João, on the worst possible page. A signed-out visitor
   opening /account got the sign-in card AND the entire member dashboard shell
   underneath it: the sidebar, "MY ACCOUNT", the nav (Overview, Start here,
   Profile, Kids, Membership & payments) and "Loading your dashboard...".
   `#loggedIn` carried `hidden` from first paint and `showLoggedOut()` set it
   again; `.account-grid { display: grid }` overrode both.

   Three classes in this repo declare `display` on elements the markup marks
   `hidden`: `.account-grid` (grid), `.nav-group` (flex) and `.status-banner`
   (flex). Rather than patch three call sites, make the attribute mean what it
   says everywhere, including on markup written later.

   `!important` is load-bearing and not a shortcut: without it this rule loses
   to the very declarations it exists to beat. Verified safe first, because it
   WOULD break an element shown via `style.display` while still carrying
   `hidden`: no element in public/js is toggled both ways. */
[hidden] { display: none !important; }

:root {
  /* Member-facing "white kimono Japanese" palette — REVERTED to the original
     paper / sumi ink / hinomaru-red on 2026-06-21 (the Concept 02 colour
     experiment was rolled back; only the new LOGO was kept). `--gold` is NAMED
     gold but the value is hinomaru RED — do not change to yellow. */
  --bg: #FCFDFE;             /* cream paper */
  --surface: #FFFFFF;
  --surface-2: #C7CFDA;
  --gold: #5A6473;           /* hinomaru red — primary accent */
  --gold-2: #454E5C;         /* deeper red — hover / pressed */
  /* Channel-only twins of the two above, for alpha washes:
     `rgba(var(--gold-rgb), 0.08)`. A wash cannot be expressed with the hex
     token alone, and writing the channels out by hand is what put 72 untracked
     copies of the brand colour in `public/`. Keep the values in sync with the
     hexes above; they are the same colour, split into channels. */
  --gold-rgb: 207, 197, 241;
  --gold-2-rgb: 167, 225, 215;
  --red: #1F2226;
  --text: #1F2226;           /* sumi ink */
  --muted: #4E5763;
  --line: #9DA8B6;           /* parchment hairline */
  /* Semantic status colors. RAG indicators across coach + admin
     dashboards. Distinct from --gold (which is brand-accent red, not
     yellow). 2026-05-09: introduced when sweeping the abandoned
     #C9A84C dark-gold scheme out of the codebase — code that used to
     reach for #C9A84C as an "amber" warning indicator should now use
     var(--warn). */
  --ok:        #22C55E;
  --warn:      #D97706;
  --warn-deep: #A66400;
  --danger:    #DC2626;
  /* Deeper functional red, for failure text and destructive controls that sit
     on a DARK surface (coach + admin), where #DC2626 is too hot. Holds the same
     value as --gold-2 today, so tokenising the coach surface against it is a
     pure refactor. It is deliberately a SEPARATE token: --gold-2 is brand and
     goes to ink in the monochrome move, this one is functional and stays red.
     See topics/active/plans/2026-07-29-monochrome-palette.md. */
  --danger-deep: #A62521;

  /* ── Silver + iridescent ramp (preview, 2026-08-03) ─────────────────────
     A third palette experiment. Silver is the MAIN colour; the mint and lilac
     are lifted straight off the logo's holographic treatment, which is
     Concept 02's turquoise #a7e1d7 and lilac #cfc5f1. So this is Concept 02's
     feel rebuilt on a cool silver base rather than a purple one.

     The raw mint and lilac are far too pale to carry text or a button, so the
     accent is the mint DEEPENED until it holds WCAG AA. The pale originals stay
     available for washes and tints only. Inert unless [data-palette="silver"]. */
  /* Near-white, not grey. The base WAS #F3F4F6, so every unbanded section was
     already grey and the banded ones were greyer: the whole page sat in fog and
     no amount of deepening the band could fix a grey ground. Against the band
     this reads 1.29:1 where the grey base read 1.20:1, and white cards finally
     have somewhere to be white. */
  --silver-paper: #FCFDFE;
  /* The accent gradient, DEEPENED. The raw logo pair measures 1.11:1 on the
     band, which is not low contrast, it is invisible: the accent word was
     disappearing in Programs, Pricing and Trial. These hold 3:1 large-text on
     every ground in the palette. The teal end is deliberately equal-ish in
     green and blue so it reads teal rather than the green that got rejected
     when a deepened mint was tried as the chrome accent. */
  --iris-mint-deep:  #237370;   /* deepened 2026-08-04: #27807F measured 2.98:1
                                  on the deepened band, just under the 3:1
                                  large-text floor. The violet end was fine. */
  --iris-lilac-deep: #6E5FA8;
  /* Value-stretched 2026-08-04. Silver has no hue shift to separate its two
     greys the way cream vs parchment separates the default's, so value has
     to do all the work: bands went from 1.09:1 to 1.20:1 against paper.
     The ceiling is the steel eyebrows, 0.72rem normal text sitting directly
     on the band in seven sections: #DBE1E8 keeps them at 4.55:1, one step
     deeper fails AA. Muted deepened with it, or it would have dropped to
     3.99:1 on the new band. Line deepened so hairlines read on both. */
  --silver-2:     #C7CFDA;
  --silver-line:  #9DA8B6;
  --silver-mid:   #A8B0B8;
  --silver-deep:  #4E5763;
  --silver-ink:   #1F2226;
  --iris-mint:    #A7E1D7;   /* straight off the logo, washes only */
  --iris-lilac:   #CFC5F1;   /* straight off the logo, washes only */
  --steel-accent: #5A6473;   /* THE ACCENT. Cool steel, 5.44:1 on paper. The
                                lightest value that still holds AA, so it reads
                                as silver rather than as dark grey. */
  --steel-accent-2: #454E5C; /* pressed, 7.64:1 */
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  background: var(--bg); color: var(--text);
  font-family: 'Inter', system-ui, sans-serif; font-weight: 300; line-height: 1.6;
  overflow-x: hidden;
}
h1, h2, h3, h4, .eyebrow, .btn {
  font-family: 'Oswald', sans-serif; font-weight: 600;
  letter-spacing: 0.02em; text-transform: uppercase;
}
h1 { font-size: clamp(2.5rem, 6vw, 5rem); line-height: 0.95; letter-spacing: -0.01em; }
h2 { font-size: clamp(2rem, 4vw, 3rem); line-height: 1; margin-bottom: 1rem; }
h3 { font-size: 1.5rem; letter-spacing: 0.03em; }
h4 { font-size: 1.1rem; letter-spacing: 0.08em; }
p { color: #6B6B6B; margin-bottom: 1rem; }
a { color: inherit; text-decoration: none; }

.container { max-width: 1200px; margin: 0 auto; padding: 0 32px; }
/* Section headings follow the hero: first line ink, accent word in the brand
   colour. why, facilities and pricing carried this as an inline style on the
   span; programs, founders, team, cta-banner and trial did not, so five of the
   eight rendered flat. One rule replaces the three inline styles and covers all
   eight. Deliberately NOT display:block, unlike .hero h1 .accent: the <br/> in
   the markup already breaks the line, and cta-banner and trial keep their
   accent inline, exactly as "One Roll" sits inline in the hero. */
h2 .accent { color: var(--gold); }
.eyebrow { color: var(--gold); font-size: 0.85rem; letter-spacing: 0.3em; font-weight: 500; margin-bottom: 1rem; display: block; }

/* NAV */
/* HOW TALL THE FIXED NAV IS, so pages can clear it exactly.
   ---------------------------------------------------------------------------
   The nav is `position: fixed`, so every page under it has to pad its own top
   by the nav's height. That height is not free to guess: it is content-driven,
   from the logo box plus .nav-inner's vertical padding plus the 1px border, and
   it changes at two breakpoints. Measured in a real browser 2026-08-27, and the
   arithmetic below matches to the pixel at every width from 320 to 1440:

       >= 761px   46 logo + 18*2 padding + 1 border = 83
       381-760px  46 logo + 12*2 padding + 1 border = 71
       <= 380px   38 logo + 12*2 padding + 1 border = 63

   ⚠ THIS LIVES NEXT TO THE NAV ON PURPOSE. The value is derived from the two
   declarations immediately below and from .logo-svg a few lines down. Keeping
   it in the page that consumes it is how /account ended up padding 140px to
   clear an 83px nav: a 57px gap under the top bar that nobody could trace back
   to a decision. If you change .nav-inner's padding or .logo-svg's height,
   change these three numbers in the same edit. */
:root { --nav-h: 83px; }
@media (max-width: 760px) { :root { --nav-h: 71px; } }
@media (max-width: 380px) { :root { --nav-h: 63px; } }

.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  background: rgba(255,255,255, 0.9); backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.nav-inner {
  max-width: 1280px; margin: 0 auto; padding: 18px 32px;
  display: flex; align-items: center; justify-content: space-between;
}
.logo {
  font-family: 'Oswald', sans-serif; font-weight: 700;
  font-size: 1.1rem; letter-spacing: 0.15em; text-transform: uppercase;
  display: flex; align-items: center; gap: 12px;
}
/* ── THE FOOTER MARK, 2026-09-01 ────────────────────────────────────────────
   This replaced `.logo-mark`, which was a CSS diamond containing the literal
   text "IG": a 2px border rotated 45deg with a counter-rotated span inside. It
   was not the brand mark. The brand mark is public/img/brand/logo-mark-black.svg
   and until now only the NAV used it, so every footer on the site rendered a
   hand-made lookalike, in 21 pages.

   ⚠ THE TELL WAS ALREADY IN THE REPO. /shop's HEADER carried the same fake and
   was fixed on 2026-08-27, described in its own comment as "the only page in the
   repo rendering the footer logo in its header". That framing is what hid this:
   the fix treated a site-wide footer problem as a one-page nav mistake, so the
   header was corrected and the 21 footers were not.

   ⚠ AND THE OLD RULE HAD BRAND-MARK PROTECTION IT DID NOT DESERVE. The note
   further down this file said ".logo-mark is deliberately NOT here. It is the
   brand mark, and a mark that changes colour with a theme is not a mark." The
   diamond was bordered in var(--gold), a token that has been gold, plum, red and
   now steel; the real emblem is a static SVG that genuinely never changes. The
   protection was pointed at the impostor.

   ⚠ EXPLICIT WIDTH AND HEIGHT, max-width:none, flex:none. Same three guards as
   .logo-svg above, for the same reason recorded there: the global
   `img { max-width: 100% }` collapses an SVG <img> to zero width inside a
   shrink-to-fit flex container. Do not "simplify" any of the three away. */
.foot-logo-svg {
  height: 36px; width: 36px;
  max-width: none; flex: 0 0 auto; display: block;
}
.logo small { display: block; font-size: 0.65rem; color: var(--muted); letter-spacing: 0.25em; margin-top: 2px; font-weight: 400; }
/* New SVG emblem (Brand Alignment 2026-06-21) — emblem-only crown mark, no
   wordmark text (the wordmark was illegible at nav size). The emblem.svg viewBox
   was tightly cropped to the artwork (no dead padding) + given intrinsic dims, so
   the box is all ink. EXPLICIT height AND width (0.866 ratio) — never `width:auto`,
   which can collapse an `<img>` SVG to a speck in some browsers. */
/* CRITICAL: max-width:none + flex:none — a global `img { max-width:100% }` rule
   collapses this SVG <img> to 0 width inside the shrink-to-fit flex `.logo`
   container (circular intrinsic-size dependency). That collapse is what made the
   logo vanish/look tiny before. */
/* translateX (not margin) nudges ONLY the logo left — margin would reflow the bar. */
.logo-svg { height: 46px; width: 46px; max-width: none; flex: 0 0 auto; display: block; transform: translateX(-10px); }
@media (max-width: 380px) { .logo-svg { height: 38px; width: 38px; } }
.nav-links { display: flex; gap: 26px; align-items: center; list-style: none; }
.nav-links a {
  font-family: 'Oswald', sans-serif; font-size: 0.85rem;
  letter-spacing: 0.18em; text-transform: uppercase;
  font-weight: 500; color: #1A1A1A; transition: color 0.2s; position: relative;
}
.nav-links a:hover { color: var(--gold); }
.lang { display: flex; gap: 8px; font-size: 0.75rem; color: var(--muted); }
.lang span.active { color: var(--gold); }

/* Mobile nav: pre-existing layout pushed past the viewport (logo + 3 links
   + 4 flags + cart icon = ~600px on a 390px screen). With body's overflow-x
   clip, the right half just disappeared. Compact on phones, drop the
   language flags (only EN + PT shipped so far), shrink the logo. */
@media (max-width: 760px) {
  .nav-inner { padding: 12px 16px; gap: 8px; }
  .nav-links { gap: 14px; flex-wrap: wrap; justify-content: flex-end; }
  .nav-links a {
    font-size: 0.7rem; letter-spacing: 0.14em;
  }
  .nav-links .lang { display: none; }
  .logo { font-size: 0.9rem; gap: 8px; letter-spacing: 0.12em; }
  .foot-logo-svg { height: 30px; width: 30px; }
  .icon-btn { width: 36px; height: 36px; }
}
@media (max-width: 380px) {
  /* Tiniest devices: drop the wordmark, keep just the IG diamond + cart. */
  .logo span:not(.logo-mark) { display: none; }
}

.btn {
  display: inline-block; padding: 14px 28px; font-size: 0.85rem;
  letter-spacing: 0.2em; text-transform: uppercase; font-weight: 600;
  background: var(--gold); color: #ffffff; border: 2px solid var(--gold);
  cursor: pointer; transition: all 0.25s; font-family: 'Oswald', sans-serif;
}
.btn:hover { background: transparent; color: var(--gold); }
.btn.outline { background: transparent; color: var(--text); border-color: var(--text); }
.btn.outline:hover { background: var(--gold); border-color: var(--gold); color: #ffffff; }

/* Nav-specific Free Trial CTA — refined gold ghost pill with a pulsing dot. */
.btn-trial-nav {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 18px 9px 16px;
  font-family: 'Oswald', sans-serif; font-weight: 600;
  font-size: 0.78rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); background: transparent;
  border: 1.5px solid var(--gold);
  cursor: pointer;
  transition: background 0.3s, color 0.3s, box-shadow 0.3s, transform 0.25s;
}
.btn-trial-nav::after { content: '→'; font-size: 0.95rem; letter-spacing: 0; transition: transform 0.25s; }
/* Specificity bump — see matching block in public/index.html. The bare
   .btn-trial-nav:hover loses to .nav-links a:hover (element selector
   pushes it ahead by 1), so we qualify with .nav-links to match + win
   on source order. Otherwise the FREE TRIAL text disappears on hover
   (red on red). */
.nav-links a.btn-trial-nav:hover {
  background: var(--gold); color: #ffffff;
  box-shadow: 0 8px 22px rgba(var(--gold-rgb), 0.22);
  transform: translateY(-1px);
}
.nav-links a.btn-trial-nav:hover::after { transform: translateX(3px); }
.btn-trial-nav .dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--gold); flex: 0 0 auto;
  animation: btnTrialPulse 2.2s ease-in-out infinite;
}
.btn-trial-nav:hover .dot { background: #ffffff; animation: none; }
@keyframes btnTrialPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--gold-rgb), 0.55); }
  50%      { box-shadow: 0 0 0 6px rgba(var(--gold-rgb), 0); }
}

/* Language switcher with flags */
.lang a {
  font-size: 1.1rem; line-height: 1; filter: grayscale(0.5); opacity: 0.65;
  transition: filter 0.2s, opacity 0.2s;
}
.lang a:hover { filter: grayscale(0); opacity: 1; }
.lang a.active { filter: grayscale(0); opacity: 1; }

.icon-btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; color: #1A1A1A;
  border: 1px solid var(--line); transition: all 0.2s;
}
.icon-btn:hover { color: var(--gold); border-color: var(--gold); background: rgba(var(--gold-rgb), 0.08); }

/* Sign In — labeled nav pill. Secondary CTA sibling to .btn-trial-nav: kept
   visually quieter (neutral outline, no pulse, no directional arrow) so Free
   Trial remains the dominant call-to-action for new visitors while returning
   members have an unmistakable labeled entry point. Promoted from a tiny
   person-silhouette icon that testers couldn't find. */
.btn-signin-nav {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px 9px 14px;
  font-family: 'Oswald', sans-serif; font-weight: 600;
  font-size: 0.78rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--text); background: transparent;
  border: 1.5px solid var(--line);
  cursor: pointer; white-space: nowrap;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.btn-signin-nav svg { width: 16px; height: 16px; flex: 0 0 auto; }
.btn-signin-nav:hover { color: var(--gold); border-color: var(--gold); background: rgba(var(--gold-rgb), 0.08); }

/* Logged-in modifier: same .btn-signin-nav pill geometry, just flipped to
   red-fill so the state is visually distinct without changing dimensions
   (rebuilt 2026-04-26 — was a separate .btn-member-chip 40x40 square that
   reflowed the nav on signin). All responsive rules on .btn-signin-nav
   carry through automatically because the base class is preserved. The
   label text (.signin-label) is replaced with the member's initials by
   member-nav.js. Status-colour overrides (pending/blocked) are applied
   inline by member-nav.js on top of this. */
.btn-signin-nav--member {
  background: var(--gold);
  color: #fff;
  border-color: var(--gold);
}
.btn-signin-nav--member:hover {
  background: var(--gold);
  color: #fff;
  border-color: var(--gold);
  filter: brightness(0.92);
}

/* Legacy .btn-member-chip rules — kept as no-op fallback in case a
   cached older member-nav.js is briefly served alongside fresh CSS. Can
   be removed in a future sweep once the cache window has elapsed. */
.btn-member-chip {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--gold); color: #fff;
  border: 1.5px solid var(--gold);
  padding: 9px 16px 9px 14px;
  font-family: 'Oswald', sans-serif; font-weight: 700;
  font-size: 0.78rem; letter-spacing: 0.18em; text-transform: uppercase;
  cursor: pointer;
  transition: filter 0.2s;
}
.btn-member-chip:hover { filter: brightness(0.92); }

/* On narrow phones the label gets in the way of Free Trial. Drop it and keep
   the icon — at this point the user already knows it's the account button
   because Free Trial is right next to it and clearly distinct. */
@media (max-width: 480px) {
  .btn-signin-nav .signin-label { display: none; }
  .btn-signin-nav { padding: 9px 11px; gap: 0; }
}
.cart-badge {
  position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px;
  background: var(--red); color: #fff; border-radius: 50%;
  font-family: 'Oswald', sans-serif; font-size: 0.7rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center; padding: 0 4px;
  border: 2px solid var(--bg);
}
.cart-badge.hide { display: none; }

/* PAGE HERO (shorter than home hero) */
.page-hero {
  position: relative; padding: 180px 0 80px;
  background: linear-gradient(135deg, #FFFFFF 0%, #ffffff 70%);
  overflow: hidden; border-bottom: 1px solid var(--line);
}
.page-hero::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 20% 0%, rgba(var(--gold-rgb), 0.15), transparent 60%);
}
.page-hero-inner { position: relative; z-index: 2; max-width: 900px; }
.breadcrumbs {
  font-family: 'Oswald', sans-serif; font-size: 0.75rem;
  letter-spacing: 0.25em; text-transform: uppercase; color: var(--muted); margin-bottom: 1rem;
}
.breadcrumbs a { color: var(--muted); }
.breadcrumbs a:hover { color: var(--gold); }
.breadcrumbs .sep { margin: 0 10px; color: var(--line); }

section { padding: 80px 0; position: relative; }
.section-head { max-width: 700px; margin-bottom: 50px; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-sub { color: var(--muted); font-size: 1.05rem; margin-top: 12px; }

.content-block { max-width: 820px; }
.content-block p { font-size: 1.05rem; color: #6B6B6B; margin-bottom: 1.2rem; }
.content-block h2 { margin-top: 2.5rem; }
.content-block h3 { margin-top: 2rem; margin-bottom: 0.75rem; color: var(--gold); }
.content-block ul, .content-block ol { padding-left: 1.5rem; margin-bottom: 1.2rem; color: #6B6B6B; }
.content-block ul li, .content-block ol li { padding: 6px 0; }
.content-block ul li::marker { color: var(--gold); }

/* Info cards grid */
.card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.info-card {
  background: var(--surface-2); padding: 36px 32px; border: 1px solid var(--line);
  border-top: 3px solid var(--gold); transition: transform 0.3s;
}
.info-card:hover { transform: translateY(-4px); }
.info-card .num {
  font-family: 'Oswald', sans-serif; font-size: 3rem; color: var(--gold);
  font-weight: 700; line-height: 1; margin-bottom: 14px;
}
.info-card h3 { margin-bottom: 12px; }
.info-card p { color: #6B6B6B; font-size: 0.95rem; }

/* Split blocks */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: start; }
.split.alt { direction: rtl; }
.split.alt > * { direction: ltr; }

.photo-placeholder {
  background: linear-gradient(135deg, #FFFFFF, #ffffff);
  aspect-ratio: 4/3; border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  background-image:
    repeating-linear-gradient(45deg, transparent 0 40px, rgba(var(--gold-rgb), 0.03) 40px 41px);
  color: var(--muted); font-family: 'Oswald', sans-serif;
  letter-spacing: 0.2em; font-size: 0.85rem; text-transform: uppercase;
}

/* Table / schedule-style */
.mini-schedule {
  width: 100%; border-collapse: collapse; font-family: 'Oswald', sans-serif;
}
.mini-schedule th, .mini-schedule td {
  padding: 16px 14px; text-align: left; border: 1px solid var(--line);
  font-size: 0.9rem; letter-spacing: 0.05em;
}
.mini-schedule th {
  background: var(--surface); color: var(--gold); text-transform: uppercase;
  letter-spacing: 0.2em; font-size: 0.78rem;
}

/* Belt row */
.belts { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; margin: 40px 0; }
.belt {
  padding: 30px 16px; text-align: center; border-right: 1px solid var(--line);
  position: relative;
}
.belt:last-child { border-right: 0; }
.belt-bar { height: 8px; margin-bottom: 20px; position: relative; }
.belt-bar::after { content: ''; position: absolute; right: 10%; top: 0; bottom: 0; width: 15%; background: #000; }
.belt.white .belt-bar { background: #ffffff; }
.belt.blue .belt-bar  { background: #1e6bb8; }
.belt.purple .belt-bar{ background: #6a3b9c; }
.belt.brown .belt-bar { background: #6b3e12; }
.belt.black .belt-bar { background: #000; border: 1px solid #333; }
/* Black belt: tip overrides the default #000 with red. Standard tip would
   be invisible on a black bar, and BJJ tradition labels black belts with
   a red tag. Uses the site's hinomaru-red --gold accent. */
.belt.black .belt-bar::after { background: var(--gold); }

/* ─── Multi-select chip pattern (used by /account profile sections) ─────
   Reusable pill UI. Used by:
     - /account → Profile → BJJ profile (account-profile.js)
     - /account → Profile → Health info (account-profile-contacts.js)
   Per-section typography (font-family, letter-spacing, text-transform)
   stays inline at the call site; behavior + accent come from here. Lived
   inside #bjjProfileBody until 2026-05-02 — moved out so the health
   chips actually toggle visually on click. */
.pf-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.pf-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--line, #E5E1D6);
  background: var(--surface, #FFFFFF);
  color: var(--text, #1A1A1A);
  font-size: 13px; cursor: pointer;
  transition: all 0.15s; user-select: none;
}
.pf-chip:hover { border-color: var(--gold); }
.pf-chip.is-on {
  border-color: var(--gold);
  background: var(--gold);
  color: #FFFFFF;
}
.belt h4 { font-family: 'Oswald', sans-serif; letter-spacing: 0.15em; }
.belt p { font-size: 0.8rem; color: var(--muted); margin-top: 8px; }

/* CTA */
.cta-banner {
  padding: 100px 0; background: var(--bg); position: relative; overflow: hidden;
}
.cta-banner::before {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(255,255,255,0.85), rgba(255,255,255,0.6)),
    radial-gradient(ellipse at center right, rgba(var(--gold-rgb), 0.18), transparent 60%);
}
.cta-inner { position: relative; z-index: 2; text-align: center; max-width: 800px; margin: 0 auto; }
.cta-inner h2 span { color: var(--gold); }
.cta-inner p { font-size: 1.1rem; margin-bottom: 2rem; color: #6B6B6B; }

/* FOOTER */
footer { background: #ffffff; padding: 60px 0 32px; border-top: 1px solid var(--line); }
.foot-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 48px; margin-bottom: 40px; }
.foot-col h4 { color: var(--gold); margin-bottom: 16px; font-size: 0.9rem; letter-spacing: 0.2em; }
.foot-col ul { list-style: none; }
.foot-col ul li { padding: 5px 0; color: var(--muted); font-size: 0.88rem; }
.foot-col a { color: var(--muted); }
.foot-col a:hover { color: var(--gold); }
.foot-brand p { color: var(--muted); margin-top: 14px; max-width: 320px; font-size: 0.9rem; }
.foot-bottom {
  padding-top: 24px; border-top: 1px solid var(--line);
  display: flex; justify-content: space-between; color: var(--muted); font-size: 0.82rem; flex-wrap: wrap; gap: 16px;
}

/* CHAT + MODAL (identical to index.html) */
.chat-fab {
  position: fixed; bottom: 28px; right: 28px; z-index: 150;
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--gold); color: #ffffff; border: 0;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: 0 10px 30px rgba(0,0,0,0.4);
  animation: chatPulse 2.6s infinite;
}
@keyframes chatPulse {
  0% { box-shadow: 0 10px 30px rgba(0,0,0,0.4), 0 0 0 0 rgba(var(--gold-rgb), 0.55); }
  70% { box-shadow: 0 10px 30px rgba(0,0,0,0.4), 0 0 0 18px rgba(var(--gold-rgb), 0); }
  100% { box-shadow: 0 10px 30px rgba(0,0,0,0.4), 0 0 0 0 rgba(var(--gold-rgb), 0); }
}
.chat-panel {
  position: fixed; bottom: 110px; right: 28px; z-index: 149;
  width: 380px; max-width: calc(100vw - 32px);
  height: 560px; max-height: calc(100vh - 150px);
  background: var(--surface); border: 1px solid var(--line); border-top: 3px solid var(--gold);
  display: none; flex-direction: column; overflow: hidden;
  box-shadow: 0 24px 64px rgba(0,0,0,0.26);
}
.chat-panel.open { display: flex; animation: chatRise 0.22s ease both; }
@keyframes chatRise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.chat-head {
  padding: 15px 18px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 11px;
  background: var(--surface-2); flex: none;
}
.chat-head .dot {
  width: 9px; height: 9px; border-radius: 50%; background: #3CA85A; flex: none;
  box-shadow: 0 0 0 3px rgba(60,168,90,0.18);
}
.chat-head strong { font-family: 'Oswald', sans-serif; letter-spacing: 0.12em; text-transform: uppercase; font-size: 0.86rem; color: var(--text); line-height: 1.1; }
.chat-head small { color: var(--muted); font-size: 0.72rem; display: block; margin-top: 3px; }
.chat-close { margin-left: auto; background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 1.5rem; line-height: 1; padding: 0 2px; transition: color 0.15s; }
.chat-close:hover { color: var(--text); }

.chat-body {
  flex: 1; padding: 18px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 10px; background: var(--bg);
}
.chat-body::-webkit-scrollbar { width: 8px; }
.chat-body::-webkit-scrollbar-thumb { background: var(--line); }
.chat-body::-webkit-scrollbar-track { background: transparent; }

.chat-msg {
  font-size: 0.9rem; line-height: 1.5; padding: 10px 13px;
  max-width: 84%; width: fit-content; word-wrap: break-word;
  border: 1px solid transparent;
  animation: chatMsgIn 0.18s ease both;
}
@keyframes chatMsgIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.chat-msg.bot { background: var(--surface); color: var(--text); border-color: var(--line); align-self: flex-start; }
.chat-msg.user { background: var(--text); color: var(--surface); align-self: flex-end; margin-left: auto; }

/* Typing indicator — three pulsing dots in a bot bubble (empty while streaming). */
.chat-msg.typing { color: transparent; min-width: 46px; min-height: 21px; position: relative; }
.chat-msg.typing::after {
  content: ''; position: absolute; left: 14px; top: 50%; margin-top: -3px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--muted);
  box-shadow: 11px 0 var(--muted), 22px 0 var(--muted);
  animation: chatTyping 1.1s infinite ease-in-out;
}
@keyframes chatTyping { 0%, 70%, 100% { opacity: 0.28; } 35% { opacity: 0.9; } }

/* Inline suggestion chips streamed by the bot (event: meta {quickReplies}).
   Distinct from the persistent bottom quick-bar: gold outline that fills on
   hover, so they read as "tap to reply". Left-aligned under the latest reply. */
.chat-replies { display: flex; flex-wrap: wrap; gap: 7px; align-self: flex-start; max-width: 100%; animation: chatMsgIn 0.18s ease both; }
.chat-reply {
  background: var(--surface); color: var(--gold);
  border: 1px solid var(--gold); padding: 6px 12px;
  font-family: 'Inter', sans-serif; font-size: 0.8rem; cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.chat-reply:hover { background: var(--gold); color: #ffffff; }

.chat-quick {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 11px 14px; border-top: 1px solid var(--line); background: var(--surface-2); flex: none;
}
.chat-quick button {
  background: var(--surface); color: var(--muted);
  border: 1px solid var(--line); padding: 7px 12px;
  font-family: 'Inter', sans-serif; font-size: 0.78rem; cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.chat-quick button:hover { color: var(--gold); border-color: var(--gold); }

.chat-input { display: flex; border-top: 1px solid var(--line); background: var(--surface); flex: none; }
.chat-input input { flex: 1; background: var(--surface); border: 0; padding: 14px 16px; color: var(--text); font-family: 'Inter', sans-serif; font-size: 0.9rem; }
.chat-input input::placeholder { color: var(--muted); }
.chat-input input:focus { outline: none; }
.chat-input button {
  background: var(--gold); color: #ffffff; border: 0; padding: 0 22px;
  font-family: 'Oswald', sans-serif; letter-spacing: 0.15em; text-transform: uppercase; font-size: 0.8rem;
  cursor: pointer; transition: background 0.15s;
}
.chat-input button:hover { background: #B02824; }

/* Hamburger button (hidden on desktop) */
.hamburger { display: none; background: none; border: none; color: var(--text); cursor: pointer; font-size: 1.5rem; padding: 4px 8px; }
.nav-links li:has(.icon-btn) + li:has(.icon-btn) { margin-left: -24px; }

/* Intermediate desktop widths — between the hamburger breakpoint (≤700px)
   and the width where the full nav fits cleanly (~1280px). Without these
   rules, the rightmost item (the FREE TRIAL CTA, the most conversion-
   critical button on the site) gets clipped on narrower laptop screens
   like ~1280px Safari + system chrome.
   Strategy: progressively drop the lowest-priority clusters (language
   flags first, then social/cart icons, then tighten the page-link spacing)
   so Sign In + Free Trial always survive. */
@media (max-width: 1280px) and (min-width: 701px) {
  /* Language flags are aspirational today — only EN ships, PT is planned.
     The DE/ES flags render disabled. They're the cheapest thing to drop. */
  .nav-links .lang { display: none; }
}
@media (max-width: 1100px) and (min-width: 701px) {
  /* Social + cart icons live in the footer too. The Cart is for a shop
     currently hidden, so it's a no-op visual today anyway. Drop them and
     tighten the page-link spacing. */
  .nav-links li:has(.icon-btn) { display: none; }
  .nav-links { gap: 18px; }
  .nav-links a { font-size: 0.78rem; letter-spacing: 0.14em; }
}
@media (max-width: 900px) and (min-width: 701px) {
  /* Final compaction before hamburger kicks in at ≤700px. */
  .nav-links { gap: 12px; }
  .nav-links a { font-size: 0.72rem; letter-spacing: 0.12em; }
  .btn-trial-nav { padding: 8px 14px; font-size: 0.72rem; letter-spacing: 0.16em; }
  .btn-signin-nav { padding: 8px 12px; font-size: 0.72rem; }
}

@media (max-width: 1024px) {
  .split { grid-template-columns: 1fr; }
  .card-grid { grid-template-columns: 1fr 1fr; }
  .foot-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 700px) {
  .nav .nav-inner { position: relative; }
  .nav-links {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-wrap: wrap; align-items: center; gap: 0;
    background: rgba(255,255,255,0.98); border-top: 1px solid var(--line);
    padding: 4px 20px 16px;
    max-height: calc(100vh - 70px); overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .nav-links.open { display: flex; }
  .nav-links li { flex: 1 1 100%; border-bottom: 1px solid var(--line); }
  .nav-links li a { display: block; padding: 14px 4px; font-size: 0.95rem; }
  .nav-links li.lang { display: flex; gap: 16px; padding: 14px 4px; border-bottom: 1px solid var(--line); }
  .nav-links li.lang a { display: inline; padding: 0; font-size: 1.2rem; }
  .nav-links a::after { display: none; }

  .nav-links li:has(.icon-btn) {
    flex: 0 0 auto; padding: 14px 0 4px; margin-right: 10px;
    border-bottom: 0;
  }
  .nav-links li:has(.icon-btn) + li:has(.icon-btn) { margin-left: 0; }
  .nav-links li:has(.icon-btn) a {
    padding: 10px 14px; border: 1px solid var(--line);
    display: inline-flex; align-items: center;
  }
  .nav-links li:has(.icon-btn) a:hover { border-color: var(--gold); }

  /* Sign In: full-width outlined pill on its own row, above Free Trial. Undo
     the narrow-phone ≤480px label-collapse — hamburger menu has the room. */
  .nav-links li:has(.btn-signin-nav) {
    flex: 1 1 100%; margin-top: 12px;
    border-bottom: 0;
  }
  .nav-links li:has(.btn-signin-nav) .btn-signin-nav {
    display: flex; justify-content: center; padding: 14px;
    width: 100%; gap: 8px;
  }
  .nav-links li:has(.btn-signin-nav) .signin-label { display: inline; }

  .nav-links li:has(.btn-trial-nav) {
    flex: 1 1 100%; margin-top: 10px;
    border-bottom: 0;
  }
  .nav-links li:has(.btn-trial-nav) a {
    display: flex; justify-content: center; padding: 14px;
  }

  .hamburger { display: block; }
  .hamburger.open { color: var(--gold); }

  .card-grid, .foot-grid { grid-template-columns: 1fr; }
  .belts { grid-template-columns: repeat(5, 1fr); }
  .container { padding: 0 20px; }
  section { padding: 60px 0; }
}

/* ── Silver preview ──────────────────────────────────────────────────────
   Opt in with ?palette=silver. Same mechanism as the monochrome preview: the
   member tokens are repointed and nothing else changes, so the shipped default
   is untouched.

   Silver leads AND is the accent. The logo's iridescence appears only as a
   low-opacity wash, which is where "a bit of colour from the logo" belongs. Every pair below was
   contrast-checked rather than eyeballed: text 14.5:1, muted 4.6:1, accent
   5.4:1 on paper and 6.0:1 on white, all AA. That check matters more here than
   on the red scheme, because a silver base narrows the range everything else
   has to work in. */
:root[data-palette="silver"] {
  --bg:         var(--silver-paper);
  --surface:    #FFFFFF;
  --surface-2:  var(--silver-2);
  --line:       var(--silver-line);
  --text:       var(--silver-ink);
  --muted:      var(--silver-deep);
  /* The accent is SILVER, not the mint. Silver is the whole point of this
     palette; a deepened mint read as green and buried the idea. */
  --gold:       var(--steel-accent);
  --gold-2:     var(--steel-accent-2);
  /* DELIBERATELY NOT the channel twin of --gold. These channels drive the
     low-opacity hero washes, and this is the one place the logo's colour
     belongs: a lilac tint behind silver chrome, rather than a grey wash that
     would say nothing. The accent stays steel; only the wash is iridescent.
     Lilac #CFC5F1, straight off the logo. */
  --gold-rgb:   207, 197, 241;
  --gold-2-rgb: 167, 225, 215;   /* mint #A7E1D7, secondary washes */
  --red:        var(--silver-ink);
}

/* ── Silver: where the logo's colour actually appears ────────────────────
   The wash channels above sit at 0.03 to 0.22 alpha, so a lilac tint on a
   silver ground is invisible in practice. Putting the logo's colour ONLY there
   would have been a claim rather than a design.

   So it goes on the card's 3px top stripe, the brand's signature device, as a
   mint-to-lilac gradient: literally the logo's holographic treatment, on the one
   element every card already carries. A 3px rule holds no text, so no contrast
   rule applies and the pale originals can be used at full strength.

   border-image rather than border-top, because a border colour cannot be a
   gradient. The border-top width declaration must survive for it to render.

   The list was derived by parsing both stylesheets rather than recalled. It is
   every framed BOX: the four that already carried a 3px gold stripe (.info-card,
   .chat-panel, .modal, .form-box) plus the content cards that only ever had a
   plain 1px --line border and no stripe at all (.prog, .price-card, .coach,
   .founder, .faq-item, .faq-cta, .map-embed, .photo-placeholder). Those gain a
   3px top edge here, which is the point: the trial form had the treatment and
   the programme and price cards did not.

   Deliberately NOT included, because they are controls and content rather than
   cards, and a gradient frame on them would read as noise: .icon-btn, form
   inputs, table cells, .coach-tags li, .legend-swatch, .social a, nav links,
   .chat-quick button. If you add a new CARD, add it here too. */
:root[data-palette="silver"] .info-card,
:root[data-palette="silver"] .chat-panel,
:root[data-palette="silver"] .modal,
:root[data-palette="silver"] .form-box,
:root[data-palette="silver"] .card,
:root[data-palette="silver"] .prog,
:root[data-palette="silver"] .price-card,
:root[data-palette="silver"] .coach,
:root[data-palette="silver"] .founder,
:root[data-palette="silver"] .faq-item,
:root[data-palette="silver"] .faq-cta,
:root[data-palette="silver"] .map-embed,
:root[data-palette="silver"] .why-card,
:root[data-palette="silver"] .photo-placeholder {
  border-image: linear-gradient(90deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%) 1;
  border-image-slice: 1;
  border-top-width: 3px;
  border-left-width: 1px;
  border-right-width: 1px;
  border-bottom-width: 1px;
  border-style: solid;
}
/* Eyebrows stay STEEL, not a deepened mint. A readable mint is a green, which
   is the thing this palette is not. The stripe is the only place the logo's
   colour appears, and keeping it to one place is what stops it becoming
   decoration again. */

/* ── Silver: the values mosaic and the stat dividers ─────────────────────
   Experiment, silver preview only.

   The ten virtue tiles are NOT framed individually. .values-grid is a gapless
   mosaic: gap:1px over a background, so the "gaps" are the hairlines, showing
   the container through. Framing each tile would double every interior seam and
   print ten 3px stripes down the middle of the block. So the gradient goes on
   the CONTAINER and the seams sample it: the horizontal rule sweeps the whole
   mint-to-lilac ramp, the four vertical rules each step through it. One stripe
   over the whole grid, not ten.

   The stat dividers are the same device (a hairline, not a frame), so they take
   the ramp vertically rather than being left grey beside a coloured mosaic.
   .legend-swatch is deliberately excluded: those outline belt colours, and belt
   colours are content, not chrome. */
:root[data-palette="silver"] .values-grid {
  background: linear-gradient(90deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%);
  border-image: linear-gradient(90deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%) 1;
  border-image-slice: 1;
  border-top-width: 3px;
  border-right-width: 0;
  border-bottom-width: 0;
  border-left-width: 0;
  border-style: solid;
}
/* The kana line stays steel. At 0.75rem, mint on paper is about 1.5:1 and
   simply cannot be read; the seam beside it carries the colour instead. */
:root[data-palette="silver"] .stat,
:root[data-palette="silver"] .founder-stat {
  border-image: linear-gradient(180deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%) 1;
  border-image-slice: 1;
}

/* The pull-quote and the location panel carry a 3px LEFT accent bar rather than
   a frame, so they take the ramp vertically. Same reasoning as the why-card
   bar: a 3px column sampling a 90deg gradient would be one flat colour. */
:root[data-palette="silver"] .testi,
:root[data-palette="silver"] .loc-info,
:root[data-palette="silver"] .founder-quote,
:root[data-palette="silver"] .price-note {
  border-image: linear-gradient(180deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%) 1;
  border-image-slice: 1;
  border-left-width: 3px;
  border-style: solid;
  border-top-width: 0;
  border-right-width: 0;
  border-bottom-width: 0;
}

/* ── Silver: everything else the ramp has to reach ───────────────────────
   Experiment, silver preview only.

   Found by scanning the sheet for the PROPERTY that makes a thing framed,
   border: Npx solid var(--gold), rather than by guessing at class names. That
   turned up 22 rules, of which these were still steel while their neighbours
   had gone iridescent. Guessing found the cards; only the property scan found
   the tags, badges and portrait corners.

   The brand mark is deliberately NOT here, and it is now .foot-logo-svg /
   .logo-svg: an SVG asset, so there is no colour for a palette to reach. This
   note used to name .logo-mark, a CSS diamond bordered in var(--gold), which
   means the thing it protected from theme colour WAS a theme colour. See the
   .foot-logo-svg block above. */
/* Keep their own bar widths: the shared rule above sets 3px for .testi and
   .loc-info, but these two are 2px and a 1px change would nudge their text. */
:root[data-palette="silver"] .founder-quote,
:root[data-palette="silver"] .price-note { border-left-width: 2px; }

:root[data-palette="silver"] .btn-member-chip,
:root[data-palette="silver"] .prog-icon,
:root[data-palette="silver"] .prog-tag,
:root[data-palette="silver"] .founder-badge,
:root[data-palette="silver"] .coach-portrait .coach-tag,
:root[data-palette="silver"] .recruit-cta {
  border-image: linear-gradient(135deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%) 1;
  border-image-slice: 1;
  color: var(--steel-accent);
}
/* The portrait corner brackets are an L, top and right only, so a 135deg ramp
   would put both visible edges at nearly the same point on it. 90deg instead:
   the top edge sweeps and the right edge lands on lilac. */
:root[data-palette="silver"] .founder-portrait::after,
:root[data-palette="silver"] .coach-portrait::after {
  border-image: linear-gradient(90deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%) 1;
  border-image-slice: 1;
}

/* ── Silver: every heading is INK ────────────────────────────────────────
   Experiment, silver preview only.

   Reversed 2026-08-04 on João's call: headings are black, not steel. They had
   been steel since the palette went in, and the reason for changing is the
   deepened band. Steel on the new #DBE1E8 measures 4.55:1, which passes AA but
   only just, and a heading that merely passes is a heading that stops carrying
   the page. Ink is 12.13:1 on the same band and 14.51:1 on paper.

   All six levels, not only the three named, because leaving h4 steel would put
   the ten virtues in a different colour from every other card title and
   recreate exactly the half-steel mix that was called out before.

   One rule rather than a patch per card. :root[data-palette] scores 0,2,1 and
   the card rules that set colour on their own titles are 0,1,1, so this wins
   on specificity without !important and without touching each one.

   Silver has not left the page: it still carries the eyebrows, the coach
   roles, the icons and the button labels, which is where an accent belongs.
   Headings are structure, and structure reads best in ink. This is a hierarchy
   decision and not a contrast ceiling. */
/* The eyebrow is 0.72rem NORMAL text sitting directly on a band, and at
   #5A6473 it was the single thing capping how dark the band could go. The
   deeper steel is already in the palette as --gold-2 and holds 5.35:1 on
   the new band. --gold itself is unchanged, so buttons and icons do not
   darken with it. */
:root[data-palette="silver"] .eyebrow { color: var(--gold-2); }

:root[data-palette="silver"] h1,
:root[data-palette="silver"] h2,
:root[data-palette="silver"] h3,
:root[data-palette="silver"] h4,
:root[data-palette="silver"] h5,
:root[data-palette="silver"] h6 {
  color: var(--text);
}

/* ── Silver: the landmark band ───────────────────────────────────────────
   Experiment, silver preview only.

   One section gets a whisper mint-tinted band, #DBE7E3, instead of the plain
   grey: Facilities, the newest asset. It gives the page a landmark and the
   logo colour one legitimate home beyond the washes. Same value as the grey
   band, so the rhythm holds; the difference is hue alone.

   It also repairs a rhythm break the section reorder introduced: facilities,
   schedule and founders were three paper sections in a row. The tint breaks
   the triple.

   Cards inside must go WHITE: their normal band fill measures 1.04:1 against
   the tint, invisible. White is 1.27:1. Muted text on the tint is 4.82:1. */

:root[data-palette="silver"] #facilities .why-card { background: var(--surface); }

/* ── Silver: cards sit ON the page, not in it ────────────────────────────
   The hairline is structurally weak on a band, even at #9DA8B6 it only reaches
   1.69:1 there, so past a point more colour buys nothing. A shadow separates
   without spending any contrast budget at all, which is why it is the right
   third lever rather than a darker line.

   Free-standing cards only. .why-card and .val are excluded because they are
   tiles in gapless mosaics, 2px and 1px, where a shadow would bleed straight
   into the neighbour instead of lifting anything. */
:root[data-palette="silver"] .prog,
:root[data-palette="silver"] .coach,
:root[data-palette="silver"] .founder,
:root[data-palette="silver"] .price-card,
:root[data-palette="silver"] .testi,
:root[data-palette="silver"] .form-box,
:root[data-palette="silver"] .faq-cta,
:root[data-palette="silver"] .map-embed,
:root[data-palette="silver"] .info-card,
:root[data-palette="silver"] .card {
  box-shadow: 0 1px 2px rgba(31, 34, 38, 0.06), 0 6px 16px rgba(31, 34, 38, 0.06);
}
/* The mint landmark band tracks the new band's VALUE so the rhythm still
   holds and only the hue differs, which was the point of it. */
:root[data-palette="silver"] #facilities { background: #C1D5CF; }

/* ── Silver: each banded section gets its own gradient ───────────────────
   The bands read as one flat grey slab because every one of them is the same
   #C7CFDA fill. Each now carries a distinct sweep, so the page changes as you
   scroll instead of repeating.

   EVERY STOP IS LIGHTER THAN THE BAND, AND THAT IS NOT A STYLE CHOICE.
   Secondary text on a band measures 4.66:1 against #C7CFDA and the AA floor is
   4.5, so there is 0.16 of headroom. #C3CBD7, one step down, already fails. The
   darkest point of a gradient sets the floor for every piece of text sitting on
   it, so the sweeps may only lighten. The band colour itself remains the darkest
   point anywhere, which is why the contrast numbers do not move at all.

   The logo's LILAC cannot be used raw here. #CFC5F1 measures 0.5955 luminance
   against the band's 0.6183, so it is DARKER than the ground it would sit on,
   and painting it over a band would quietly push the text under AA. It is
   lightened 40% toward white to #E2DCF7 before use. Mint is already lighter at
   0.6697 and is used closer to raw. This is the same trap as the pale pair not
   being able to carry text: pale is not the same as light.

   Fixed per section rather than randomised. A gradient that changes on reload
   reads as a bug, and the two stylesheets have to stay byte-identical. */
:root[data-palette="silver"] .stats {
  background: linear-gradient(180deg, #E6E9EE 0%, var(--surface-2) 60%);
}
:root[data-palette="silver"] .programs {
  background: linear-gradient(135deg, #C1EAE3 0%, var(--surface-2) 55%);
}
:root[data-palette="silver"] .team {
  background: linear-gradient(45deg, #E2DCF7 0%, var(--surface-2) 58%);
}
:root[data-palette="silver"] .values {
  background: radial-gradient(ellipse 90% 60% at 50% 0%, #EDF0F4 0%, var(--surface-2) 65%);
}
:root[data-palette="silver"] .pricing {
  background: linear-gradient(100deg, var(--surface-2) 30%, #E2DCF7 100%);
}
:root[data-palette="silver"] .trial {
  background: linear-gradient(200deg, #C1EAE3 0%, var(--surface-2) 52%);
}
:root[data-palette="silver"] .faq {
  background: radial-gradient(ellipse 80% 70% at 100% 100%, #E6E9EE 0%, var(--surface-2) 60%);
}

/* ── Silver: iridescence on the buttons and the hero accent ──────────────
   Experiment, silver preview only.

   Buttons keep the steel fill and take the gradient as their BORDER. The fill
   has to stay solid: white label text on a mint-to-lilac gradient would fail
   contrast at the pale end, and a button is the one element on the page that
   must always be readable.

   "One Roll" in the hero uses background-clip:text, which is the only way to
   put a gradient on glyphs. -webkit- prefix included because Safari still needs
   it. A fallback colour is set first, so if the clip is unsupported the text
   renders steel rather than invisible, which is the failure mode this technique
   is known for. */
:root[data-palette="silver"] .btn,
:root[data-palette="silver"] .btn-trial-nav,
:root[data-palette="silver"] .btn.outline {
  border-image: linear-gradient(90deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%) 1;
  border-image-slice: 1;
  border-width: 2px;
  border-style: solid;
}
/* The steel fill fought the iridescent border: a dark slab framed in pale mint
   reads as two unrelated ideas stacked. The primary button now takes a PALE
   wash of the same gradient, so the fill and the frame are the same material,
   and the label goes to ink. Ink on the wash is roughly 15:1, far past AA,
   where white on it would have been unreadable. */
:root[data-palette="silver"] .btn,
:root[data-palette="silver"] .btn-trial-nav {
  background: linear-gradient(90deg,
    rgba(var(--gold-2-rgb), 0.38) 0%,
    rgba(var(--gold-rgb), 0.38) 100%);
  color: var(--silver-ink);
}
/* The outline variant stays white so the two are still distinguishable: same
   frame, different weight of fill. */
:root[data-palette="silver"] .btn.outline {
  background: #FFFFFF;
  color: var(--silver-ink);
}
/* District teaser cards carry border-top:3px solid var(--gold) as an INLINE
   style, which no class selector can beat, hence !important. They were the
   boxes still showing a dark steel top edge. */
:root[data-palette="silver"] .loc-districts a[style] {
  border-image: linear-gradient(90deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%) 1 !important;
  border-image-slice: 1 !important;
  border-style: solid !important;
  border-top-width: 3px !important;
  border-right-width: 1px !important;
  border-bottom-width: 1px !important;
  border-left-width: 1px !important;
}
/* The accent word takes the mint-to-lilac gradient in EVERY heading, not only
   the hero. This has to out-specify the h1..h6 ink rule, which scores 0,2,1;
   "silver h2 .accent" scores 0,2,2 and wins without !important.

   -webkit-text-fill-color is what makes the glyphs show the gradient. The
   color declaration above it is the fallback for a browser without
   background-clip on text, where the word renders ink and matches the rest of
   the heading instead of vanishing, which is the known trap with this
   technique. Fallback first, deliberately. */
:root[data-palette="silver"] h2 .accent,
:root[data-palette="silver"] .hero h1 .accent {
  color: var(--iris-mint-deep);
  background: linear-gradient(90deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ── Silver: ticker and display type ─────────────────────────────────────
   The ticker was a full-width slab of --gold, which under this palette meant a
   dark steel band and the largest dark element on the page. It takes the same
   pale wash as the buttons, so the three iridescent elements now agree, and its
   white hairlines become the line token or they vanish against the wash. */
:root[data-palette="silver"] .ticker {
  background: linear-gradient(90deg,
    rgba(var(--gold-2-rgb), 0.38) 0%,
    rgba(var(--gold-rgb), 0.38) 100%);
  color: var(--silver-ink);
  border-top-color: var(--silver-line);
  border-bottom-color: var(--silver-line);
}
/* This block sits LATER in the file than the h1..h6 rule above and therefore
   wins for h1 and h2, so it has to agree with it or the reversal would be half
   applied. Both are ink now. Kept as a separate rule only because .hero h1
   needs naming explicitly. */
:root[data-palette="silver"] h1,
:root[data-palette="silver"] h2,
:root[data-palette="silver"] .hero h1 {
  color: var(--text);
}
/* The hero accent keeps its gradient. It is one deliberate decorative word,
   not a heading colour, so the reversal does not touch it. The colour here is
   only the fallback for a browser without background-clip:text, and it moves
   to ink so that failure mode matches the rest of the headings rather than
   leaving one steel word behind. */
:root[data-palette="silver"] .hero h1 .accent {
  color: var(--text);
}

/* ── Silver: the why-cards ───────────────────────────────────────────────
   .why-card had NO border at all, only a background and a ::before accent bar,
   so the scan that found every other card by its border could not see it. That
   is the third miss today from deriving a list one way; card-ness is not always
   spelled "border".

   It gains the same frame as the rest. Its 4px left bar, which animates height
   on hover, becomes the gradient too, running vertically so a 4px column still
   shows both ends of it. The ◆ icon frame follows, using border-image for the
   same reason the cards do. */
:root[data-palette="silver"] .why-card::before {
  background: linear-gradient(180deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%);
}
:root[data-palette="silver"] .why-card .icon {
  border-image: linear-gradient(135deg, var(--iris-mint-deep) 0%, var(--iris-lilac-deep) 100%) 1;
  border-image-slice: 1;
  border-width: 2px;
  border-style: solid;
  color: var(--steel-accent);
}
