/* ══════════════════════════════════════════════════════════════════════
   content-v2.css, Content pages (legal, admin, about, FMG, error)
   Rem-based · fluid clamp() typography · full breakpoint system
   Base assumption: 1rem = 16px (browser default, never override :root)

   Breakpoints:
     xs   < 30rem  (480px)   small mobile
     sm   < 48rem  (768px)   mobile
     md   < 80rem  (1280px)  tablet / small desktop
     lg   < 120rem (1920px)  1080p desktop
     xl   < 160rem (2560px)  1440p / QHD
     2xl  ≥ 160rem (2560px+) 4K / UHD
══════════════════════════════════════════════════════════════════════ */

/* ── One scrollbar, not two ─────────────────────────────────────────────
   main-dashboard.css pins html and body to height: 100% so the dashboard can be a
   fixed-viewport app shell. Content pages load that file too, and their content is far
   taller than the viewport, so both elements ended up shorter than what they contained:
   two nested scroll containers, and a browser draws a scrollbar for each.

   Released here rather than there, so the dashboard shell is untouched. html carries no
   page-type class, only body does, hence :has(). .shell already sets min-height: 100dvh,
   so a content page still fills a short viewport without the pinned body.           ---- */
html:has(body:not(.is-dashboard)),
body:not(.is-dashboard) { height: auto; }

/* ── Fluid type scale ───────────────────────────────────────────────── */
:root {
  --ct-2xs:  clamp(0.5625rem, 0.5rem   + 0.15vw, 0.6875rem); /* 9–11px  */
  --ct-xs:   clamp(0.625rem,  0.575rem + 0.2vw,  0.75rem);   /* 10–12px */
  --ct-sm:   clamp(0.6875rem, 0.625rem + 0.25vw, 0.9375rem); /* 11–15px */
  --ct-base: clamp(0.8125rem, 0.75rem  + 0.3vw,  1.0625rem); /* 13–17px */
  --ct-md:   clamp(0.875rem,  0.8rem   + 0.35vw, 1.125rem);  /* 14–18px */
  --ct-lg:   clamp(1rem,      0.9rem   + 0.5vw,  1.5rem);    /* 16–24px */
  --ct-xl:   clamp(1.25rem,   1rem     + 1vw,    2.25rem);   /* 20–36px */
  --ct-hero: clamp(1.5rem,    1.1rem   + 1.5vw,  3rem);      /* 24–48px */

  /* Fluid spacing, replaces hardcoded px gaps/margins */
  --cs-2xs: clamp(0.25rem,  0.2rem  + 0.15vw, 0.375rem);
  --cs-xs:  clamp(0.375rem, 0.3rem  + 0.25vw, 0.625rem);
  --cs-sm:  clamp(0.5rem,   0.4rem  + 0.35vw, 0.875rem);
  --cs-md:  clamp(0.75rem,  0.6rem  + 0.5vw,  1.25rem);
  --cs-lg:  clamp(1rem,     0.8rem  + 0.75vw, 1.75rem);
  --cs-xl:  clamp(1.5rem,   1rem    + 1.25vw, 3rem);
  --cs-2xl: clamp(2rem,     1.5rem  + 2vw,    4.5rem);

  /* Content max-widths, fluid from mobile up to 4K */
  --content-w:      min(92vw, 62rem);    /* full-bleed on mobile, caps at 992px */
  --content-w-wide: min(96vw, 90rem);   /* admin/analytics, caps at 1440px */

  /* Hairline used for table rows/borders, overridden in light mode below */
  --md-hairline:     rgba(255,255,255,.04);
  /* Amber callout body text, overridden in light mode below */
  --md-callout-text: #e0b97a;
  /* Footer bar background, overridden in light mode below */
  --md-footer-bg:    var(--md-surface);
  /* AI-disclaimer red, bright on dark, darker in light for AA contrast */
  --md-error-text:   #ff4444;
}

/* ── Light mode (content pages only; the dashboard stays dark) ──────────
   A pre-paint script in _Layout_md3v2 sets html[data-theme] from the saved
   choice, falling back to the OS (prefers-color-scheme). When it resolves to
   "light" we re-point the shared MD3 tokens to a light palette for content
   pages only (body:not(.is-dashboard)). The dashboard and its dark tokens are
   never touched. The body background follows --md-background automatically. */
html[data-theme="light"] body:not(.is-dashboard) {
    color-scheme: light;

    /* MD3 cyan light tonal palette (derived from the dark primary) */
    --md-background:        #f8fafd;
    --md-surface:           #f8fafd;
    --md-surf-1:            #ffffff;
    --md-surf-2:            #eef3f7;
    --md-surf-3:            #e6edf2;

    --md-on-background:     #191c1e;
    --md-on-surface:        #191c1e;
    --md-surface-variant:   #dce4e8;
    --md-on-surface-var:    #40484c;
    --md-outline:           #70787d;
    --md-outline-var:       #c4ccd1;

    --md-primary:           #006780;
    --md-on-primary:        #ffffff;
    --md-primary-container: #b8eafe;
    --md-on-primary-cont:   #001f29;
    --md-secondary:         #46626a;

    --md-hairline:          rgba(0,0,0,.07);
    --md-callout-text:      #8a5a00;
    --md-error-text:        #ba1a1a;   /* MD3 error, ~6:1 on white */

    /* Prominent cyan chrome: header + footer get the primary container tint.
       The brand icon flips to solid primary so it stays distinct from the
       now-tinted header bar. (Dashboard stays dark and is unaffected.) */
    --md-topbar-bg:         var(--md-primary-container);
    --md-brand-icon-bg:     var(--md-primary);
    --md-brand-icon-fg:     var(--md-on-primary);
    --md-footer-bg:         var(--md-primary-container);
}

/* ── Theme toggle button (header trail, content pages only) ───────────── */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem;
  flex-shrink: 0;
  padding: 0;
  border: 0;
  border-radius: var(--shape-full);
  background: transparent;
  color: var(--md-on-background);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 150ms ease, color 150ms ease;
}
.theme-toggle:hover  { background: color-mix(in srgb, var(--md-on-background) 8%, transparent); }
.theme-toggle:active { background: color-mix(in srgb, var(--md-on-background) 12%, transparent); }
.theme-toggle:focus-visible { outline: 2px solid var(--md-primary); outline-offset: 2px; }
.theme-toggle svg { width: 1.25rem; height: 1.25rem; }
/* Show the current state: sun while in light mode, moon while in dark mode.
   (Dark is the default, so the sun is hidden until data-theme="light".) */
.theme-toggle .theme-toggle-sun { display: none; }
html[data-theme="light"] .theme-toggle .theme-toggle-moon { display: none; }
html[data-theme="light"] .theme-toggle .theme-toggle-sun  { display: block; }

/* Smooth crossfade only while toggling (the .theme-anim class is added by the
   toggle handler for ~250ms, so page load and hovers are never animated). */
@media (prefers-reduced-motion: no-preference) {
  html.theme-anim,
  html.theme-anim * {
    transition: background-color .25s ease, color .25s ease,
                border-color .25s ease, fill .25s ease;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   LEGAL / CONTENT PAGE SHELL
══════════════════════════════════════════════════════════════════════ */
.legal-page {
  max-width: var(--content-w);
  margin: var(--cs-lg) auto var(--cs-2xl);   /* tighter top gap under the header; keep bottom breathing room */
  padding: 0 var(--cs-xl) var(--cs-2xl);
}
.legal-page a { color: var(--md-primary); }
.legal-page a:hover { opacity: .8; }

/* ── Hero ───────────────────────────────────────────────────────────── */
.legal-hero {
  background: var(--md-surf-1);
  border: 1px solid var(--md-outline-var);
  border-radius: var(--shape-xl);
  padding: var(--cs-2xl) var(--cs-2xl) var(--cs-xl);
  margin-bottom: var(--cs-xl);
  position: relative;
  overflow: hidden;
}
.legal-hero::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--md-primary), var(--md-secondary));
  border-radius: var(--shape-xl) var(--shape-xl) 0 0;
}
.legal-hero-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  color: var(--md-primary);
  letter-spacing: .18em;
  text-transform: uppercase;
  margin-bottom: var(--cs-xs);
}
.legal-hero-title {
  font-family: var(--font-display);
  font-size: var(--ct-xl);
  font-weight: 700;
  color: var(--md-on-background);
  line-height: 1.2;
  margin-top: 0;
  margin-bottom: var(--cs-md);
}
.legal-hero-meta {
  display: flex; flex-wrap: wrap; gap: var(--cs-lg);
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  color: var(--md-on-surface-var);
}
.legal-hero-meta span { display: flex; align-items: center; gap: 0.375rem; }
.legal-hero-meta span::before {
  content: ''; display: block;
  width: 0.3125rem; height: 0.3125rem; border-radius: 50%;
  background: var(--md-primary); opacity: .6;
}
/* Shared "stale data" pill (amber warning tonal). MD3 tonal + full (pill) shape;
   same component is defined in main-dashboard.css for the AI Mood popup. Amber
   reads as caution (data is behind), not error. Theme-safe: bright amber on
   dark, darker amber text on the lighter fill in light mode. */
.stale-pill {
  display: inline-flex; align-items: center;
  padding: 0.0625rem 0.5rem;
  border-radius: var(--shape-full, 999px);
  background: color-mix(in srgb, #FFB300 22%, transparent);
  color: #FFB300;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
html[data-dash-theme="light"] .stale-pill {
  color: #8A5A00;
  background: color-mix(in srgb, #FFB300 30%, transparent);
}
.legal-hero-meta .stale-pill::before { display: none; }

/* ── Back link → "Free Live Dashboard" CTA ──────────────────────────────
   Not a quiet breadcrumb anymore: a gradient pill with a pulsing LIVE dot
   and a breathing glow, the first thing the eye lands on. */
.legal-back,
.legal-page a.legal-back {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--font-mono);
  font-size: var(--ct-sm);
  font-weight: 700;
  color: var(--md-on-primary, #06282e);
  text-decoration: none;
  padding: 0.6rem 1.25rem;
  border-radius: var(--shape-full);
  border: none;
  background: var(--md-primary);
  margin-bottom: var(--cs-lg);
  transition: transform .18s cubic-bezier(0.2, 0, 0, 1), box-shadow .18s;
  letter-spacing: .04em;
  box-shadow: var(--md-elev-1, 0 1px 3px rgba(0, 0, 0, .3));
}
.legal-back:hover,
.legal-page a.legal-back:hover {
  color: var(--md-on-primary, #06282e);
  opacity: 1;
  transform: translateY(-2px) scale(1.03);
  box-shadow: var(--md-elev-2, 0 4px 14px rgba(0, 0, 0, .28));
  filter: brightness(1.06);
}
.legal-back::after { content: '\2192'; font-size: var(--ct-md); }
/* Live equalizer bars: three bars rising and falling like a moving market.
   currentColor so they follow the button's on-primary role in both themes. */
.eq-bars {
  display: inline-flex; align-items: flex-end; gap: 2px;
  width: 14px; height: 13px;
}
.eq-bars i {
  flex: 1;
  background: currentColor;
  border-radius: 1px;
  animation: eq-bounce 1.1s ease-in-out infinite;
}
.eq-bars i:nth-child(1) { animation-delay: 0s;    }
.eq-bars i:nth-child(2) { animation-delay: -0.35s; }
.eq-bars i:nth-child(3) { animation-delay: -0.7s;  }
@keyframes eq-bounce {
  0%, 100% { height: 30%; }
  50%      { height: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .eq-bars i { animation: none; height: 60%; }
  .eq-bars i:nth-child(2) { height: 100%; }
}

/* ── Table of contents ──────────────────────────────────────────────── */
.legal-toc {
  background: var(--md-surf-1);
  border: 1px solid var(--md-outline-var);
  border-radius: var(--shape-lg);
  padding: var(--cs-lg) var(--cs-xl);
  margin-bottom: var(--cs-xl);
}
.legal-toc-title {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  color: var(--md-on-surface-var);
  letter-spacing: .14em;
  text-transform: uppercase;
  margin-bottom: var(--cs-md);
}
.legal-toc ol {
  list-style: none; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 0.25rem var(--cs-xl);
}
.legal-toc ol li a {
  font-family: var(--font-body);
  font-size: var(--ct-base);
  color: var(--md-primary);
  text-decoration: none;
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.25rem 0;
  transition: color .15s;
}
.legal-toc ol li a:hover { color: var(--md-on-primary-cont); }
.legal-toc ol li a .toc-num {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  color: var(--md-on-surface-var);
  min-width: 1.125rem;
}

/* ── Section card ───────────────────────────────────────────────────── */
.legal-section {
  background: var(--md-surf-1);
  border: 1px solid var(--md-outline-var);
  border-radius: var(--shape-lg);
  padding: var(--cs-xl) var(--cs-2xl);
  margin-bottom: var(--cs-md);
  scroll-margin-top: 5rem;
}
.legal-section-header {
  display: flex; align-items: baseline; gap: var(--cs-md);
  margin-bottom: var(--cs-md);
  padding-bottom: var(--cs-md);
  border-bottom: 1px solid var(--md-outline-var);
}
.legal-section-num {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  color: var(--md-primary);
  letter-spacing: .1em;
  min-width: 1.75rem;
  flex-shrink: 0;
}
.legal-section-title {
  font-family: var(--font-display);
  font-size: var(--ct-lg);
  font-weight: 700;
  color: var(--md-on-background);
  line-height: 1.3;
}
.legal-subhead {
  font-family: var(--font-display);
  font-size: var(--ct-md);
  font-weight: 700;
  color: var(--md-on-background);
  line-height: 1.35;
  margin: var(--cs-lg) 0 var(--cs-sm);
}

/* ── Dashboard CTA (funnels content-page readers into the live dashboard) ── */
/* Hidden by default; JS in _DashboardCta.cshtml reveals it only for visitors
   who arrived from outside the site (not internal nav). Two classes so this
   wins over the .dash-cta display rule below. */
.dash-cta.dash-cta--prehide { display: none; }
.dash-cta {
  display: flex; align-items: center; gap: var(--cs-lg);
  margin: var(--cs-lg) 0 var(--cs-xl);
  padding: var(--cs-lg) var(--cs-xl);
  border-radius: var(--shape-lg);
  background: linear-gradient(135deg,
      color-mix(in srgb, var(--md-primary) 14%, var(--md-surf-3)) 0%,
      var(--md-surf-3) 72%);
  border: 1px solid color-mix(in srgb, var(--md-primary) 30%, transparent);
  text-decoration: none;
  transition: transform .15s ease, box-shadow .2s ease, border-color .2s ease;
}
.dash-cta:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--md-primary) 55%, transparent);
  box-shadow: 0 10px 30px color-mix(in srgb, var(--md-primary) 20%, transparent);
}
.dash-cta-live {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--font-mono); font-size: .7rem; font-weight: 700;
  letter-spacing: .12em; color: var(--md-error-text); flex-shrink: 0;
}
.dash-cta-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--md-error-text);
  animation: dash-cta-pulse 1.8s ease-in-out infinite;
}
.dash-cta-body { flex: 1 1 auto; display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.dash-cta-title {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--ct-lg); color: var(--md-on-background); line-height: 1.25;
}
.dash-cta-sub {
  font-family: var(--font-body); font-size: var(--ct-sm);
  color: var(--md-on-surface-var); line-height: 1.4;
}
.dash-cta-free, .dash-exit-free {
  /* Text uses the on-surface role (guaranteed AA contrast on the card); primary
     is used only as the icon + border accent, never as the text colour. */
  display: inline-flex; align-items: center; gap: .3rem; width: fit-content;
  font-family: var(--font-mono); font-size: .72rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--md-on-background);
  background: color-mix(in srgb, var(--md-primary) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--md-primary) 40%, transparent);
  padding: 3px 10px; border-radius: 999px;
}
.dash-cta-free { margin-top: .3rem; }
.dash-exit-free { margin: .15rem 0 var(--cs-md); }
.dash-cta-free .material-symbols-outlined,
.dash-exit-free .material-symbols-outlined { font-size: 15px; color: var(--md-primary); }
.dash-cta-action {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: .4rem;
  padding: .6rem 1.15rem; border-radius: 999px;
  background: var(--md-primary); color: var(--md-on-primary);
  font-family: var(--font-body); font-weight: 600; font-size: var(--ct-sm);
  white-space: nowrap;
}
.dash-cta:hover .dash-cta-action { background: color-mix(in srgb, var(--md-primary) 88%, #000); }
.dash-cta-action .material-symbols-outlined { font-size: 18px; transition: transform .15s ease; }
.dash-cta:hover .dash-cta-action .material-symbols-outlined { transform: translateX(3px); }

@keyframes dash-cta-pulse {
  0%, 100% { opacity: 1;  transform: scale(1); }
  50%      { opacity: .4; transform: scale(.8); }
}
@media (max-width: 640px) {
  .dash-cta { flex-direction: column; align-items: flex-start; gap: var(--cs-md); }
  .dash-cta-action { align-self: stretch; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  .dash-cta-dot { animation: none; }
  .dash-cta:hover { transform: none; }
}

/* ── Exit-intent modal (desktop, external landers, once/session) ─────────── */
.dash-exit { position: fixed; inset: 0; z-index: 5000; }
.dash-exit[hidden] { display: none; }
.dash-exit-scrim {
  position: absolute; inset: 0;
  background: rgba(0,0,0,.5);
  opacity: 0; transition: opacity .22s ease;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.dash-exit.open .dash-exit-scrim { opacity: 1; }
.dash-exit-dialog {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -48%) scale(.97);
  width: min(440px, calc(100vw - 32px));
  box-sizing: border-box;
  padding: var(--cs-xl) var(--cs-xl) var(--cs-lg);
  border-radius: var(--shape-lg);
  background: var(--md-surf-3);
  /* signature cyan -> purple glow, matching the AI Mood popup + nav drawer */
  box-shadow:
    0 0 0 1px rgba(6,182,212,.5),
    0 0 0 3px rgba(168,85,247,.2),
    0 0 40px rgba(6,182,212,.18),
    0 24px 60px rgba(0,0,0,.55);
  opacity: 0;
  transition: transform .25s cubic-bezier(.34,1.56,.64,1), opacity .2s ease;
}
.dash-exit.open .dash-exit-dialog { transform: translate(-50%, -50%) scale(1); opacity: 1; }
.dash-exit-close {
  position: absolute; top: .6rem; right: .6rem;
  width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; border-radius: 50%; cursor: pointer;
  color: var(--md-on-surface-var); transition: background .15s;
}
.dash-exit-close:hover { background: color-mix(in srgb, var(--md-on-background) 8%, transparent); }
.dash-exit-live {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--font-mono); font-size: .7rem; font-weight: 700;
  letter-spacing: .12em; color: var(--md-error-text);
}
.dash-exit-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--md-error-text);
  animation: dash-cta-pulse 1.8s ease-in-out infinite;
}
.dash-exit-title {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--ct-xl); color: var(--md-on-background);
  line-height: 1.2; margin: .5rem 0 .35rem;
}
.dash-exit-sub {
  font-family: var(--font-body); font-size: var(--ct-sm);
  color: var(--md-on-surface-var); line-height: 1.5; margin: 0 0 var(--cs-sm);
}
.dash-exit-list {
  list-style: none; margin: 0 0 var(--cs-lg); padding: 0;
  display: grid; gap: .45rem;
}
.dash-exit-list li {
  position: relative; padding-left: 1.5rem;
  font-family: var(--font-body); font-size: var(--ct-sm);
  color: var(--md-on-surface-var); line-height: 1.4;
}
.dash-exit-list li::before {
  content: 'check'; font-family: 'Material Symbols Outlined';
  position: absolute; left: 0; top: 0;
  font-size: 1rem; color: var(--md-primary);
}
.about-newhere {
  font-family: var(--font-body); font-size: var(--ct-sm);
  color: var(--md-on-surface-var); margin: 0 0 var(--cs-lg);
}
.about-newhere a { color: var(--md-primary); text-decoration: none; }
.about-newhere a:hover { text-decoration: underline; }
.dash-exit-action {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .7rem 1.3rem; border-radius: 999px;
  background: var(--md-primary); color: var(--md-on-primary) !important;
  font-family: var(--font-body); font-weight: 600; font-size: var(--ct-sm);
  text-decoration: none;
}
.dash-exit-action .material-symbols-outlined { font-size: 18px; }
.dash-exit-action:hover { background: color-mix(in srgb, var(--md-primary) 88%, #000); }

@media (prefers-reduced-motion: reduce) {
  .dash-exit-dot { animation: none; }
  .dash-exit-scrim, .dash-exit-dialog { transition: none; }
}
.legal-section p {
  font-family: var(--font-body);
  font-size: var(--ct-md);
  line-height: 1.75;
  color: var(--md-on-surface);
  margin-bottom: var(--cs-md);
}
.legal-section p:last-child { margin-bottom: 0; }
.legal-section ul { padding-left: var(--cs-xl); margin-bottom: var(--cs-md); }
.legal-section ul li {
  font-family: var(--font-body);
  font-size: var(--ct-md);
  line-height: 1.75;
  color: var(--md-on-surface);
  margin-bottom: 0.25rem;
}
.legal-section ul li::marker { color: var(--md-primary); }

/* ── Callout / warning block ────────────────────────────────────────── */
.legal-callout {
  background: rgba(255,167,38,.07);
  border: 1px solid rgba(255,167,38,.25);
  border-left: 3px solid var(--amber);
  border-radius: var(--shape-sm);
  padding: var(--cs-lg) var(--cs-xl);
  margin: var(--cs-md) 0;
}
.legal-callout p {
  font-size: var(--ct-base) !important;
  color: var(--md-callout-text) !important;
  margin-bottom: 0 !important;
}

/* ── Contact card ───────────────────────────────────────────────────── */
.legal-contact {
  background: var(--md-primary-container);
  border: 1px solid rgba(77,208,225,.2);
  border-radius: var(--shape-lg);
  padding: var(--cs-xl) var(--cs-2xl);
  margin-top: var(--cs-xl);
  display: flex; align-items: center; gap: var(--cs-xl);
}
.legal-contact-icon {
  width: 3rem; height: 3rem;
  border-radius: var(--shape-md);
  background: rgba(77,208,225,.15);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.375rem;
  flex-shrink: 0;
}
.legal-contact-body { flex: 1; }
.legal-contact-body strong {
  display: block;
  font-family: var(--font-display);
  font-size: var(--ct-md);
  font-weight: 700;
  color: var(--md-on-primary-cont);
  margin-bottom: 0.25rem;
}
.legal-contact-body span {
  font-family: var(--font-body);
  font-size: var(--ct-base);
  color: var(--md-on-primary-cont);
  opacity: .8;
}
.legal-contact-body a { color: var(--md-on-primary-cont); font-weight: 600; }

/* ── Modifier: variants ─────────────────────────────────────────────── */
.legal-page--wide        { max-width: var(--content-w-wide); }
.legal-section--highlight { border-left: 3px solid var(--md-primary); }
.legal-section--table    { padding: 0; overflow-x: auto; }
.legal-section--mt       { margin-top: var(--cs-xl); }
.legal-contact--spaced   { margin-top: var(--cs-2xl); }

/* ── Support buttons ────────────────────────────────────────────────── */
.support-links {
  display: flex; gap: 0.875rem; flex-wrap: wrap; margin-top: 1rem;
}
.support-btn {
  display: inline-flex; align-items: center; gap: 0.625rem;
  padding: 0.6875rem 1.25rem;
  border-radius: 0.625rem;
  text-decoration: none;
  font-family: var(--font-body);
  font-size: var(--ct-md);
  font-weight: 600;
  color: var(--md-on-surface);
  background: var(--md-surface);
  border: 1.5px solid var(--md-outline-var);
  transition: border-color .15s, transform .15s, background .15s;
}
.support-btn:hover { transform: translateY(-2px); background: var(--md-primary-container); }
.support-btn-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.625rem; height: 1.625rem; border-radius: 0.375rem;
  font-size: 0.9375rem; flex-shrink: 0;
}
.support-btn-body { display: flex; flex-direction: column; }
.support-btn-name { font-size: var(--ct-md); font-weight: 700; color: var(--md-on-surface); line-height: 1.2; }
.support-btn-sub  { font-size: var(--ct-xs); font-weight: 400; color: var(--md-on-surface); opacity: .7; margin-top: 0.0625rem; }
.support-btn-bmc  .support-btn-icon { background: #FFDD00; }
.support-btn-kofi .support-btn-icon { background: #29abe0; }
.support-btn-bmc:hover  { border-color: #FFDD00; }
.support-btn-kofi:hover { border-color: #29abe0; }

/* ── Table of contents ──────────────────────────────────────────────── */
.legal-section-num.wn-date {
  font-size: var(--ct-xs);
  min-width: 2.75rem;
  background: var(--md-primary-container);
  color: var(--md-on-primary-cont);
  border-radius: 0.375rem;
  padding: 0.125rem 0.5rem;
  letter-spacing: .04em;
}
.wn-list { padding-left: var(--cs-xl); margin: 0; }
.wn-list li {
  font-family: var(--font-body);
  font-size: var(--ct-md);
  line-height: 1.75;
  color: var(--md-on-surface);
  margin-bottom: 0.375rem;
}
.wn-list li::marker { color: var(--md-primary); }

/* ══════════════════════════════════════════════════════════════════════
   DATA SOURCES PAGE
══════════════════════════════════════════════════════════════════════ */
.ds-table {
  width: 100%; border-collapse: collapse;
  font-size: var(--ct-base);
  margin-top: var(--cs-md);
}
.ds-table th {
  text-align: left; padding: var(--cs-xs) var(--cs-md);
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--md-on-surface-var);
  border-bottom: 1px solid var(--md-outline-var);
}
.ds-table td {
  padding: var(--cs-xs) var(--cs-md);
  color: var(--md-on-surface);
  border-bottom: 1px solid var(--md-hairline);
  vertical-align: top;
}
.ds-table tr:last-child td { border-bottom: none; }
.ds-table tr:hover td { background: var(--md-surf-2); }
.ds-table-note {
  margin-top: var(--cs-md);
  font-size: var(--ct-xs);
  color: var(--md-on-surface-var);
}
.ds-compare-p    { margin-top: 0.75rem; }
.ds-compare-link { color: var(--md-primary); font-weight: 600; }

/* Generic responsive wrapper: lets any content table scroll horizontally on
   narrow screens instead of overflowing the page. Reusable across pages. */
.content-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: var(--cs-md); }
.content-table-wrap .ds-table { margin-top: 0; }

/* ── MD3 Expressive table card (guide pages) ──────────────────────────
   Opt-in skin over ds-table / va-table: the table becomes a tonal card
   (large corner, contained surface), the header row gets a tonal fill
   with Label type in sentence case instead of the admin mono-caps, and
   rows keep a gentle hover state layer. Admin tables are untouched. */
.md3-table-card {
  border: 1px solid var(--md-outline-var);
  border-radius: 16px;                        /* shape.corner.large */
  background: var(--md-surf-1);
  overflow: hidden; overflow-x: auto;
  margin-top: var(--cs-md);
}
.md3-table-card table { margin-top: 0; }
.md3-table-card th {
  background: var(--md-surf-3);               /* tonal header band */
  font-family: var(--font-body);
  font-size: var(--ct-sm);
  font-weight: 700;                           /* Label Large, Emphasized */
  letter-spacing: .01em; text-transform: none;
  color: var(--md-on-surface);
  padding: 0.8rem 1rem;
  border-bottom: 1px solid var(--md-outline-var);
}
.md3-table-card td { padding: 0.7rem 1rem; }

/* Alternating row tint: traces a row across wide multi-column tables (MD3 §4).
   Hover uses surf-3 so it still reads as a state change on striped rows. */
.md3-table-card tbody tr:nth-child(even) td { background: var(--md-surf-2); }
.md3-table-card tbody tr:hover td { background: var(--md-surf-3); }

/* Sticky identity column: on narrow screens the card scrolls horizontally and
   the row label would scroll out of view. Backgrounds must be opaque here, or
   scrolled cells show through. Header sits above it on the z axis. */
.md3-table-card th:first-child,
.md3-table-card td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  font-weight: 600;                           /* row identity leads */
  background: var(--md-surf-1);
  border-right: 1px solid var(--md-outline-var);
}
.md3-table-card th:first-child { background: var(--md-surf-3); z-index: 2; }
.md3-table-card tbody tr:nth-child(even) td:first-child { background: var(--md-surf-2); }
.md3-table-card tbody tr:hover td:first-child { background: var(--md-surf-3); }

/* ── Comparison table ───────────────────────────────────────────────── */
.cmp-table {
  width: 100%; border-collapse: collapse;
  font-size: var(--ct-base);
  margin-top: var(--cs-md);
}
.cmp-table th {
  text-align: center; padding: var(--cs-xs) var(--cs-md);
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--md-on-surface-var);
  border-bottom: 2px solid var(--md-outline-var);
}
.cmp-table th:first-child { text-align: left; }
.cmp-table td {
  padding: var(--cs-xs) var(--cs-md);
  text-align: center;
  color: var(--md-on-surface);
  border-bottom: 1px solid var(--md-hairline);
}
.cmp-table td:first-child { text-align: left; font-weight: 600; }
.cmp-table tr:last-child td { border-bottom: none; }
.cmp-table tr:hover td { background: var(--md-surf-2); }
.cmp-table .cmp-gmd { color: var(--md-primary); font-weight: 700; }
.cmp-yes  { color: var(--gain); font-weight: 700; }
.cmp-no   { color: var(--md-outline); }
.cmp-part { color: var(--amber, #f59e0b); }

/* ══════════════════════════════════════════════════════════════════════
   ABOUT PAGE
══════════════════════════════════════════════════════════════════════ */
.about-feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13.75rem, 1fr));
  gap: 1rem;
  margin-top: 0.75rem;
}
.about-feature-card {
  background: var(--md-surface-2);
  border: 1px solid var(--md-outline-var);
  border-radius: 0.75rem;
  padding: 1rem;
}
.about-feature-title {
  font-size: var(--ct-base);
  font-weight: 700;
  color: var(--md-primary);
  margin-bottom: 0.375rem;
}
.about-feature-card p {
  font-size: var(--ct-xs);
  color: var(--md-on-surface-var);
  line-height: 1.6;
  margin: 0;
}

.about-faq { display: flex; flex-direction: column; gap: 1rem; margin-top: 0.75rem; }
.about-faq-item {
  border-left: 3px solid var(--md-primary);
  padding-left: 1rem;
}
.about-faq-q {
  font-size: var(--ct-md);
  font-weight: 700;
  color: var(--md-on-surface);
  margin: 0 0 0.375rem;
}
.about-faq-a {
  font-size: var(--ct-base);
  color: var(--md-on-surface-var);
  line-height: 1.6;
  margin: 0;
}

.about-comparison-wrap { overflow-x: auto; }
/* ── Footer link nav, MD3 icon list in a tonal card ────────────────── */
.content-footer {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.25rem 1.5rem;
  margin-top: var(--cs-xl);
  padding: 1.25rem 1.5rem;
  background: var(--md-footer-bg);
  border: 1px solid var(--md-outline-var);
  border-radius: 16px;
}
.content-footer-copy {
  margin: 0.75rem 0 0;
  text-align: center;
  font-size: 0.8125rem;
  color: var(--md-on-surface-var);
}
.content-footer-link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6875rem 0.75rem;
  border-radius: 10px;
  color: var(--md-on-surface);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  transition: background-color 120ms ease, color 120ms ease;
}
.content-footer-link .material-symbols-outlined {
  font-size: 20px;
  color: var(--md-primary);
  transition: color 120ms ease;
}
.content-footer-link:hover {
  background-color: color-mix(in srgb, var(--md-primary) 8%, transparent);
  color: var(--md-primary);
}
.content-footer-link:active {
  background-color: color-mix(in srgb, var(--md-primary) 12%, transparent);
}
.content-footer-link:focus-visible {
  outline: 2px solid var(--md-primary);
  outline-offset: 2px;
  background-color: color-mix(in srgb, var(--md-primary) 12%, transparent);
}

/* ── AI disclaimer ──────────────────────────────────────────────────── */
.ai-disclaimer-section { border-left: 4px solid var(--md-error-text); }
.ai-disclaimer-num     { color: var(--md-error-text); }
.ai-disclaimer-title   { color: var(--md-error-text); }
.ai-callout     { border-color: var(--md-error-text); background: rgba(255,68,68,0.08); }
.ai-callout--mt { border-color: var(--md-error-text); background: rgba(255,68,68,0.08); margin-top: 0.75rem; }
.ai-callout-warning { color: var(--md-error-text); font-weight: 700; }
.ai-callout-bold    { font-weight: 700; }

/* ── Utility links ──────────────────────────────────────────────────── */
.content-link       { color: var(--md-primary); font-weight: 600; }
.content-link-plain { color: var(--md-primary); }
.kofi-btn-img       { border: 0; height: 2.25rem; }

/* ══════════════════════════════════════════════════════════════════════
   ADMIN, VISITOR ANALYTICS
══════════════════════════════════════════════════════════════════════ */
.status-strip     { display: none !important; }
.bottom-row       { display: none !important; }
footer.movers-bar { display: none !important; }

/* SignalR live indicators are meaningless on static content pages (no hub
   connection here) and clash with the light header bar, hide them. */
.chip-live        { display: none !important; }
#conn-status      { display: none !important; }

.va-wrap {
  max-width: var(--content-w-wide);
  margin: 0 auto;
  padding: var(--cs-xl) var(--cs-md);
}
.va-hero { margin-bottom: var(--cs-xl); }
.va-hero-eyebrow {
  font-size: var(--ct-xs);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--md-primary);
  margin-bottom: 0.375rem;
}
.va-hero-title {
  font-size: clamp(1.625rem, 4vw, 2.375rem);
  font-weight: 800;
  color: var(--md-on-surface);
  line-height: 1.15;
}
.va-hero-sub {
  font-size: var(--ct-sm);
  color: var(--md-on-surface-var);
  margin-top: 0.375rem;
}
.va-kpi-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--cs-md);
  margin-bottom: var(--cs-xl);
}
.va-kpi {
  background: var(--md-surface-1);
  border: 1px solid var(--md-outline-var);
  border-radius: 1rem;
  padding: var(--cs-md) var(--cs-lg);
}
.va-kpi-label {
  font-size: var(--ct-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--md-on-surface-var);
  margin-bottom: 0.5rem;
}
.va-kpi-value {
  font-size: clamp(2rem, 5vw, 3rem);
  font-weight: 900;
  color: var(--md-primary);
  line-height: 1;
}
.va-kpi-sub {
  font-size: var(--ct-xs);
  color: var(--md-on-surface-var);
  margin-top: 0.25rem;
}
.va-kpi--live                  { border-color: var(--gain); }
.va-kpi--live .va-kpi-label    { color: var(--gain); }
.va-kpi--live .va-kpi-value    { color: var(--gain); }

.va-kpi--peak                  { border-color: #a855f7; }
.va-kpi--peak .va-kpi-label    { color: #a855f7; }
.va-kpi--peak .va-kpi-value    { color: #a855f7; }

.va-card {
  background: var(--md-surface-1);
  border: 1px solid var(--md-outline-var);
  border-radius: 1rem;
  padding: var(--cs-lg);
  margin-bottom: var(--cs-md);
}
.va-card-title {
  font-size: var(--ct-sm);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--md-on-surface-var);
  margin-bottom: var(--cs-md);
}
.va-breakdown-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17.5rem, 1fr));
  gap: var(--cs-md);
  margin-bottom: var(--cs-xl);
}
.va-bar-row {
  display: flex; align-items: center; gap: 0.625rem;
  margin-bottom: 0.625rem;
  font-size: var(--ct-md);
}
.va-bar-label {
  flex: 0 0 auto; width: 10.625rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--md-on-surface); font-weight: 500;
}
.va-bar-track {
  flex: 1; background: var(--md-outline-var);
  border-radius: 0.25rem; height: 0.4375rem; overflow: hidden;
}
.va-bar-fill { height: 100%; border-radius: 0.25rem; background: var(--md-primary); }
.va-bar-count {
  flex: 0 0 2.75rem; text-align: right;
  color: var(--md-on-surface-var);
  font-size: var(--ct-base);
}
.va-hourly {
  display: flex; align-items: flex-end; gap: 0.1875rem;
  height: 3.75rem; margin-bottom: var(--cs-lg);
}
.va-hourly-col {
  flex: 1; height: 100%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: flex-end;
}
.va-hourly-bar {
  width: 100%; background: var(--md-primary);
  border-radius: 0.125rem 0.125rem 0 0;
  opacity: .65; min-height: 0.125rem;
}
.va-hourly-hr {
  margin-top: 0.1875rem;
  font-size: 0.5625rem; line-height: 1;
  color: var(--md-on-surface-var);
  font-variant-numeric: tabular-nums;
}
.va-table-wrap { overflow-x: auto; }
.va-table { width: 100%; border-collapse: collapse; font-size: var(--ct-base); }
.va-table th {
  text-align: left; padding: 0.625rem 0.75rem;
  border-bottom: 1px solid var(--md-outline-var);
  font-size: var(--ct-xs);
  font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--md-on-surface-var);
}
.va-table td {
  padding: 0.5625rem 0.75rem;
  border-bottom: 1px solid var(--md-hairline);
  color: var(--md-on-surface); vertical-align: top;
  max-width: 13.75rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* IP cell must never truncate: a full IPv6 + the confirmed check need to stay
   visible. The admin table has the horizontal room (it can scroll if needed). */
.va-table td.va-ip-cell { max-width: none; overflow: visible; text-overflow: clip; }
.va-table tr:last-child td { border-bottom: none; }
.va-table tr:hover td { background: var(--md-surf-2); }
/* Prose comparison tables (e.g. Trader vs Gambler): cells wrap to full, clear
   sentences instead of the compact admin-table ellipsis truncation. */
.va-table--wrap td { white-space: normal; max-width: none; overflow: visible; text-overflow: clip; }
/* Small info-icon link (e.g. glance-table label -> matching FAQ answer). */
.fmg-faq-icon { display: inline-flex; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem; margin-left: 0.1rem; vertical-align: middle; color: var(--md-primary); text-decoration: none; opacity: .7; }
.fmg-faq-icon:hover { opacity: 1; }
.fmg-faq-icon .material-symbols-outlined { font-size: 1.15rem; }
/* Numbered steps inside a FAQ answer (e.g. how to stay disciplined). */
.fmg-steps { margin: 0.5rem 0 0; padding-left: 1.25rem; }
.fmg-steps li { margin-bottom: 0.5rem; line-height: 1.55; }

/* ── Trader / Gambler self-test quiz ──────────────────────────────────────── */
.quiz-form { display: grid; gap: 0.85rem; }
.quiz-q { border: 1px solid var(--md-outline-var); border-radius: 0.9rem; padding: 1rem 1.1rem; margin: 0; background: var(--md-surf-2, var(--md-surface)); }
.quiz-q-text { font-weight: 600; line-height: 1.5; margin: 0 0 0.85rem; }
.quiz-q-num { display: inline-flex; align-items: center; justify-content: center; width: 1.5rem; height: 1.5rem; margin-right: 0.45rem; border-radius: 50%; background: var(--md-primary); color: #fff; font-size: var(--ct-xs); font-weight: 700; }
.quiz-scale { display: flex; align-items: center; justify-content: space-between; gap: 0.4rem; flex-wrap: wrap; }
.quiz-scale-end { font-size: var(--ct-xs); color: var(--md-on-surface-var); flex: 0 0 auto; }
.quiz-scale label { cursor: pointer; position: relative; }
.quiz-scale input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.quiz-scale label span { display: inline-flex; align-items: center; justify-content: center; width: 2.4rem; height: 2.4rem; border-radius: 50%; border: 1.5px solid var(--md-outline-var); font-weight: 700; transition: background .15s, border-color .15s, color .15s; }
.quiz-scale input:checked + span { background: var(--md-primary); border-color: var(--md-primary); color: #fff; }
.quiz-scale input:focus-visible + span { outline: 2px solid var(--md-primary); outline-offset: 2px; }
.quiz-submit { margin-top: 0.35rem; padding: 0.8rem 1.6rem; border: none; border-radius: 2rem; background: var(--md-primary); color: #fff; font-weight: 700; font-size: var(--ct-base); cursor: pointer; }
.quiz-submit:hover:not(:disabled) { filter: brightness(1.08); }
.quiz-submit:disabled { opacity: .45; cursor: not-allowed; }
.quiz-progress { margin-left: 0.75rem; font-size: var(--ct-sm); color: var(--md-on-surface-var); }
.quiz-result { margin-top: 1.5rem; border: 1px solid var(--md-outline-var); border-radius: 1rem; padding: 1.5rem; background: var(--md-surf-2, var(--md-surface)); text-align: center; }
.quiz-result-score { font-size: 2.6rem; font-weight: 800; color: var(--md-primary); line-height: 1.1; }
.quiz-result-score small { font-size: 1.1rem; color: var(--md-on-surface-var); font-weight: 600; }
.quiz-result-title { font-size: 1.4rem; margin: 0.35rem 0 0.75rem; }
.quiz-result-text { line-height: 1.6; margin: 0 auto 1.1rem; max-width: 42rem; }
.quiz-result-cta a { display: inline-block; margin: 0.3rem; }
.quiz-result-cta a.quiz-dash-cta { display: inline-block; margin: 0.3rem 0 0; padding: 0.8rem 1.6rem; border-radius: 2rem; background: var(--md-primary); color: #fff; font-weight: 700; font-size: var(--ct-base); text-decoration: none; }
.quiz-result-cta a.quiz-dash-cta:hover { color: #fff; filter: brightness(1.08); }
.quiz-dash-sub { margin: 0.5rem auto 0; max-width: 32rem; font-size: var(--ct-sm); color: var(--md-on-surface-var); line-height: 1.5; }
/* In the left-aligned intro (vs the centered result box) the sub-line hugs the button */
.quiz-intro .quiz-dash-sub { margin-left: 0.25rem; text-align: left; }

.va-ok { color: var(--md-primary); font-weight: 700; }

/* Admin: Recent Visits card header + on-demand bot-hygiene button */
.va-card-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.va-btn {
    font: inherit; font-size: var(--ct-sm); font-weight: 600; line-height: 1;
    color: var(--md-on-primary); background: var(--md-primary);
    border: none; border-radius: 999px; padding: 0.55rem 1.1rem; cursor: pointer;
    transition: filter 120ms ease, opacity 120ms ease;
}
.va-btn:hover { filter: brightness(1.08); }
.va-btn:disabled { opacity: 0.6; cursor: default; }
.va-hygiene-msg { margin-top: 0.6rem; font-size: var(--ct-sm); color: var(--md-on-surface-var); }

/* Smooth in-page anchor jumps (ToC, glance-table info icons), MD3 motion.
   Honors reduced-motion; scroll-margin gives the target a little breathing room. */
@media (prefers-reduced-motion: no-preference) { html, body, main { scroll-behavior: smooth; } }
:target { scroll-margin-top: 1rem; }

/* ── Physical AI guide ────────────────────────────────────────────────────── */
/* MD3 media card: vertical (image on top) on mobile, horizontal (image left,
   text right) on desktop. */
.pai-figure { display: flex; flex-direction: column; margin: 1.25rem 0; border: 1px solid var(--md-outline-var); border-radius: 16px; overflow: hidden; background: var(--md-surf-2, var(--md-surface)); }
.pai-img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; display: block; }
/* Phones: guide images are wide banners, never a full-viewport wall.
   Explicit height cap because aspect-ratio alone has proven unreliable
   in some mobile browsers/WebViews. */
@media (max-width: 48rem) {
  .pai-img { aspect-ratio: auto; height: clamp(140px, 26vh, 230px); object-fit: cover; }
}
.pai-figure figcaption { margin: 0; padding: 0.9rem 1.1rem; font-size: var(--ct-base); color: var(--md-on-surface-var); line-height: 1.5; }
@media (min-width: 641px) {
  .pai-figure { flex-direction: row; align-items: stretch; }
  .pai-img { flex: 0 0 240px; width: 240px; aspect-ratio: auto; height: auto; }
  .pai-figure figcaption { align-self: center; }
  /* Banner variant for portrait/square sources: full-width center-cropped
     strip with the caption below, instead of a skinny image tower next to
     an empty caption cavern. */
  .pai-figure--banner { flex-direction: column; }
  .pai-figure--banner .pai-img { flex: none; width: 100%; height: 300px; }
}
/* Dividends-vs-bonds guide: dual-coded side chips so the two sides of the
   comparison read at a glance - bond = blue + lock (fixed, contractual),
   dividend stock = green + rising chart (growing, at risk). */
.dvb-side {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.1rem 0.55rem; border-radius: var(--shape-full, 999px);
  font-weight: 700; white-space: nowrap;
}
.dvb-side .material-symbols-outlined { font-size: 1rem; }
.dvb-bond { color: #2979FF; background: rgba(41, 121, 255, .10); border: 1px solid rgba(41, 121, 255, .30); }
.dvb-div  { color: #4CAF50; background: rgba(76, 175, 80, .10);  border: 1px solid rgba(76, 175, 80, .30); }
html[data-theme="light"] body:not(.is-dashboard) .dvb-bond { color: #1655b8; }
html[data-theme="light"] body:not(.is-dashboard) .dvb-div  { color: #2e7d32; }
/* Phones: chips must not force wide table columns - drop the pill box,
   keep only the color + icon coding, and let the label wrap. */
@media (max-width: 48rem) {
  .dvb-side { white-space: normal; padding: 0; border: none; background: none; gap: 0.2rem; }
  .dvb-side .material-symbols-outlined { font-size: 0.875rem; }
}

.pai-list { list-style: none; padding: 0; margin: 0.75rem 0; display: grid; gap: 0.6rem; }
.pai-list li { padding: 0.75rem 1rem; border: 1px solid var(--md-outline-var); border-radius: 14px; line-height: 1.55; }
.quiz-share { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem; margin-top: 1.1rem; }
.quiz-share-item { display: inline-flex; align-items: center; padding: 0.55rem 1.1rem; border-radius: 2rem; border: 1.5px solid var(--md-outline-var); background: transparent; color: var(--md-on-surface); font-weight: 600; font-size: var(--ct-sm); cursor: pointer; text-decoration: none; }
.quiz-share-item:hover { border-color: var(--md-primary); color: var(--md-primary); }
.va-chip {
  display: inline-block;
  padding: 0.1875rem 0.625rem; border-radius: 0.625rem;
  font-size: var(--ct-xs); font-weight: 700;
  border: 1px solid var(--md-outline-var);
  color: var(--md-on-surface-var);
}
.va-chip.mobile  { border-color: var(--gain);        color: var(--gain); }
.va-chip.tablet  { border-color: var(--amber);       color: var(--amber); }
.va-chip.desktop { border-color: var(--md-primary);  color: var(--md-primary); }
.va-chip--inline { flex: 0 0 auto; }
.va-back {
  display: inline-block; margin-bottom: var(--cs-lg);
  font-size: var(--ct-md); font-weight: 600; color: var(--md-primary);
  text-decoration: none;
}
.va-back:hover { text-decoration: underline; }
.va-empty { font-size: var(--ct-xs); color: var(--md-on-surface-var); }
.va-meta  { font-size: var(--ct-2xs); color: var(--md-on-surface-var); }
.va-td-total { font-weight: 700; color: var(--md-primary); }
.va-td-muted { color: var(--md-on-surface-var); }

/* ══════════════════════════════════════════════════════════════════════
   ADMIN, AFFILIATES
══════════════════════════════════════════════════════════════════════ */
.aff-status-chips  { display: flex; gap: 0.625rem; flex-wrap: wrap; margin-bottom: var(--cs-xl); }
.aff-name          { font-weight: 700; font-size: var(--ct-xs); color: var(--md-on-surface); }
.aff-website       { font-size: var(--ct-2xs); color: var(--md-on-surface-var); }
.aff-website a     { color: var(--md-primary); text-decoration: none; }
.aff-td-panel      { font-size: var(--ct-sm); color: var(--md-on-surface-var); }
.aff-td-payout     { font-size: var(--ct-sm); color: var(--md-on-surface); }
.aff-td-center     { text-align: center; }
.aff-not-set       { font-size: var(--ct-2xs); color: var(--md-on-surface-var); }
.aff-td-notes      { font-size: var(--ct-2xs); color: var(--md-on-surface-var); max-width: 10rem; }
.aff-how-to-list   { font-size: var(--ct-xs); color: var(--md-on-surface-var); line-height: 1.8; }

.aff-mgmt-table { width: 100%; border-collapse: collapse; font-size: var(--ct-xs); }
.aff-mgmt-table th {
  text-align: left; padding: 0.625rem 0.875rem;
  font-size: var(--ct-2xs); font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--md-on-surface-var); border-bottom: 2px solid var(--md-outline-var);
  white-space: nowrap;
}
.aff-mgmt-table td {
  padding: 0.75rem 0.875rem;
  border-bottom: 1px solid var(--md-outline-var);
  vertical-align: middle;
}
.aff-mgmt-table tr:last-child td { border-bottom: none; }
.aff-mgmt-table tr:hover td { background: var(--md-surf-2); }
.aff-cat-chip {
  font-size: var(--ct-2xs); font-weight: 700; letter-spacing: .06em;
  padding: 0.125rem 0.5rem; border-radius: var(--shape-chip);
  background: var(--md-surf-3); color: var(--md-on-surface-var); white-space: nowrap;
}
.aff-status-chip {
  font-size: var(--ct-2xs); font-weight: 800; letter-spacing: .08em;
  padding: 0.125rem 0.5625rem; border-radius: var(--shape-chip);
  border: 1px solid; white-space: nowrap;
}
.aff-check   { color: var(--gain); font-weight: 700; }
.aff-missing { color: var(--loss); font-weight: 700; }
.aff-link-chip {
  font-size: var(--ct-2xs); font-weight: 700;
  color: var(--gain); text-decoration: none;
  padding: 0.125rem 0.5rem; border-radius: var(--shape-chip);
  background: var(--gain-cont); white-space: nowrap;
}
.aff-apply-btn {
  font-size: var(--ct-2xs); font-weight: 700;
  color: var(--md-primary); text-decoration: none;
  padding: 0.1875rem 0.625rem; border-radius: var(--shape-full);
  border: 1px solid var(--md-primary); white-space: nowrap;
  transition: background .15s;
}
.aff-apply-btn:hover { background: rgba(77,208,225,.1); }

/* ══════════════════════════════════════════════════════════════════════
   FINANCIAL MARKETS GUIDE
══════════════════════════════════════════════════════════════════════ */
.fmg-disclaimer { margin-top: 1rem; }

/* Live-levels band, funnels "markets today" search intent to the live dashboard */
.fmg-live-band {
  margin: var(--cs-lg) 0;
  padding: var(--cs-md) var(--cs-lg);
  border: 1px solid var(--md-outline-var);
  border-left: 3px solid var(--md-primary);
  border-radius: var(--cs-xs);
  background: color-mix(in srgb, var(--md-primary) 6%, transparent);
}
.fmg-live-band-head {
  display: flex; align-items: center; gap: 0.5rem;
  font-weight: 600; margin-bottom: 0.5rem;
}
.fmg-live-dot {
  width: 0.5rem; height: 0.5rem; border-radius: 50%;
  background: var(--md-primary);
  animation: fmgLivePulse 2s ease-in-out infinite;
}
@keyframes fmgLivePulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .4;  transform: scale(.8); }
}
@media (prefers-reduced-motion: reduce) {
  .fmg-live-dot { animation: none; }
}
.fmg-live-band a       { color: var(--md-primary); text-decoration: none; }
.fmg-live-band a:hover { text-decoration: underline; }
.fmg-live-cta {
  display: inline-block; margin-top: 0.5rem; font-weight: 600;
}
.fmg-back-top {
  margin-left: auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.625rem; height: 1.625rem; border-radius: 50%;
  border: 1px solid var(--md-outline-var);
  color: var(--md-primary);
  font-size: var(--ct-md);
  text-decoration: none; flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s;
}
.fmg-back-top:hover { background: var(--md-primary-container); border-color: var(--md-primary); }
.fmg-asset-title {
  font-size: var(--ct-lg);
  font-weight: 700;
  margin: 1.75rem 0 0.5rem;
  color: var(--md-primary);
}
.fmg-asset-title:first-of-type { margin-top: 0.5rem; }
.fmg-sources {
  font-size: var(--ct-sm);
  margin-top: 0.375rem;
  color: var(--md-on-surface-var);
}
.fmg-sources a       { color: var(--md-primary); text-decoration: none; }
.fmg-sources a:hover { text-decoration: underline; }
.fmg-sources-list    { margin: 0.75rem 0 0 1.25rem; line-height: 2; }
.fmg-sources-list a       { color: var(--md-primary); text-decoration: none; }
.fmg-sources-list a:hover { text-decoration: underline; }

/* ══════════════════════════════════════════════════════════════════════
   WEEKLY MARKET TRENDS
   Desktop: all sections stacked, pills hidden. Mobile (<=720px): sticky
   quick-jump pills filter to one market at a time (mirrors the dashboard).
══════════════════════════════════════════════════════════════════════ */
.wt-tabs { display: none; }

/* Neutral market label above each section heading (trend is shown by the
   coloured left border, which reads correctly in both light and dark). */
.wt-pill-label {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.75rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase;
  padding: 0.125rem 0.625rem;
  border-radius: var(--shape-full);
  background: var(--md-surf-3);
  color: var(--md-on-surface-var);
  margin-bottom: var(--cs-xs);
}

/* Trend accent: green up, red down, amber mixed. A border avoids the
   contrast pitfalls of coloured text on light backgrounds. */
.wt-trend-up    { border-left: 3px solid var(--gain); }
.wt-trend-down  { border-left: 3px solid var(--loss); }
.wt-trend-mixed { border-left: 3px solid var(--amber); }

/* Trend badge: a coloured circle + direction arrow in each section header,
   so the page reads as more than a wall of text. */
.wt-trend-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.875rem; height: 1.875rem; flex-shrink: 0;
  border-radius: var(--shape-full);
  font-size: 0.9rem; font-weight: 700; line-height: 1;
}
.wt-badge-up    { background: var(--gain-cont);  color: var(--gain); }
.wt-badge-down  { background: var(--loss-cont);  color: var(--loss); }
.wt-badge-mixed { background: var(--amber-cont); color: var(--amber); }
.wt-badge-up::before    { content: "\25B2"; }   /* up triangle */
.wt-badge-down::before  { content: "\25BC"; }   /* down triangle */
.wt-badge-mixed::before { content: "\2192"; }   /* right arrow */

/* Per-section subject image as a small MD3 leading thumbnail in the header
   (renders only when the file exists; falls back to the trend badge). */
.wt-thumb {
  width: 3.5rem; height: 3.5rem;     /* 56dp leading media */
  flex-shrink: 0;
  border-radius: var(--shape-md);    /* 12dp rounded square */
  object-fit: cover;
  background: var(--md-surf-2);
}
/* Center the leading thumbnail against the heading (the shared header uses
   baseline alignment, which would misalign the image). */
.wt-section .legal-section-header { align-items: center; }

.wt-cta { margin-top: var(--cs-sm); }
.wt-cta a {
  color: var(--md-primary); text-decoration: none;
  font-weight: 600; font-size: 0.875rem;
}
.wt-cta a:hover { text-decoration: underline; }

.wt-disclaimer {
  margin-top: var(--cs-lg);
  font-size: 0.8125rem; line-height: 1.5;
  color: var(--md-on-surface-var);
  font-style: italic;
}

@media (max-width: 720px) {
  .wt-tabs {
    display: flex; flex-wrap: nowrap; gap: 0.375rem;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    position: sticky; top: 0.5rem; z-index: 20;
    margin: 0 0 var(--cs-md);
    padding: 0.375rem;
    background: var(--md-surf-2);
    border: 1px solid var(--md-outline-var);
    border-radius: var(--shape-full);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05),
                0 2px 10px rgba(0, 0, 0, 0.28);
  }
  .wt-tabs::-webkit-scrollbar { display: none; }
  .wt-tab {
    flex: 0 0 auto;
    font-family: var(--font-body);
    font-size: 0.8125rem; font-weight: 600;
    padding: 0.4375rem 0.875rem;
    border-radius: var(--shape-full);
    border: 1px solid var(--md-outline-var);
    background: var(--md-surf-2);
    color: var(--md-on-surface-var);
    cursor: pointer; white-space: nowrap;
    -webkit-tap-highlight-color: transparent;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
  }
  .wt-tab.is-active {
    background: var(--md-primary-container);
    color: var(--md-on-primary-cont);
    border-color: transparent;
  }
  /* Only the active section is shown on mobile (class set by weekly-trends.js;
     ignored on desktop, where every section stays visible). */
  .wt-section.is-hidden { display: none; }

  /* Keep the thumbnail beside the title on mobile (the shared header stacks to
     a column by default); MD3 list-item style with leading media. */
  .wt-section .legal-section-header { flex-direction: row; align-items: center; }
}

/* ══════════════════════════════════════════════════════════════════════
   HOW TO INVEST IN AI  (the AI stack)
══════════════════════════════════════════════════════════════════════ */
/* The pyramid is the page's centrepiece, not a peer of the body sections, so it
   gets an expressive treatment: a tonal container at the extra-large corner
   radius, an overline, and a Headline-role title one step above the section
   titles (--ct-xl vs --ct-lg). */
.ai-pyramid {
  margin: var(--cs-lg) 0;
  padding: var(--cs-lg) var(--cs-md) var(--cs-md);
  background: var(--md-surf-1);
  border: 1px solid var(--md-outline-var);
  border-radius: var(--shape-xl);               /* shape.corner.extra-large, as .legal-hero */
}
.ai-pyramid-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  color: var(--md-primary);
  letter-spacing: .14em;
  text-transform: uppercase;
  text-align: center;
  margin-bottom: var(--cs-2xs);
}
.ai-pyramid-title {
  font-family: var(--font-display);
  font-size: var(--ct-xl);                      /* Headline role, above section titles */
  font-weight: 700;
  color: var(--md-on-background);
  line-height: 1.2;
  letter-spacing: -.01em;                       /* tighter tracking at display size */
  text-align: center;
  margin-bottom: var(--cs-md);
  text-wrap: balance;
}
.ai-pyramid svg { width: 100%; max-width: 32rem; height: auto; display: block; margin: 0 auto; overflow: visible; }
.ai-pyramid text {
  fill: #fff; font-family: var(--font-body); font-size: 23px; font-weight: 700;
  letter-spacing: .2px; text-anchor: middle; dominant-baseline: middle; pointer-events: none;
}
.ai-pyramid a { cursor: pointer; outline: none; }
.aip-band {
  stroke: rgba(255, 255, 255, .22); stroke-width: .75;
  transition: filter .15s ease, opacity .15s ease;
}
/* persistent "go" signifier (chevron), brightens on interaction */
.aip-go {
  fill: rgba(255, 255, 255, .8); font-size: 26px; font-weight: 700;
  text-anchor: middle; dominant-baseline: middle; pointer-events: none;
  transition: fill .15s ease, transform .15s ease; transform-box: fill-box; transform-origin: center;
}
/* MD3 state layers: hover lifts, press dims, keyboard focus shows a ring */
.ai-pyramid a:hover .aip-band   { filter: brightness(1.12); }
.ai-pyramid a:hover .aip-go     { fill: #fff; transform: translateX(2px); }
.ai-pyramid a:active .aip-band  { filter: brightness(.94); opacity: .9; }
.ai-pyramid a:focus-visible .aip-band {
  stroke: var(--md-on-surface, #fff); stroke-width: 2.5;
  filter: brightness(1.12) drop-shadow(0 0 3px rgba(124, 77, 255, .6));
}

.ai-pyramid-hint {
  display: flex; align-items: center; justify-content: center; gap: 0.4rem;
  margin: var(--cs-sm) 0 0; font-size: 0.875rem; font-weight: 600;
  color: var(--md-on-surface-var);
}
.ai-pyramid-hint .material-symbols-outlined { font-size: 1.1rem; }

/* sponsored partner cards (bottom of the page) */
.ai-partners-note {
  font-size: 0.8125rem; font-style: italic; color: var(--md-on-surface-var);
  margin: 0 0 var(--cs-md);
}
.ai-partners-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--cs-md);
}
@media (max-width: 560px) { .ai-partners-grid { grid-template-columns: 1fr; } }
.ai-partner-card {
  display: flex; flex-direction: column; overflow: hidden; text-decoration: none;
  background: var(--md-surf-2, var(--md-surface));
  border: 1px solid var(--md-hairline, rgba(0, 0, 0, .08));
  border-radius: var(--shape-lg, 16px);
  transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
}
.ai-partner-card:hover {
  box-shadow: var(--md-elev-2, 0 4px 14px rgba(0, 0, 0, .18));
  transform: translateY(-2px); border-color: var(--md-primary);
}
/* Capped, uniform banner height so cards stay compact and align regardless of
   the source image's shape (kept short so the block never dominates the page).
   Targets the class rather than any descendant img, so the styling is explicit
   and a future non-logo image inside the card does not inherit banner sizing. */
.ai-partner-logo {
  width: 100%; height: clamp(84px, 9vw, 120px);
  object-fit: cover; display: block;
}
.ai-partner-cta {
  margin-top: auto;                     /* pin CTA to card bottom so the row lines up */
  padding: 0.75rem 1rem; text-align: center; font-weight: 700; font-size: 0.9375rem;
  color: var(--md-primary);
}
/* faint circuit contour around the pyramid, follows the theme */
.aip-circuit polyline {
  fill: none; stroke: var(--md-outline, rgba(120, 120, 140, .45));
  stroke-width: 1; stroke-dasharray: 3 5; opacity: .5;
}
.aip-circuit circle { fill: var(--md-on-surface-var, #8a8a9a); opacity: .45; }

.ai-stocks { list-style: none; margin: var(--cs-sm) 0 0; padding: 0; }
.ai-stock {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--cs-md);
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--md-hairline, rgba(0, 0, 0, .07));
}
.ai-stock:last-child { border-bottom: none; }
.ai-stock-name { font-weight: 600; color: var(--md-on-surface); }
.ai-stock-tkr {
  font-family: var(--font-mono); font-size: 0.75rem; font-weight: 700;
  color: var(--md-on-surface-var); background: var(--md-surf-3);
  padding: 1px 6px; border-radius: var(--shape-full); margin-left: 0.25rem;
}
.ai-stock-quote { display: inline-flex; align-items: baseline; gap: 0.5rem; white-space: nowrap; }
.ai-stock-price { font-family: var(--font-mono); font-weight: 600; color: var(--md-on-surface); }
.ai-stock-chg   { font-family: var(--font-mono); font-size: 0.8125rem; font-weight: 700; }
.ai-stock-chg.up   { color: var(--gain); }
.ai-stock-chg.down { color: var(--loss); }
.ai-note { font-size: 0.8125rem; font-style: italic; color: var(--md-on-surface-var); margin-top: var(--cs-sm); }

/* ══════════════════════════════════════════════════════════════════════
   STEP LIST - visible numbered path, mirrors the HowTo structured data
══════════════════════════════════════════════════════════════════════ */
.pai-steps { list-style: none; counter-reset: step; padding: 0; margin: var(--cs-md) 0; display: grid; gap: 0.6rem; }
.pai-steps li {
  counter-increment: step;
  position: relative;
  padding: 0.85rem 1rem 0.85rem 3.25rem;
  border: 1px solid var(--md-outline-var);
  border-radius: 14px;
  background: var(--md-surf-1);
  line-height: 1.55;
}
.pai-steps li::before {
  content: counter(step);
  position: absolute;
  left: 0.85rem; top: 0.85rem;
  width: 1.75rem; height: 1.75rem;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--md-primary-container);
  color: var(--md-on-primary-cont);
  font-size: var(--ct-sm); font-weight: 700;
}

/* ══════════════════════════════════════════════════════════════════════
   WORLD HEATMAP (/world-heatmap) - live country-ETF tiles, theme-aware.
   Self-contained here so the content page needs no dashboard stylesheet.
══════════════════════════════════════════════════════════════════════ */
/* Live-data page: compress the whole vertical stack so every region is on one
   screen on desktop, matching the "everything on one screen" spirit rather than
   a reading-guide layout. All scoped to .wh-live-page so other content pages,
   and the shared hero/section/back styles, are untouched. */
.wh-live-page { margin-top: var(--cs-sm); }
.wh-live-page .legal-section { padding: var(--cs-lg) var(--cs-xl); }
/* Standardised content-page hero: MD3 hero rhythm with room to breathe (padding
   ~24-48dp, 16dp headline->supporting, 24dp supporting->button), capped below
   the base hero's 4.5rem so it never dominates. Doubled class (0,2,0) so it
   beats the responsive .legal-hero rules (0,1,0) later in the file, including
   the min-width:120rem block. */
.legal-hero.legal-hero--tight { padding: var(--cs-xl); margin-bottom: var(--cs-md); }
.legal-hero--tight .legal-hero-title { margin-bottom: var(--cs-md); }   /* ~16dp */
.legal-hero--tight .legal-hero-meta { gap: var(--cs-md); }

/* MD3 hero primary action: Filled Button, Full (pill) shape, primary/onPrimary
   tokens, hug-content, left-aligned under the supporting text. Mirrors the
   .dash-cta-action pattern; ~24dp spacer above via cs-md. */
/* Doubled selector (.legal-page a.legal-hero-cta) so the onPrimary text colour
   beats the generic ".legal-page a { color: primary }" link rule, which would
   otherwise paint the label primary-cyan on the cyan pill and hide it. Same
   pattern .legal-back uses. */
.legal-hero-cta,
.legal-page a.legal-hero-cta {
  display: inline-flex; align-items: center; gap: 0.55rem;
  margin-top: var(--cs-lg);   /* ~24dp supporting-text -> button */
  padding: 0.65rem 1.3rem; min-height: 2.5rem; box-sizing: border-box;
  border-radius: 999px;
  background: var(--md-primary); color: var(--md-on-primary);
  font-family: var(--font-body); font-weight: 600; font-size: var(--ct-sm);
  letter-spacing: .01em; text-decoration: none;
  transition: filter .15s ease;
}
.legal-hero-cta:hover,
.legal-page a.legal-hero-cta:hover { filter: brightness(1.08); opacity: 1; color: var(--md-on-primary); }
.legal-hero-cta::after { content: '\2192'; font-size: var(--ct-md); }
.legal-hero-cta .eq-bars i { background: var(--md-on-primary); }

.wh-region { margin: var(--cs-sm) 0 0; }
.wh-region:first-child { margin-top: 0; }
.wh-region-head {
  font-family: var(--font-body);
  font-size: var(--ct-sm); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--md-on-surface-var);
  margin: 0 0 var(--cs-xs);
}
.wh-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.4rem;
  /* Size each tile to its own content; the grid default (stretch) padded shorter
     tiles up to the tallest in the row, which read as dead space. */
  align-items: start;
}
@media (max-width: 720px) { .wh-grid { grid-template-columns: repeat(2, 1fr); } }
.wh-tile {
  display: flex; flex-direction: column; gap: 0.15rem;
  padding: 0.6rem 0.8rem;
  border-radius: var(--cs-xs);
  border: 1px solid var(--md-outline-var);
  background: var(--md-surf-1);
  transition: transform .18s cubic-bezier(.34,1.56,.64,1), box-shadow .18s,
              background-color .45s cubic-bezier(.2,0,0,1),
              border-color .45s cubic-bezier(.2,0,0,1);
}
.wh-tile:hover { transform: scale(1.03); box-shadow: 0 6px 18px rgba(0,0,0,.25); }
.wh-tile-name {
  font-family: var(--font-body);
  font-size: 0.875rem; font-weight: 700; letter-spacing: .01em; line-height: 1.25;
  color: var(--md-on-surface);
}
.wh-tile-pct {
  font-family: var(--font-mono);
  font-size: 1.0625rem; font-weight: 700; line-height: 1.1;
}
.wh-tile.up .wh-tile-pct { color: #2ea043; }
.wh-tile.dn .wh-tile-pct { color: #e5534b; }
.wh-tile.flat .wh-tile-pct { color: var(--md-on-surface-var); }
html[data-theme="light"] .wh-tile.up .wh-tile-pct { color: #135c28; }
html[data-theme="light"] .wh-tile.dn .wh-tile-pct { color: #99261b; }
.wh-tile-meta {
  font-family: var(--font-mono);
  font-size: var(--ct-xs); color: var(--md-on-surface-var);
}
.wh-loading, .wh-meta { color: var(--md-on-surface-var); font-size: var(--ct-sm); }
.wh-status { display: flex; align-items: center; gap: var(--cs-sm); margin-bottom: var(--cs-md); flex-wrap: wrap; }
.wh-live {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.2rem 0.6rem; border-radius: 2rem;
  font-family: var(--font-mono); font-size: var(--ct-xs);
  font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  border: 1px solid var(--md-outline-var);
}
.wh-live-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.wh-live.is-open { color: #2ea043; border-color: rgba(46,160,67,.4); }
.wh-live.is-open .wh-live-dot { background: #2ea043; animation: wh-live-pulse 1.8s ease-in-out infinite; }
.wh-live.is-closed { color: var(--md-on-surface-var); }
.wh-live.is-closed .wh-live-dot { background: var(--md-on-surface-var); }
html[data-theme="light"] .wh-live.is-open { color: #135c28; }
@keyframes wh-live-pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) { .wh-live-dot { animation: none !important; } }
.wh-status .wh-meta { margin: 0; }

/* ══════════════════════════════════════════════════════════════════════
   FORMULA CALLOUT - shaded box for the one line worth remembering
══════════════════════════════════════════════════════════════════════ */
.pai-formula {
  margin: var(--cs-md) 0;
  padding: var(--cs-md) var(--cs-lg);
  background: var(--md-primary-container);
  color: var(--md-on-primary-cont);
  border-radius: var(--cs-xs);
  font-size: var(--ct-lg);
  font-weight: 700;
  line-height: 1.5;
  text-align: center;
}

/* ══════════════════════════════════════════════════════════════════════
   PULL QUOTE - tonal surface, primary accent rule (MD3 expressive)
══════════════════════════════════════════════════════════════════════ */
.pai-quote {
  margin: var(--cs-lg) 0;
  padding: var(--cs-md) var(--cs-lg);
  background: var(--md-surf-2);
  border-left: 3px solid var(--md-primary);
  border-radius: var(--cs-xs);
}
.pai-quote p {
  margin: 0;
  font-size: var(--ct-lg);
  line-height: 1.5;
  font-style: italic;
  color: var(--md-on-surface);
}
.pai-quote cite {
  display: block;
  margin-top: var(--cs-sm);
  font-size: var(--ct-sm);
  font-style: normal;
  font-weight: 600;
  color: var(--md-on-surface-var);
}

/* ══════════════════════════════════════════════════════════════════════
   ERROR PAGE
══════════════════════════════════════════════════════════════════════ */
.err-wrap {
  max-width: 40rem;
  margin: 0 auto;
  padding: var(--cs-xl) var(--cs-md);
  text-align: center;
}
.err-code {
  font-size: clamp(4.5rem, 16vw, 7.5rem);
  font-weight: 900; line-height: 1;
  color: var(--loss); opacity: .18;
  letter-spacing: -.04em; user-select: none;
}
.err-icon {
  font-size: 3rem;
  margin: var(--cs-lg) 0 var(--cs-md);
  color: var(--loss);
}
.err-title {
  font-size: clamp(1.25rem, 4vw, 1.75rem);
  font-weight: 800; color: var(--md-on-surface);
  margin-bottom: var(--cs-xs);
}
.err-sub {
  font-size: var(--ct-md);
  color: var(--md-on-surface-var);
  line-height: 1.6; margin-bottom: var(--cs-xl);
}
.err-card {
  background: var(--md-outline-var);
  border: 1px solid var(--md-outline-var);
  border-radius: 0.75rem;
  padding: var(--cs-lg); margin-bottom: var(--cs-xl);
  text-align: left;
}
.err-card-label {
  font-size: var(--ct-2xs); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--md-on-surface-var); margin-bottom: var(--cs-xs);
}
.err-request-id {
  font-family: monospace; font-size: var(--ct-xs);
  color: var(--md-primary); word-break: break-all;
}
.err-home {
  display: inline-flex; align-items: center; gap: var(--cs-xs);
  padding: 0.75rem 1.75rem; border-radius: 1.5rem;
  background: var(--md-primary); color: var(--md-on-primary);
  font-size: var(--ct-base); font-weight: 700;
  text-decoration: none; transition: opacity .15s;
}
.err-home:hover { opacity: .85; }

/* ══════════════════════════════════════════════════════════════════════
   RESPONSIVE BREAKPOINTS
   xs   < 30rem  (480px)   small mobile
   sm   < 48rem  (768px)   mobile
   md   < 80rem  (1280px)  tablet, base styles cover this range
   lg   ≥ 80rem  (1280px)  large desktop
   xl   ≥ 120rem (1920px)  1440p / QHD
   2xl  ≥ 160rem (2560px)  4K / UHD
══════════════════════════════════════════════════════════════════════ */

/* ── xs, small mobile (< 480px) ───────────────────────────────────── */
@media (max-width: 30rem) {
  /* Layout */
  .legal-page   { padding: 0 var(--cs-sm) var(--cs-xl); }
  .legal-hero   { padding: var(--cs-lg) var(--cs-md); }
  .legal-section { padding: var(--cs-md) var(--cs-lg); }
  .legal-section-header { flex-direction: column; gap: var(--cs-xs); }
  .legal-contact { flex-direction: column; text-align: center; gap: var(--cs-md); }
  .legal-contact-icon { margin: 0 auto; }
  .legal-toc    { padding: var(--cs-md) var(--cs-lg); }
  .legal-toc ol { grid-template-columns: 1fr; }

  /* Hero text */
  .legal-hero-eyebrow { font-size: var(--ct-2xs); }
  .legal-hero-meta    { gap: var(--cs-sm); flex-wrap: wrap; }

  /* Support buttons, stack vertically */
  .support-links  { flex-direction: column; }
  .support-btn    { width: 100%; justify-content: flex-start; }

  /* About */
  .about-feature-grid { grid-template-columns: 1fr; }
  .content-footer     { grid-template-columns: 1fr; padding: 1rem; }

  /* Visitor analytics */
  .va-wrap         { padding: var(--cs-md) var(--cs-sm); }
  .va-kpi-grid     { grid-template-columns: repeat(2, 1fr); gap: var(--cs-sm); }
  .va-kpi          { padding: var(--cs-sm) var(--cs-md); }
  .va-kpi-value    { font-size: clamp(1.5rem, 7vw, 2rem); }
  .va-breakdown-grid { grid-template-columns: 1fr; }
  .va-bar-label    { width: 6.5rem; font-size: var(--ct-xs); }
  .va-table th, .va-table td { padding: 0.375rem 0.5rem; font-size: var(--ct-xs); }
  .va-table td     { max-width: 8rem; }

  /* Content tables are a communication surface, not an admin grid: the dense
     va-table clamp above drops to 10-12px, well under the surrounding prose.
     Restore MD3 body sizing and padding for .md3-table-card only. */
  .md3-table-card td { padding: 0.7rem 0.8rem; font-size: var(--ct-base); max-width: none; }
  .md3-table-card th { padding: 0.7rem 0.8rem; font-size: var(--ct-sm); }
  .md3-table-card td:first-child,
  .md3-table-card th:first-child { max-width: 7.5rem; }

  /* Affiliates, horizontal scroll, tighter cells */
  .aff-mgmt-table  { font-size: var(--ct-2xs); }
  .aff-mgmt-table th, .aff-mgmt-table td { padding: 0.375rem 0.5rem; }
  .aff-td-notes    { max-width: 6rem; }

  /* Comparison table */
  .cmp-table       { font-size: var(--ct-2xs); }
  .cmp-table th, .cmp-table td { padding: 0.25rem 0.375rem; }

  /* Data / content tables */
  .ds-table        { font-size: var(--ct-2xs); }
  .ds-table th, .ds-table td { padding: 0.25rem 0.375rem; }

  /* Error page */
  .err-wrap        { padding: var(--cs-lg) var(--cs-sm); }
  .err-home        { width: 100%; justify-content: center; }
}

/* ── sm, mobile (< 768px) ─────────────────────────────────────────── */
@media (max-width: 48rem) {
  /* Layout */
  .legal-page     { padding: 0 var(--cs-md) var(--cs-xl); }
  .legal-hero     { padding: var(--cs-xl) var(--cs-lg) var(--cs-lg); }
  .legal-section  { padding: var(--cs-lg) var(--cs-xl); }
  .legal-toc ol   { grid-template-columns: 1fr; }
  .legal-contact  { flex-direction: column; text-align: center; gap: var(--cs-md); }
  .legal-contact-icon { margin: 0 auto; }

  /* Hero */
  .legal-hero-title { font-size: clamp(1.25rem, 5vw, 1.75rem); }
  .legal-hero-meta  { gap: var(--cs-sm); }

  /* Support */
  .support-links  { gap: var(--cs-sm); }

  /* Visitor analytics */
  .va-kpi-grid    { grid-template-columns: repeat(3, 1fr); gap: var(--cs-sm); }
  .va-kpi-value   { font-size: clamp(1.75rem, 5vw, 2.5rem); }
  .va-breakdown-grid { grid-template-columns: 1fr; }
  .va-bar-label   { width: 7.5rem; }
  .va-table th, .va-table td { padding: 0.4375rem 0.625rem; }

  /* Affiliates */
  .aff-mgmt-table { font-size: var(--ct-xs); }
  .aff-mgmt-table th, .aff-mgmt-table td { padding: 0.5rem 0.625rem; }

  /* Comparison table */
  .cmp-table      { font-size: var(--ct-xs); }
  .cmp-table th, .cmp-table td { padding: var(--cs-2xs) var(--cs-xs); }

  /* Data / content tables */
  .ds-table       { font-size: var(--ct-xs); }
  .ds-table th, .ds-table td { padding: var(--cs-2xs) var(--cs-xs); }
}

/* ── md, tablet / small desktop (< 1280px), base styles cover this ─ */

/* ── lg, large desktop (≥ 1280px) ─────────────────────────────────── */
@media (min-width: 80rem) {
  :root {
    --content-w:      min(80vw, 72rem);
    --content-w-wide: min(88vw, 100rem);
  }
  .legal-section      { padding: var(--cs-xl) var(--cs-2xl); }
  .about-feature-grid { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
  .va-breakdown-grid  { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }
  .va-kpi-grid        { grid-template-columns: repeat(5, 1fr); }
}

/* ── xl, 1440p / QHD (≥ 1920px) ──────────────────────────────────── */
@media (min-width: 120rem) {
  :root {
    --content-w:      min(70vw, 80rem);
    --content-w-wide: min(82vw, 112rem);
  }
  .legal-hero         { padding: var(--cs-2xl); }
  .va-kpi-grid        { gap: var(--cs-lg); }
  .va-breakdown-grid  { grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); }
  .aff-mgmt-table th, .aff-mgmt-table td { padding: 0.875rem 1rem; }
}

/* ── 2xl, 4K / UHD (≥ 2560px) ────────────────────────────────────── */
@media (min-width: 160rem) {
  :root {
    --content-w:      min(60vw, 90rem);
    --content-w-wide: min(72vw, 130rem);
  }
  .legal-section      { padding: var(--cs-2xl); }
  .about-feature-grid { grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); }
  .va-kpi-grid        { gap: var(--cs-xl); }
  .va-kpi             { padding: var(--cs-lg) var(--cs-xl); }
  .va-kpi-value       { font-size: clamp(3rem, 4vw, 4rem); }
  .va-breakdown-grid  { grid-template-columns: repeat(auto-fit, minmax(26rem, 1fr)); }
  .aff-mgmt-table th, .aff-mgmt-table td { padding: 1rem 1.25rem; }
  .va-table th, .va-table td { padding: 0.75rem 1rem; font-size: var(--ct-base); }
}

/* ══════════════════════════════════════════════════════════════════════
   MARKETS TODAY (/markets-today)
   The daily brief page. MD3 Expressive: tonal container per brief, a
   primary-coloured overline, display type for the headline and a shape
   scale that matches .legal-hero. Session chips reuse .wh-live.
   ══════════════════════════════════════════════════════════════════════ */

/* Row of open/closed chips under the hero. Layout only: the chips
   themselves are the shared .wh-live component. */
.mtd-sessions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-xs);
  justify-content: center;
  margin: 0 0 var(--cs-lg);
}

/* Times swapped to the reader's zone by markets-today.js. The dotted rule
   hints that the value is localised rather than fixed. */
.mtd-time {
  font-family: var(--font-mono);
  border-bottom: 1px dotted var(--md-outline-var);
}

.mtd-empty {
  padding: var(--cs-md);
  background: var(--md-surf-2);
  border-radius: var(--shape-lg);
  color: var(--md-on-surface-var);
}

/* ── One brief ───────────────────────────────────────────────────────── */
/* Tonal surface rather than an outlined card: MD3 Expressive leans on
   colour rather than borders to separate a block from the page. */
.mtd-brief {
  position: relative;
  background: var(--md-surf-2);
  border-radius: var(--shape-xl);          /* shape.corner.extra-large, as .legal-hero */
  padding: var(--cs-lg) var(--cs-lg) var(--cs-md);
  margin: 0 0 var(--cs-lg);
  overflow: hidden;
}

/* Expressive accent edge, echoing the .legal-section top gradient. */
.mtd-brief::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  background: linear-gradient(180deg, var(--md-primary), var(--md-secondary));
}

.mtd-brief-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--cs-xs);
  margin-bottom: var(--cs-xs);
}

.mtd-brief-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--md-primary);
}

.mtd-brief-time {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  color: var(--md-on-surface-var);
}

/* Headline carries the page: display face, large role, balanced wrap. */
.mtd-brief-headline {
  font-family: var(--font-display);
  font-size: var(--ct-lg);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -.01em;
  color: var(--md-on-background);
  margin: 0 0 var(--cs-xs);
  text-wrap: balance;
}

.mtd-brief-summary {
  font-size: var(--ct-md);
  line-height: 1.6;
  color: var(--md-on-surface);
  margin: 0 0 var(--cs-md);
}

.mtd-brief-block { margin-bottom: var(--cs-sm); }
.mtd-brief-block p { margin: 0; }

.mtd-brief-block-title {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--md-on-surface-var);
  margin-bottom: var(--cs-2xs);
}

/* ── World table ─────────────────────────────────────────────────────── */
.mtd-region { margin-bottom: var(--cs-lg); }

.mtd-region-title {
  font-family: var(--font-display);
  font-size: var(--ct-md);
  font-weight: 700;
  color: var(--md-on-background);
  margin: 0 0 var(--cs-xs);
}

/* Wide tables scroll inside their own box so the page never scrolls sideways. */
.mtd-table-wrap {
  overflow-x: auto;
  border-radius: var(--shape-lg);
  border: 1px solid var(--md-outline-var);
}

.mtd-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--ct-sm);
}

.mtd-table th,
.mtd-table td {
  padding: var(--cs-xs) var(--cs-sm);
  text-align: left;
  white-space: nowrap;
}

.mtd-table th {
  background: var(--md-surf-2);
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--md-on-surface-var);
}

.mtd-table tbody tr + tr td { border-top: 1px solid var(--md-outline-var); }

.mtd-table td:nth-child(2),
.mtd-table td:nth-child(3) { font-family: var(--font-mono); text-align: right; }

.mtd-table th:nth-child(2),
.mtd-table th:nth-child(3) { text-align: right; }

.mtd-ticker {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  color: var(--md-on-surface-var);
  margin-left: .35rem;
}

/* Same greens and reds the world heatmap uses, including its light-theme
   contrast fix, so a rise looks identical across the site. */
.mtd-up   { color: #2ea043; }
.mtd-down { color: #e5534b; }
html[data-theme="light"] .mtd-up   { color: #135c28; }
html[data-theme="light"] .mtd-down { color: #99261b; }

@media (max-width: 640px) {
  .mtd-brief { padding: var(--cs-md) var(--cs-md) var(--cs-sm); }
  .mtd-brief-head { flex-direction: column; align-items: flex-start; gap: var(--cs-2xs); }
}

/* ── Market temperature, the day-arc ─────────────────────────────────────
   One 0-100 reading per session plotted on a shared track, so the reader
   sees the mood handed from Tokyo to London to New York rather than a
   single snapshot. Marker positions come from a dynamic style binding
   (style="@left"), which is data, not styling. */
.mtd-arc {
  background: var(--md-surf-2);
  border-radius: var(--shape-xl);
  padding: var(--cs-md) var(--cs-lg) var(--cs-md);
  margin: 0 0 var(--cs-lg);
}

.mtd-arc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cs-sm);
  margin-bottom: var(--cs-sm);
}

.mtd-arc-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--md-primary);
}

.mtd-arc-tone {
  font-family: var(--font-display);
  font-size: var(--ct-lg);
  font-weight: 700;
  line-height: 1.15;
  color: var(--md-on-background);
}

/* Expressive focal number: large, tabular, quiet in colour so the tone
   word stays the headline and the digits support it. */
.mtd-arc-value {
  font-family: var(--font-mono);
  font-size: var(--ct-xl);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--md-on-surface-var);
}

/* The scale itself. Same reds and greens as the heatmap, so a rise reads
   the same everywhere on the site. */
.mtd-arc-track {
  position: relative;
  height: 10px;
  border-radius: var(--shape-full, 999px);
  background: linear-gradient(90deg, #e5534b 0%, #d7a52b 50%, #2ea043 100%);
  /* Fixed bottom gap, not a clamp token: it has to clear the staggered labels
     below the track, whose offsets are fixed rem values. */
  margin: var(--cs-lg) 0 4rem;
}

.mtd-arc-marker {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
}

.mtd-arc-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--md-surf-1);
  border: 3px solid var(--md-on-background);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
}

/* The newest reading is the one that matters now, so it gets the accent. */
.mtd-arc-marker:last-child .mtd-arc-dot {
  border-color: var(--md-primary);
  transform: scale(1.15);
}

.mtd-arc-label {
  position: absolute;
  top: 1.25rem;
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  font-weight: 700;
  white-space: nowrap;
  color: var(--md-on-surface-var);
}

/* Stagger every second label so two close readings do not collide. */
.mtd-arc-marker:nth-child(even) .mtd-arc-label { top: 2.4rem; }

.mtd-arc-scale {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--ct-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--md-on-surface-var);
  margin-bottom: var(--cs-sm);
}

.mtd-arc-note {
  font-size: var(--ct-sm);
  line-height: 1.55;
  color: var(--md-on-surface-var);
  margin: 0;
}

@media (max-width: 640px) {
  .mtd-arc { padding: var(--cs-md); }
  .mtd-arc-head { align-items: flex-start; }
}

/* ── /is-the-market-open: exchange clocks ──────────────────────────────────────
   Phase is carried three ways on purpose: dial colour, the tonal chip, and the
   text label. Colour alone would fail in greyscale and for colourblind readers,
   and this page's whole job is being unambiguous about open versus closed.
   Every colour resolves through the shared tokens, so light and dark both work
   without a second stylesheet. ------------------------------------------------ */

/* Phase colours are literal here, not token aliases, and identical in both themes.
   The wall is read as an instrument at a glance, often across a room on a spare monitor,
   so the mint and the amber are the page's own signal rather than the dashboard's
   gain green and callout tan, which shift per theme and were tuned for text. */
.mkc-page {
  --mkc-open:    #57e5c6;
  --mkc-edge:    #dc9f59;
  --mkc-lunch:   var(--md-primary);
  --mkc-shut:    var(--md-outline);
  /* Sized so three rows of four plus the header and legend clear a 900px viewport without
     scrolling, which is the whole promise of the page. */
  --mkc-dial:    5.875rem;
}

/* No hero on this page: the clocks are the content and a tall hero pushed all twelve below
   the fold. The header is two lines total, the question and then the answer, because every
   line here costs a row of clocks. */
.mkc-head { margin: 0 0 var(--cs-sm); }

.mkc-head .legal-hero-title {
  font-size: var(--ct-lg);
  line-height: 1.25;
  margin: 0 0 .15rem;
}

/* Answer and status on one line, baseline aligned, wrapping only when they truly cannot fit. */
.mkc-line {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .35rem var(--cs-sm);
}

.mkc-status {
  font-size: var(--ct-xs);
  color: var(--md-outline);
  font-variant-numeric: tabular-nums;
  margin: 0;
  white-space: nowrap;
}

/* isolation so the blurred sky behind the cards cannot bleed over neighbouring sections. */
.mkc-wall {
  position: relative;
  isolation: isolate;
  margin: 0 0 var(--cs-md);
  padding: var(--cs-xs);
  border-radius: 1.75rem;
  overflow: hidden;
}

/* The light the glass refracts. Hue is set by market-clocks.js from the UTC hour. */
.mkc-sky {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}

.mkc-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(58px);
  opacity: .42;
  transition: background 2s linear;
}

.mkc-blob--1 { width: 18rem; height: 18rem; left: -3rem;  top: -4rem; }
.mkc-blob--2 { width: 20rem; height: 20rem; right: -4rem; top: 2rem; }
.mkc-blob--3 { width: 19rem; height: 19rem; left: 38%;    bottom: -6rem; }

/* Offset sits under the city as a quiet attribute of the place, not of the countdown. */
.mkc-offset {
  font-size: var(--ct-2xs);
  color: var(--md-outline);
  margin: 0 0 var(--cs-2xs);
}

.mkc-answer {
  font-size: var(--ct-base);
  line-height: 1.35;
  color: var(--md-on-surface);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.mkc-empty {
  font-size: var(--ct-base);
  line-height: 1.6;
  color: var(--md-on-surface-var);
  background: var(--md-surf-2);
  border-radius: 1rem;
  padding: var(--cs-md);
}

/* MD3 title-small with a rule that runs to the edge. Used by the session map heading. */
.mkc-region-title {
  display: flex;
  align-items: center;
  gap: var(--cs-sm);
  font-size: var(--ct-sm);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--md-outline);
  margin: 0 0 var(--cs-xs);
}

.mkc-region-title::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--md-hairline);
}

/* auto-fill, not auto-fit: auto-fit collapses empty tracks, so a region holding one
   exchange (Middle East, Africa) would stretch that card across the full width. */
/* Fixed six per row, two rows of six. A fluid auto-fill count made the wall reflow into
   ragged rows at some widths, and the twelve are a deliberate set, not a feed.
   grid-auto-rows: 1fr keeps every card the same height whatever text it carries. */
/* Four per row, three rows. Six fitted, but a 9px ring and readable numerals need the
   width. grid-auto-rows: 1fr keeps every card the same height whatever text it carries. */
.mkc-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: var(--cs-xs);
}

.mkc-caveat {
  font-size: var(--ct-xs);
  line-height: 1.5;
  color: var(--md-outline);
  background: var(--md-surf-2);
  border-radius: .875rem;
  padding: var(--cs-sm) var(--cs-md);
  margin: var(--cs-md) 0;
}

/* Expressive tonal container rather than a bordered card: the surface itself
   carries the elevation, which is what MD3 Expressive asks for. */
/* Frosted glass over the sky above. Same material the AI Mood popup uses, so this is an
   extension of the house style rather than a new one. */
.mkc-card {
  position: relative;
  z-index: 1;
  /* The specular sheen down the top half, which is what makes this read as a pane of glass
     catching a light source rather than as a tinted rectangle. Real glass is brightest at
     the top edge and falls off fast, so the ramp is front-loaded: most of the lift is spent
     in the first third and it is gone by 62%, leaving the lower half clean for the dial.
     Two stops rather than one, because a single linear fade to transparent greys out through
     the middle instead of falling away.

     A background layer, not a ::before. The card already spends ::after on the New York
     marker, and an absolutely positioned pseudo-element inside a box whose children are all
     static would paint over the city name and the countdown. */
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .13) 0%,
      rgba(255, 255, 255, .05) 34%,
      rgba(255, 255, 255, 0)   62%),
    rgba(255, 255, 255, .05);
  /* Every card carries its continent on the rim, not just the trading ones. The legend
     below the wall names five regions, and a closed market is still on its continent, so
     a neutral rim left four of the five legend colours pointing at nothing for most of
     the day. Low alpha keeps the glass intact; the live cards lift to 70% further down. */
  border: 1px solid color-mix(in srgb, var(--mkc-phase) 34%, transparent);
  border-radius: 1.625rem;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .2), 0 6px 20px rgba(0, 0, 0, .28);
  padding: var(--cs-sm) var(--cs-2xs);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .1rem;
}

/* Blur is the single most expensive thing on this page: one compositing layer per card,
   twelve of them, on a page that also ticks every second. Desktop only. Mobile keeps the
   translucent fill, which reads almost the same and costs nothing. */
@media (min-width: 641px) {
  .mkc-card {
    -webkit-backdrop-filter: blur(16px) saturate(150%);
    backdrop-filter: blur(16px) saturate(150%);
  }
}

/* The chip sits on the baseline of every card regardless of how many text lines are above
   it, so a row of six reads as one object rather than six ragged ones. */
.mkc-card .mkc-chip { margin-top: auto; }

/* The live ones still lead: brighter glass and the same continent colour raised from the
   base 32% to full strength, so the trading markets read first without the closed ones
   losing their region. */
/* The sheen is restated in every rule that sets background, here and in both light-mode
   rules below. background is a shorthand: naming only a colour drops the gradient layer
   with it, and a live card would go flat while the closed ones beside it kept their glass. */
.mkc-card.is-open,
.mkc-card.is-auction,
.mkc-card.is-power,
.mkc-card.is-lunch {
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .16) 0%,
      rgba(255, 255, 255, .06) 34%,
      rgba(255, 255, 255, 0)   62%),
    rgba(255, 255, 255, .085);
  border-color: color-mix(in srgb, var(--mkc-phase) 72%, transparent);
}

/* Continent accents are gone. The rim now carries trading state, the same colour the
   dial and the countdown already use, so a card says one thing loudly instead of two
   things quietly. Geography was costing a five-colour legend to explain something the
   city name already tells you. */

/* Light mode: white-on-white glass is invisible, so the frost inverts. The panes become
   near-opaque white over a much fainter sky, which reads as frosted rather than as the
   luminous night version, and keeps small text legible. */
/* Light mode gets the sheen as a highlight rather than a lift: more white on an already
   near-white pane is invisible, so the top instead goes fully opaque and fades to the
   translucent body, which is how glass over a pale ground actually behaves. */
html[data-theme="light"] body:not(.is-dashboard) .mkc-card {
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .92) 0%,
      rgba(255, 255, 255, .30) 34%,
      rgba(255, 255, 255, 0)   62%),
    rgba(255, 255, 255, .62);
  border-color: rgba(0, 0, 0, .08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9), 0 4px 14px rgba(0, 0, 0, .08);
}

html[data-theme="light"] body:not(.is-dashboard) .mkc-card.is-open,
html[data-theme="light"] body:not(.is-dashboard) .mkc-card.is-auction,
html[data-theme="light"] body:not(.is-dashboard) .mkc-card.is-power,
html[data-theme="light"] body:not(.is-dashboard) .mkc-card.is-lunch {
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .95) 0%,
      rgba(255, 255, 255, .34) 34%,
      rgba(255, 255, 255, 0)   62%),
    rgba(255, 255, 255, .78);
}

html[data-theme="light"] body:not(.is-dashboard) .mkc-blob      { opacity: .22; }
html[data-theme="light"] body:not(.is-dashboard) .mkc-dial-track { stroke: rgba(0, 0, 0, .12); }

/* Same scoping the rest of this file uses for light mode: html[data-theme] is set
   pre-paint, and only content pages are re-pointed. */

.mkc-dial {
  position: relative;
  width: var(--mkc-dial);
  height: var(--mkc-dial);
  margin-bottom: var(--cs-2xs);
}

.mkc-dial svg { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Thick enough to read as an instrument. At 7 the ring looked like a border.

   Both rings are a ladder of ticks rather than a solid stroke, which is what makes
   the dial read as a gauge instead of a progress bar. pathLength="100" in the markup
   normalises the circumference, so the dash pair is read directly as a percentage of
   the ring and never needs recomputing against 257.6.

   "1.36 0.64" is a period of 2, so 50 ticks, with the gap taking a third of each step.
   It was 40 ticks on a 2.5 period whose gap took 58%, which left the ring reading as
   separated dashes rather than as a machined scale. Narrower gaps and more of them is
   the whole difference between a countdown and an instrument. */
.mkc-dial-track,
.mkc-dial-fill {
  fill: none;
  stroke-width: 9;
  stroke-dasharray: 1.36 0.64;
}

.mkc-dial-track { stroke: rgba(255, 255, 255, .16); }

/* Only a live session glows, so trading markets pull the eye with no extra label.
   Keyed off --mkc-phase rather than currentColor: an SVG stroke does not inherit from it. */
.mkc-card.is-open    .mkc-dial-fill,
.mkc-card.is-auction .mkc-dial-fill,
.mkc-card.is-power   .mkc-dial-fill,
.mkc-card.is-lunch   .mkc-dial-fill {
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mkc-phase) 48%, transparent));
}

/* butt, not round: round caps on a 1.05-long tick swell it into a dot and close the
   gaps the ticks exist to make. The progress is a mask now, not this element's own
   dash offset, so there is no dashoffset left to animate. */
.mkc-dial-fill {
  stroke: var(--mkc-shut);
  stroke-linecap: butt;
  transition: stroke .3s ease;
}

/* Google Sans Display carries tnum, verified in the shipped woff2, so the digits
   do not jitter as the countdown ticks. No extra font needed. */
.mkc-count {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Google Sans Display', 'Google Sans', system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  /* Sized to fit H:MM:SS inside the ring, which is the widest form the dial ever shows.
     var(--ct-md) overflowed and clipped the seconds. */
  font-size: var(--ct-sm);
  font-weight: 500;
  letter-spacing: -.02em;
  white-space: nowrap;
  color: var(--md-on-surface);
}

.mkc-city {
  font-size: var(--ct-base);
  font-weight: 500;
  color: var(--md-on-surface);
  margin: 0;
}

.mkc-local,
.mkc-boundary,
.mkc-reason {
  font-size: var(--ct-xs);
  line-height: 1.35;
  margin: 0;
}

.mkc-local    { color: var(--md-on-surface-var); font-variant-numeric: tabular-nums; }
.mkc-boundary { color: var(--md-outline); }
.mkc-reason   { color: var(--md-callout-text); font-weight: 500; }

/* Tonal chip, MD3 assist-chip proportions. */
.mkc-chip {
  margin-top: var(--cs-2xs);
  display: inline-block;
  font-size: var(--ct-2xs);
  line-height: 1;
  padding: .3rem .6rem;
  border-radius: 999px;
  background: var(--md-surf-3);
  color: var(--md-on-surface-var);
}

/* New York is roughly 45% of world equity value, so it gets a permanent marker while the
   wall rotates around it. A dot and a brighter pane, deliberately quiet: it must be
   findable in one sweep without out-shouting the phase colours, which are the real signal. */
/* Same class count as .mkc-card and later in the file, so this wins outright: without the
   gradient restated, New York would be the one flat pane on a wall of glass ones. */
.mkc-card--primary {
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .16) 0%,
      rgba(255, 255, 255, .06) 34%,
      rgba(255, 255, 255, 0)   62%),
    rgba(255, 255, 255, .085);
  border-color: rgba(255, 255, 255, .28);
}

.mkc-card--primary::after {
  content: "";
  position: absolute;
  top: .7rem;
  right: .7rem;
  width: .35rem;
  height: .35rem;
  border-radius: 50%;
  background: var(--md-primary);
}

html[data-theme="light"] body:not(.is-dashboard) .mkc-card--primary {
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .95) 0%,
      rgba(255, 255, 255, .34) 34%,
      rgba(255, 255, 255, 0)   62%),
    rgba(255, 255, 255, .82);
  border-color: rgba(0, 0, 0, .16);
}

/* One variable drives ring, glow and chip, so the three can never disagree about phase. */
.mkc-card              { --mkc-phase: var(--mkc-shut); }
.mkc-card.is-open      { --mkc-phase: var(--mkc-open); }
.mkc-card.is-auction,
.mkc-card.is-power     { --mkc-phase: var(--mkc-edge); }
.mkc-card.is-lunch     { --mkc-phase: var(--mkc-lunch); }

.mkc-dial-fill { stroke: var(--mkc-phase); }

/* Opaque, and the text lifted off the pure phase hue.
   Two problems, one fix. The phase colour on a 20% wash of itself measured
   4.13:1 for the closed and pre-open chips against 4.5 required at this size,
   and only 4.59:1 when open. The wash was also transparent, sitting on a
   translucent card over a blurred blob, so an auditing tool cannot resolve a
   real background at all and reports the whole stack.
   Mixing the fill into an opaque surface and the text toward on-surface makes
   the value computable and clears 4.5 on every phase in both themes.

   Re-measured after the ring colours became literal mint and amber, identical in
   both themes. Dark is comfortable at a 70% text mix, worst case first: closed
   5.56, edge 6.49, lunch 7.01, open 7.60. Light is not: against a near-white chip
   the same 70% mix put open at 2.55, because 70% of a bright mint plus 30% of a
   near-black on-surface is still a pale colour. The hue is the thing being kept
   identical, not the text weight, so light mode pulls the text further toward
   on-surface and clears 4.5 again: at 42% it measures open 4.88, edge 5.84,
   shut 7.66, lunch 8.70.

   42% rather than the 45% that first cleared: 45% put the open chip at exactly
   4.50, which is the threshold itself and not a margin. Going much below 40 starts
   turning the mint and the amber grey, which is the one thing this chip exists to
   say, so the usable band is narrow and 42 sits in the middle of it. */
.mkc-chip {
  background: color-mix(in srgb, var(--mkc-phase) 14%, var(--md-surf-2));
  color: color-mix(in srgb, var(--mkc-phase) 70%, var(--md-on-surface));
}

html[data-theme="light"] body:not(.is-dashboard) .mkc-chip {
  color: color-mix(in srgb, var(--mkc-phase) 42%, var(--md-on-surface));
}

.mkc-card.is-closed  .mkc-count,
.mkc-card.is-holiday .mkc-count { color: var(--md-outline); }

/* ── 24h session map ──────────────────────────────────────────────────────── */

/* Hours as prose. Deliberately plain: these exist to be quoted by an answer engine and
   read by anyone who wants the schedule rather than the live state. */
.mkc-hours { margin: var(--cs-lg) 0; }

/* The table is the same material as the clocks: a tonal glass container with a large
   corner radius, so it reads as part of the wall rather than as an HTML table dropped
   underneath it. Scrolls itself instead of widening the page, which is how a six-column
   table normally breaks a phone. */
/* ── Trading hours table, Material Design 3 ────────────────────────────────────
   Built to the M3 data-table spec rather than to the page's glass: solid surface
   containers, dividers instead of zebra, and the venue as an assist chip. Glass was
   the wrong material here, a table needs a stable ground for long rows of numbers.

   Type is the M3 scale at fixed sizes, not the fluid --ct-* clamps: those are for
   dense dashboard readouts, and a table people read is a communication surface.
     label-large   14/500   column headers
     title-medium  16/500   exchange names
     body-medium   14/400   data cells
     label-small   11/500   venue chips
   ------------------------------------------------------------------------------ */

.mkc-hours-scroll {
  overflow-x: auto;
  border-radius: 12px;                     /* shape-corner-medium */
  background: var(--md-surf-1);            /* surface-container-low */
}

.mkc-hours-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

/* Header row: surface-container, 56dp, label-large. */
.mkc-hours-table thead th {
  height: 3.5rem;
  background: var(--md-surf-2);
  color: var(--md-on-surface);
  font-size: .875rem;
  font-weight: 500;
  letter-spacing: .00625em;
  text-align: left;
  white-space: nowrap;
  padding: 0 1rem 0 0;                     /* 16dp between columns */
  border-bottom: 1px solid var(--md-outline-var);
}

/* 24dp at the start and end of every row. */
.mkc-hours-table th:first-child,
.mkc-hours-table td:first-child { padding-left: 1.5rem; }
.mkc-hours-table th:last-child,
.mkc-hours-table td:last-child  { padding-right: 1.5rem; }

/* Data rows: 52dp, body-medium, horizontal dividers only. M3 tables separate
   columns with whitespace, never with vertical rules. */
.mkc-hours-table tbody td,
.mkc-hours-table tbody th {
  height: 3.25rem;
  padding: 0 1rem 0 0;
  text-align: left;
  vertical-align: middle;
  white-space: nowrap;
  border-bottom: 1px solid var(--md-outline-var);
  font-size: .875rem;
  font-weight: 400;
  color: var(--md-on-surface-var);         /* on-surface-variant */
}

.mkc-hours-table tbody tr:last-child td,
.mkc-hours-table tbody tr:last-child th { border-bottom: 0; }

/* Exchange name: title-medium on-surface, the one primary column. */
.mkc-hours-table tbody th {
  font-size: 1rem;
  font-weight: 500;
  color: var(--md-on-surface);
}

/* Name and chip share the cell, but the chip is pushed to the column's trailing edge so
   the twelve chips form a straight column. Left as an inner flex wrapper rather than
   display:flex on the th itself, which would stop it being a table-cell and break the
   column widths the rest of the table depends on. */
/* Venue as an M3 assist chip, now that it has its own column: the table aligns the chips
   into a straight edge for free, which is what made them look wrong when they trailed the
   city name inside a stretching cell.
   32dp high, shape-corner-small (8dp), secondary-container with its on-color, label-small. */
.mkc-hours-venue {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 3.25rem;
  height: 2rem;
  padding: 0 .625rem;
  border-radius: 8px;
  background: var(--md-secondary-cont);
  color: var(--md-on-secondary-cont);
  font-size: .6875rem;
  /* Matches .mkc-venue on the cards: the same twelve codes appear in both places and it
     would be odd for NYSE to be bold on its card and not in the table under it. */
  font-weight: 700;
  letter-spacing: .03em;
}

/* State layers: 8% on-surface on hover, 12% plus a 2dp primary outline on focus. */
.mkc-hours-table tbody tr {
  transition: background .15s cubic-bezier(.2, 0, 0, 1);
}

.mkc-hours-table tbody tr:hover {
  background: color-mix(in srgb, var(--md-on-surface) 8%, transparent);
}

.mkc-hours-table tbody tr:focus-within {
  background: color-mix(in srgb, var(--md-on-surface) 12%, transparent);
  outline: 2px solid var(--md-primary);
  outline-offset: -2px;
}

/* The sentences exist to be quoted, so they stay readable prose rather than shrinking into
   a footnote: MD3 body-medium, two columns on a wide screen so twelve of them do not turn
   into a wall of text. */
.mkc-hours-prose {
  margin: var(--cs-md) 0 0;
  columns: 2;
  column-gap: var(--cs-xl);
}

.mkc-hours-prose p {
  break-inside: avoid;
  margin: 0 0 var(--cs-sm);
  font-size: .875rem;
  line-height: 1.6;
  color: var(--md-on-surface-var);
}

@media (max-width: 720px) {
  .mkc-hours-prose { columns: 1; }
}

.mkc-hours-note {
  font-size: var(--ct-xs);
  color: var(--md-outline);
  line-height: 1.5;
  margin: var(--cs-sm) 0 0;
}

/* Deep links land on a card or an hours row, so keep them clear of the top bar. */
.mkc-card[id],
.mkc-hours-table tr[id] { scroll-margin-top: 5rem; }

.mkc-map { margin: var(--cs-xl) 0 var(--cs-lg); }

.mkc-map-rows { display: flex; flex-direction: column; gap: .3rem; }

.mkc-map-row {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  align-items: center;
  gap: var(--cs-xs);
}

.mkc-map-label {
  font-size: var(--ct-xs);
  color: var(--md-on-surface-var);
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mkc-map-track {
  position: relative;
  height: .55rem;
  background: var(--md-surf-2);
  border-radius: 999px;
}

.mkc-map-bar {
  position: absolute;
  top: 0;
  height: .55rem;
  border-radius: 999px;
  background: var(--md-outline-var);
}

.mkc-map-bar.is-live { background: var(--mkc-open); }

.mkc-map-scale {
  display: flex;
  justify-content: space-between;
  margin: var(--cs-2xs) 0 0 7.5rem;
  font-size: var(--ct-2xs);
  color: var(--md-outline);
  font-variant-numeric: tabular-nums;
}

.mkc-map-note {
  font-size: var(--ct-sm);
  line-height: 1.55;
  color: var(--md-on-surface-var);
  margin: var(--cs-sm) 0 0;
}

@media (max-width: 1024px) {
  .mkc-page { --mkc-dial: 5.5rem; }
  .mkc-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  /* Three across so all twelve stay on one screen, which is the point of the page. */
  .mkc-page { --mkc-dial: 4rem; }
  .mkc-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .mkc-card { padding: var(--cs-xs) 2px; border-radius: 1.125rem; }
  .mkc-boundary, .mkc-offset { display: none; }
  .mkc-map-row { grid-template-columns: 4.5rem minmax(0, 1fr); }
  .mkc-map-scale { margin-left: 5.5rem; }
  /* Two boundaries only happen during an Asian lunch break, where the line
     would otherwise wrap awkwardly inside a half-width card. */
  .mkc-boundary { font-size: var(--ct-2xs); }
}

@media (prefers-reduced-motion: reduce) {
  .mkc-dial-fill { transition: none; }
}

/* ── Wall mode ─────────────────────────────────────────────────────────────────
   The whole viewport as a clock wall, for a TV, a spare monitor or a desk
   display. Entered from the button on the page or by loading with ?wall=1.

   Note the class is is-wall on the body, not mkc-wall: .mkc-wall is already the
   section that holds the sky, the grid and the legend.

   Everything below the wall is hidden with CSS rather than dropped from the
   markup. The hours table, the twelve sentences and the FAQ are the reason this
   page answers anything for a crawler or an assistant, and a display mode must
   not cost that.                                                            ---- */

body.is-wall .site-nav-launcher,
body.is-wall .mkc-map,
body.is-wall .mkc-caveat,
body.is-wall .mkc-hours,
body.is-wall .legal-section,
body.is-wall .dash-cta,
body.is-wall .content-footer,
/* The copyright line is a sibling of .content-footer in _ContentFooter.cshtml, not a child
   of it, so hiding the nav alone left "© GMD" stranded on the wall. The signature already
   says where the display came from. */
body.is-wall .content-footer-copy,
/* The mobile bottom nav is an in-flow grid row of .shell, 80px of it, so a wall was always
   100dvh of clocks plus 80px and could not help but scroll. Nothing taps a TV anyway. */
body.is-wall .mobile-bottom-nav { display: none; }

/* The page owns the viewport: no max-width, no auto margins, no bottom run-off. */
body.is-wall .mkc-page {
  max-width: none;
  /* Fill the row, do not re-claim the viewport. .shell is already min-height: 100dvh and
     main is its 1fr track, so a second 100dvh here counted the viewport twice: the page
     started 11px down and ended 11px past the fold, which is why the wall scrolled by a
     hair. min-height: 100% cannot do it either, because main is a stretched grid item with
     an auto height and a percentage has nothing definite to resolve against, so the page
     collapsed to its content and left a band of black above the signature.

     So: 100dvh for a definite height the grid can actually divide, plus flex: 1 to absorb
     any rounding against main. main's own padding is zeroed above, which is what stops the
     dvh from overshooting the fold. */
  min-height: 100dvh;
  flex: 1;
  margin: 0;
  /* The bottom pad is the signature's lane. It is fixed to the bottom edge, so without a
     reserved strip it sat on top of the last row of cards and covered their phase chips,
     which are the one thing on the card that names the state in words. Inside the height
     thanks to border-box, so reserving it costs no scroll.

     3rem, measured rather than guessed. main's padding is zeroed above, so the only other
     reservation under the grid is .mkc-wall's own ~10px: 48 + 10 puts the last card row at
     887 on a 945 viewport, which clears a signature whose top edge is 896 without leaving
     the band of dead black that 68px of stacked padding produced. */
  padding: var(--cs-sm) var(--cs-sm) 3rem;
  display: flex;
  flex-direction: column;
}

body.is-wall .shell { padding-top: 0; }

/* main is the 1fr row of .shell, so it already owns the leftover viewport. Two things are
   needed for the wall to use it: a flex column, so .mkc-page can stretch into the height
   rather than sit at its content size, and no padding of its own. That padding was ~11px
   top and bottom, and it is the entire reason a 100dvh page ended 11px past the fold and
   the wall scrolled by a hair. Removing it here is better than subtracting it in a calc()
   somewhere else, which would silently rot the day the token changes. */
body.is-wall main {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 0;
  gap: 0;
}

/* The top bar goes, but the theme toggle stays: a wall display is the one place a
   viewer cannot reach a menu, and a dark wall in a bright room (or the reverse) is
   the first thing they will want to change. Keeping the real control rather than
   cloning it means it keeps its id, and the layout's existing toggle script binds
   to it untouched. */
body.is-wall .top-bar {
  position: fixed;
  top: 0;
  right: 0;
  left: auto;
  width: auto;
  height: auto;
  min-height: 0;
  padding: var(--cs-xs);
  background: none;
  border: none;
  box-shadow: none;
  z-index: 4;
}

body.is-wall .top-bar-lead,
body.is-wall .fs-brand-url,
body.is-wall .top-bar-trail > *:not(.theme-toggle) { display: none; }

body.is-wall .theme-toggle { opacity: .45; transition: opacity .2s ease; }
body.is-wall .theme-toggle:hover,
body.is-wall .theme-toggle:focus-visible { opacity: 1; }

/* The toggle keeps the site tooltip, only repositioned.
   It ships as data-tooltip-pos="bottom", which is right for a top bar but not for a
   control parked in a screen corner: the bubble is centred on the button, so at top
   right it runs past the right edge, and in kiosk, where the button sits at the bottom
   left, it renders below the bottom of the screen and is simply never seen. Same bubble,
   same arrow, same timing, different anchor. */

/* Browser wall mode, button top right: still below, but anchored to the button's right
   edge instead of centred, so the bubble grows inward. The arrow stays centred because
   it points at the button, not at the bubble. */
body.is-wall .theme-toggle::before {
  left: auto;
  right: 0;
  transform: translateY(-4px);
}

body.is-wall .theme-toggle:hover::before,
body.is-wall .theme-toggle:focus-visible::before { transform: translateY(0); }

/* Kiosk, button bottom left: to the right of the button, which is the site's existing
   data-tooltip-pos="right" treatment reproduced here, since the attribute is set in the
   shared layout and cannot vary per mode. */
body.is-kiosk .theme-toggle::before {
  top: 50%;
  bottom: auto;
  left: calc(100% + 8px);
  right: auto;
  transform: translateY(-50%) translateX(-4px);
}

body.is-kiosk .theme-toggle::after {
  top: 50%;
  bottom: auto;
  left: calc(100% + 2px);
  transform: translateY(-50%) translateX(-4px);
  border: 5px solid transparent;
  border-right-color: #2a2d36;
  border-left: none;
}

body.is-kiosk .theme-toggle:hover::before,
body.is-kiosk .theme-toggle:hover::after,
body.is-kiosk .theme-toggle:focus-visible::before,
body.is-kiosk .theme-toggle:focus-visible::after { transform: translateY(-50%) translateX(0); }

/* Kiosk only: bottom left instead of top right.
   In a browser the viewport starts below the browser chrome, so top right is nothing
   but page. In a packaged app the page runs to the top edge and that corner is where
   Windows draws the close button, which the toggle was sitting on top of.
   Bottom left is the corner nothing else claims: macOS keeps its controls top left,
   the signature is centred, and the legend that used to sit here is gone. */
body.is-kiosk .top-bar {
  top: auto;
  bottom: 0;
  right: auto;
  left: 0;
}

/* The wall takes whatever the header leaves, and the grid stretches inside it,
   so twelve cards divide the real estate instead of sitting in a fixed block. */
body.is-wall .mkc-wall {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* The section's normal bottom margin separates it from the prose that follows on the
     content page. On the wall there is no prose, only the signature, and the page already
     reserves a lane for that. Keeping the margin stacked a third gap under the cards and
     left a band of dead black between the last row and the mark. */
  margin-bottom: 0;
}

body.is-wall .mkc-grid {
  flex: 1;
  min-height: 0;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
}

/* Six across only once the width can carry it. Below that the aspect decides:
   a portrait panel gets a tall 3x4, which is the shape a phone or a rotated
   monitor actually is. */
@media (max-width: 1200px) {
  body.is-wall .mkc-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-template-rows: repeat(3, minmax(0, 1fr));
  }
}

@media (orientation: portrait) {
  body.is-wall .mkc-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(4, minmax(0, 1fr));
  }
}

/* Dials scale with the viewport rather than sitting at a fixed rem: the whole
   point of a wall is being readable from across a room, and vmin tracks the
   smaller axis so a wide TV does not overflow vertically. */
body.is-wall .mkc-page { --mkc-dial: clamp(7rem, 18vmin, 20rem); }
body.is-wall .mkc-city { font-size: clamp(1.05rem, 2.5vmin, 2.2rem); }

/* The countdown is sized off the dial, not off the viewport, so the digits keep
   the same relationship to the ring at every screen size instead of drifting
   small inside a large circle.

   The multiplier is set by the widest string the dial ever shows, HH:MM:SS, at
   eight characters: Sydney counts 12:35:03 to its next open and Mumbai 16:20:03.
   Eight tabular figures run about 4.6em, and the usable width inside the ring is
   roughly three quarters of the dial, which caps this at .159. Anything larger
   clips the leading and trailing digits, which is what .215 did. */
body.is-wall .mkc-count {
  font-size: calc(var(--mkc-dial) * .15);
  white-space: nowrap;
}

body.is-wall .mkc-offset,
body.is-wall .mkc-session,
body.is-wall .mkc-local,
body.is-wall .mkc-boundary { font-size: clamp(0.72rem, 1.45vmin, 1.15rem); }

body.is-wall .mkc-chip { font-size: clamp(0.68rem, 1.3vmin, 1rem); }

body.is-wall .mkc-card { gap: .25rem; justify-content: center; }

/* ── Wall contrast ──────────────────────────────────────────────────────────
   The glass is a white veil: a 5% white fill over three blurred colour blobs.
   At card size that reads as frost. Stretched to a sixth of a screen it reads
   as fog sitting on top of the numbers.

   So on the wall the fill inverts to the page's own background instead of to
   white, which darkens in dark mode and lightens in light mode from one token,
   and the sky is pulled back so it lights the gaps between cards rather than
   hazing their faces. Content then sits on a surface instead of inside one.  */

/* The sheen is restated here for the same reason it is restated on the live cards and in
   light mode: background is a shorthand, and these two rules outrank the base card, so
   naming only a fill silently drops the gradient layer. On the wall it is scaled up a
   little, because a card stretched to a sixth of a screen shows a gentle ramp over a much
   longer distance and the same values read as almost nothing. */
body.is-wall .mkc-card {
  /* Side rims, one per edge, phase-keyed like the top. Radial rather than another inset
     shadow: an inset from the left runs the full height of the card, and these are meant to
     bloom from the middle of each edge and fade out towards the corners, the way light
     catches the curve of a glass pane. Anchored at 0% 50% and 100% 50%, so the brightest
     point sits exactly at the vertical centre of each side.

     Layer order is top-down: both side rims sit over the top sheen, which sits over the
     fill. They overlap only in the corners, where both are already near zero. */
  background:
    radial-gradient(ellipse 32% 44% at 0% 50%,
      color-mix(in srgb, var(--mkc-phase) 12%, transparent), transparent 72%),
    radial-gradient(ellipse 32% 44% at 100% 50%,
      color-mix(in srgb, var(--mkc-phase) 12%, transparent), transparent 72%),
    linear-gradient(180deg,
      rgba(255, 255, 255, .10) 0%,
      rgba(255, 255, 255, .035) 34%,
      rgba(255, 255, 255, 0)    62%),
    color-mix(in srgb, var(--md-background) 62%, transparent);
  border-color: color-mix(in srgb, var(--mkc-phase) 48%, transparent);
  /* The top rim, in three parts: a crisp bright hairline on the edge itself, a short bloom
     falling from it into the card, and the existing drop shadow underneath.

     The bloom is keyed to --mkc-phase rather than to white, so it costs nothing to have a
     trading card glow mint or amber along its top while a closed one stays grey: --mkc-shut
     is already the phase value for closed, so one declaration covers all twelve states.

     The negative spread on the bloom is what keeps it a rim rather than an inner glow: it
     pulls the shadow in from every edge, and the 6px y-offset pushes what is left down from
     the top only. */
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--md-on-surface) 42%, transparent),
    inset 0 7px 16px -7px color-mix(in srgb, var(--mkc-phase) 55%, transparent),
    0 10px 32px rgba(0, 0, 0, .40);
}

/* The light-mode card rule carries one more class than body.is-wall .mkc-card, so it wins on
   the wall too and the rim above never paints. Restated at higher specificity, with a white
   hairline instead of an on-surface one: on-surface is near-black in light mode, which would
   have drawn a shadow along the top edge rather than a highlight. */
html[data-theme="light"] body:not(.is-dashboard).is-wall .mkc-card {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    inset 0 7px 16px -7px color-mix(in srgb, var(--mkc-phase) 42%, transparent),
    0 8px 24px rgba(0, 0, 0, .12);
  /* background needs restating for the same specificity reason as the shadow above. The
     rims run a little stronger here: they sit on a near-white pane, where the dark theme's
     tint of a pale phase colour is close to invisible. */
  background:
    radial-gradient(ellipse 32% 44% at 0% 50%,
      color-mix(in srgb, var(--mkc-phase) 17%, transparent), transparent 72%),
    radial-gradient(ellipse 32% 44% at 100% 50%,
      color-mix(in srgb, var(--mkc-phase) 17%, transparent), transparent 72%),
    linear-gradient(180deg,
      rgba(255, 255, 255, .92) 0%,
      rgba(255, 255, 255, .30) 34%,
      rgba(255, 255, 255, 0)   62%),
    rgba(255, 255, 255, .62);
}

/* Both rims restated, a few points hotter. A trading card is the one being read from across
   the room, and its phase colour is a live green or amber rather than the closed grey, so it
   can carry more without turning into decoration. */
body.is-wall .mkc-card.is-open,
body.is-wall .mkc-card.is-auction,
body.is-wall .mkc-card.is-power,
body.is-wall .mkc-card.is-lunch {
  background:
    radial-gradient(ellipse 32% 44% at 0% 50%,
      color-mix(in srgb, var(--mkc-phase) 15%, transparent), transparent 72%),
    radial-gradient(ellipse 32% 44% at 100% 50%,
      color-mix(in srgb, var(--mkc-phase) 15%, transparent), transparent 72%),
    linear-gradient(180deg,
      rgba(255, 255, 255, .13) 0%,
      rgba(255, 255, 255, .045) 34%,
      rgba(255, 255, 255, 0)    62%),
    color-mix(in srgb, var(--md-background) 52%, transparent);
  border-color: color-mix(in srgb, var(--mkc-phase) 88%, transparent);
}

/* The side edges as a lit line rather than a flat border: ordinary at top and bottom, full
   phase colour across the middle. border-color cannot vary along an edge and border-image
   would drop the 1.625rem radius, so the line is drawn as two thin vertical strips on a
   pseudo-element instead.

   z-index: -1 is doing real work. .mkc-card is position: relative with z-index: 1, so it
   opens a stacking context; a positioned pseudo-element at auto would paint above the card's
   own text, since the city name and countdown are static children. Negative z-index puts the
   strips above the card's background and below its content, which is exactly where an edge
   light belongs.

   The strips are straight while the corners are round, so both gradients are transparent
   through the first and last 12%: the overshoot past the curve has no colour in it to show.
   ::before is free here, ::after is spoken for by the New York marker. */
body.is-wall .mkc-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  border-radius: inherit;
  background-image:
    linear-gradient(to bottom,
      transparent 12%,
      color-mix(in srgb, var(--mkc-phase) 85%, transparent) 50%,
      transparent 88%),
    linear-gradient(to bottom,
      transparent 12%,
      color-mix(in srgb, var(--mkc-phase) 85%, transparent) 50%,
      transparent 88%);
  background-size: 1.5px 100%, 1.5px 100%;
  background-position: left center, right center;
  background-repeat: no-repeat;
}

/* A trading card's edge line goes to full strength. Closed markets keep the muted version
   above, so the wall still separates live from shut at a glance. */
body.is-wall .mkc-card.is-open::before,
body.is-wall .mkc-card.is-auction::before,
body.is-wall .mkc-card.is-power::before,
body.is-wall .mkc-card.is-lunch::before {
  background-image:
    linear-gradient(to bottom,
      transparent 10%,
      var(--mkc-phase) 50%,
      transparent 90%),
    linear-gradient(to bottom,
      transparent 10%,
      var(--mkc-phase) 50%,
      transparent 90%);
  background-size: 2px 100%, 2px 100%;
}

body.is-wall .mkc-blob { opacity: .26; }

/* Kiosk cards let more through than wall cards do, because in kiosk there is something
   behind them worth seeing: the faceted field. 62% of the page background at rest drops
   to 44%, and the live ones from 52% to 36%, so a facet edge running under a card stays
   readable through it and the glass picks up the fold instead of masking it.

   Safe to go this far only because the phase chip is opaque now. It mixes into a surface
   token rather than washing over whatever is behind it, so its measured contrast does not
   move when the card thins. The dials and the city names sit on near-background either
   way, since the facets top out around 5% of on-surface. */
body.is-kiosk .mkc-card {
  background: color-mix(in srgb, var(--md-background) 44%, transparent);
}

body.is-kiosk .mkc-card.is-open,
body.is-kiosk .mkc-card.is-auction,
body.is-kiosk .mkc-card.is-power,
body.is-kiosk .mkc-card.is-lunch {
  background: color-mix(in srgb, var(--md-background) 36%, transparent);
}

/* Text lifts in kiosk. The muted tokens are calibrated for a dense card at arm's length,
   and across a room --md-outline on a thinned card is close to unreadable. Everything
   moves onto on-surface and keeps its hierarchy through alpha instead of through hue, so
   light mode inverts with it rather than needing a second set of colours. */
body.is-kiosk .mkc-session,
body.is-kiosk .mkc-local,
body.is-kiosk .mkc-boundary,
body.is-kiosk .mkc-offset {
  color: color-mix(in srgb, var(--md-on-surface) 80%, transparent);
}

/* The moon comes up with it. At .45 it read as disabled rather than quiet, and it is the
   only control on the screen, so it has to be findable without being hunted for. */
body.is-kiosk .theme-toggle {
  opacity: .9;
  color: var(--md-on-surface);
}

/* Saturate rather than blur harder: the point is to make what shows through the
   glass more vivid, not to smear more of it across the card. */
@media (min-width: 641px) {
  body.is-wall .mkc-card {
    -webkit-backdrop-filter: blur(22px) saturate(190%);
    backdrop-filter: blur(22px) saturate(190%);
  }
}

/* The two things read from across a room get full contrast, not the muted
   variant that suits a dense card at arm's length. */
body.is-wall .mkc-city { color: var(--md-on-surface); }
body.is-wall .mkc-card.is-closed .mkc-count,
body.is-wall .mkc-card.is-holiday .mkc-count { color: var(--md-on-surface-var); }

/* Kiosk lifts them again, and must sit after the wall rule above: same specificity, so
   source order is the only thing deciding it. Closed markets still read a step back from
   the trading ones, but a legible step rather than the dimmest token on the page. */
body.is-kiosk .mkc-card.is-closed  .mkc-count,
body.is-kiosk .mkc-card.is-holiday .mkc-count {
  color: color-mix(in srgb, var(--md-on-surface) 88%, transparent);
}

body.is-wall .mkc-head { margin-bottom: var(--cs-xs); }

/* The full session, on every card at every size. It was wall-only on the theory that a
   normal card is too dense for it, but the card has room to spare and the line answers the
   other half of the page's question: not just how long until the bell, but what the hours
   actually are. It also carries the exchange's name, which is the one thing a card had no
   way of stating outside wall mode. */
.mkc-session {
  display: block;
  margin: 0;
  font-size: var(--ct-xs);
  line-height: 1.35;
  color: var(--md-on-surface-var);
  font-family: var(--font-mono);
  letter-spacing: .02em;
}

/* The venue is the exchange's name, so it carries the weight while the hours beside it stay
   regular. 700 rather than 500: this is a mono face at a small size, where 500 is close to
   indistinguishable from 400, and the code is meant to be findable at a glance across a
   room. Lifted to full on-surface too, since weight alone on a muted colour still reads as
   secondary. */
.mkc-venue {
  font-weight: 700;
  color: var(--md-on-surface);
}

/* ── The signature ──────────────────────────────────────────────────────────
   A wall display is seen by people who did not open it, so it has to say where
   it came from. Bottom-right, out of the grid's way, breathing slowly so it
   reads as alive rather than as a static watermark burned into a panel.     ---- */

/* ── Kiosk backdrop ─────────────────────────────────────────────────────────
   Not a flat field. A charcoal-to-near-black gradient for depth, with a fine
   tessellated wireframe over it, which is what lets the cards read as elevated
   surfaces catching light rather than as rectangles drawn on black.

   Kiosk only, and behind everything: z-index 0 against the cards' 1, so the mesh
   never competes with a dial. Built from tokens, so light mode gets dark lines on
   a pale field instead of white lines vanishing into white.                  ---- */

.mkc-facets { display: none; }

body.is-kiosk .mkc-facets {
  display: block;
  position: fixed;
  inset: 0;
  /* -1, not 0. A positioned element at z-index 0 paints above ordinary in-flow
     content, so this gradient covered the answer sentence and the header: the cards
     survived only because they carry z-index 1 of their own. Negative puts it behind
     the text while still sitting above the page canvas. */
  z-index: -1;
  pointer-events: none;
  /* The gradient field: lifted at the top where the header sits, settling to the
     page background below, so the wall has a horizon rather than a wash. */
  background:
    radial-gradient(120% 75% at 50% 0%,
      color-mix(in srgb, var(--md-surf-2) 60%, transparent) 0%,
      transparent 55%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--md-surf-2) 40%, var(--md-background)) 0%,
      var(--md-background) 60%);
}

/* The facets. Each polygon carries its own opacity in the markup, so this only sets the
   hue and an overall ceiling. Kept low on purpose: the facets are meant to be felt as
   depth behind the glass, not read as shapes competing with the dials. */
body.is-kiosk .mkc-facets svg {
  display: block;
  width: 100%;
  height: 100%;
  color: var(--md-on-surface);
  /* The one dial for the whole effect. Each facet carries its own opacity in the markup
     and this scales all of them together, so strength is tuned here rather than across
     twenty-four polygons. */
  opacity: 1;
}

.mkc-signature { display: none; }

body.is-wall .mkc-signature {
  display: block;
  position: fixed;
  /* Centred on the wall rather than tucked into the right corner: on a display seen
     from across a room the mark is the only thing that says where this came from, and
     the corner is the first thing a viewer's eye skips. The breathe animation is
     opacity only, so the centring transform is never fighting it. */
  left: 50%;
  transform: translateX(-50%);
  bottom: var(--cs-xs);
  z-index: 3;
  font-family: var(--font-mono);
  font-size: clamp(1.35rem, 3.1vmin, 3rem);
  font-weight: 700;
  letter-spacing: .12em;
  /* Brand colour, through the token rather than the hex, so it stays the cyan
     #4DD0E1 in dark and drops to #006780 in light without a second rule. The
     halo is mixed from the same token for the same reason. */
  color: var(--md-primary);
  text-shadow: 0 0 clamp(8px, 1.4vmin, 18px) color-mix(in srgb, var(--md-primary) 35%, transparent);
  opacity: .8;
  animation: mkc-sig-breathe 6s ease-in-out infinite;
  /* No underline: .legal-page a carries the site's link styling, and a rule under a
     wordmark reads as a typo from across a room rather than as an affordance. */
  text-decoration: none;
}

/* Hover and keyboard focus settle the mark at full strength. The animation has to be
   dropped rather than overridden: a running animation beats a plain opacity
   declaration, so setting opacity alone would do nothing here. */
body.is-wall .mkc-signature:hover,
body.is-wall .mkc-signature:focus-visible {
  animation: none;
  opacity: 1;
}

body.is-wall .mkc-signature:focus-visible {
  outline: 2px solid var(--md-primary);
  outline-offset: .35rem;
  border-radius: .35rem;
}

/* A narrower range than a plain fade: the mark is brand now, so it should stay
   legible at the bottom of the breath rather than dissolving. */
@keyframes mkc-sig-breathe {
  0%, 100% { opacity: .6; }
  50%      { opacity: .95; }
}

/* ── The toggle ─────────────────────────────────────────────────────────────
   Hidden until the script proves it can run: a button that does nothing is
   worse than no button, and this one is useless without JS.                ---- */

.mkc-wall-btn {
  display: none;
  align-items: center;
  gap: .4rem;
  padding: .4rem .85rem;
  border: 1px solid var(--md-outline-var);
  border-radius: var(--shape-chip);
  background: color-mix(in srgb, var(--md-on-surface) 6%, transparent);
  color: var(--md-on-surface-var);
  font-family: inherit;
  font-size: var(--ct-sm);
  cursor: pointer;
  transition: background .18s ease, color .18s ease;
}

.mkc-page.is-wall-ready .mkc-wall-btn { display: inline-flex; }

.mkc-wall-btn:hover {
  color: var(--md-on-surface);
  background: color-mix(in srgb, var(--md-on-surface) 12%, transparent);
}

.mkc-wall-btn:focus-visible {
  outline: 2px solid var(--md-primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  body.is-wall .mkc-signature { animation: none; opacity: .85; }
}
