/* Public-site chrome, redesign 2026 R1b ("Kinetic editorial", DESIGN.md).
 *
 * The header, footer, WhatsApp button, skip link and the two button styles
 * every public page shares. Loaded by the synced head region
 * (site/partials/head.html) AFTER each page's own stylesheets, on every
 * public page and every blog page, so it is the one definition of these
 * pieces. Colours, type, radii, spacing and motion come from
 * /shell/tokens.css only (--hm-*); nothing here invents a value.
 *
 * The header's DOM contract is unchanged on purpose: #site-head,
 * #site-nav, #nav-toggle, .is-scrolled and .is-open are what five existing
 * scripts (script.js, nav.js, calculators.js, the numerology calculator's
 * script and the blog's) already toggle. chrome.js adds only what is new:
 * the once-per-session logo draw and the compact phone bar.
 *
 * Motion: transform and opacity only, plus stroke-dashoffset for the logo
 * draw (DESIGN.md's one named exception). Never `transition: all`. */

/* ---------- style.css's variables, pointed at the 2026 tokens (R1c) ----------
   style.css is still the base sheet for About, the calculators, pricing,
   the legal set, methodology and the numerology calculator. Rather than
   rewrite 958 lines that every one of those pages depends on, its own
   variables are repointed at the --hm-* tokens here, in the sheet that
   loads LAST on every public page and every blog page. Each of those
   pages therefore takes the new palette, type, radii and page width
   without a second copy of any component rule.

   R1b did exactly this for the homepage alone, in home.css under
   body.home; this is that block promoted to the whole public site, which
   is what home.css's header said R1c would do. It is on :root rather
   than body so that rules targeting html pick it up too.

   The theme switch comes free: style.css was dark-only, while tokens.css
   redefines every --hm-* for light, so the pages below now follow the
   reader's Light | Dark choice like the homepage does. */
:root {
  --color-base: var(--hm-bg);
  --color-card: var(--hm-surface);
  --color-surface-2: var(--hm-surface-2);
  --color-accent-soft: var(--hm-accent-ink);
  --color-line-strong: var(--hm-line-strong);
  --color-ink-soft: var(--hm-ink-2);
  --color-ink: var(--hm-ink);
  --color-accent: var(--hm-accent);
  --color-white: var(--hm-ink);
  --font-body: var(--hm-font-sans);
  --font-display: var(--hm-font-display);
  --font-mono: var(--hm-font-mono);
  --radius-cards: var(--hm-r-3);
  --radius-cards-inner: var(--hm-r-2);
  --radius-inputs: var(--hm-r-2);
  --radius-buttons: var(--hm-r-pill);
  --radius-default: var(--hm-r-1);
  --page-max-width: var(--hm-page-max);
}

/* ---------- Page base the chrome depends on ---------- */
body {
  font-family: var(--hm-font-sans);
  background: var(--hm-bg);
  color: var(--hm-ink);
  -webkit-font-smoothing: antialiased;
}

/* Display face and the 2026 scale on every public page's headings. The
   text itself, and its order, is untouched — R1c changes how the page
   looks, never what a crawler reads. */
h1, h2, h3 {
  font-family: var(--hm-font-display);
  color: var(--hm-ink);
  text-wrap: balance;
}
h1 {
  font-weight: var(--hm-w-display);
  line-height: var(--hm-lh-display);
  letter-spacing: var(--hm-track-display);
  font-variation-settings: "opsz" 96;
}
h2 {
  font-weight: var(--hm-w-h2);
  line-height: var(--hm-lh-h2);
  letter-spacing: var(--hm-track-h2);
  font-variation-settings: "opsz" 72;
}
h3 {
  font-weight: var(--hm-w-h3);
  line-height: var(--hm-lh-h3);
  letter-spacing: var(--hm-track-h3);
}
:lang(zh) h1, :lang(zh) h2, :lang(zh) h3 { letter-spacing: 0; }
p { text-wrap: pretty; }
:focus-visible {
  outline: var(--hm-focus-width, 2px) solid var(--hm-accent-ink);
  outline-offset: var(--hm-focus-offset, 2px);
  border-radius: var(--hm-r-1);
}

.skip-link {
  position: fixed;
  top: 12px;
  left: 16px;
  z-index: var(--hm-z-toast);
  background: var(--hm-accent);
  color: var(--hm-on-accent);
  font-weight: 600;
  padding: 12px 20px;
  border-radius: var(--hm-r-pill);
  transform: translateY(-160%);
  transition: transform 240ms cubic-bezier(.2, .8, .2, 1);
}
.skip-link:focus { transform: none; text-decoration: none; }

/* Screen-reader-only text (the hero demo's plain-text summary, icon-only
   controls). Kept in the accessibility tree, off the visual one. */
.hm-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Buttons ----------
 * Crimson is the only button colour, with a DARK label: white on #ff3c4a
 * is 3.50:1 and failed AA on the pre-2026 CTA; --hm-on-accent is 5.66:1,
 * and hover LIGHTENS the fill, which raises it further. */
.btn-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--hm-hit, 44px);
  padding: 0 20px;
  border: 0;
  border-radius: var(--hm-r-pill);
  background: var(--hm-accent);
  color: var(--hm-on-accent);
  font: 600 15px/1 var(--hm-font-sans);
  letter-spacing: 0;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease, transform 120ms cubic-bezier(.2, .8, .2, 1);
}
.btn-cta:hover { background: var(--hm-accent-hover); color: var(--hm-on-accent); text-decoration: none; }
.btn-cta:active { background: var(--hm-accent-press); transform: scale(.98); }
.btn-cta:disabled { opacity: .55; cursor: not-allowed; transform: none; }
.btn-cta-lg { min-height: 52px; padding: 0 28px; font-size: 16px; }

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--hm-hit, 44px);
  padding: 0 20px;
  border: 1px solid var(--hm-line-field);
  border-radius: var(--hm-r-pill);
  background: transparent;
  color: var(--hm-ink);
  font: 500 15px/1 var(--hm-font-sans);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease, transform 120ms cubic-bezier(.2, .8, .2, 1);
}
.btn-ghost:hover { background: var(--hm-surface-2); border-color: var(--hm-ink-3); text-decoration: none; }
.btn-ghost:active { transform: scale(.98); }

/* ---------- Header ---------- */
.site-head {
  position: sticky;
  top: 0;
  z-index: var(--hm-z-header);
  height: 72px;
  padding: 0 var(--hm-gutter);
  padding-top: env(safe-area-inset-top);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color 240ms ease, border-color 240ms ease;
}
.site-head.is-scrolled {
  background: color-mix(in srgb, var(--hm-bg) 82%, transparent);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  backdrop-filter: saturate(140%) blur(14px);
  border-bottom-color: var(--hm-line);
}
.site-head-inner {
  position: relative;
  max-width: var(--hm-page-max);
  height: 100%;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  min-height: var(--hm-hit, 44px);
  color: var(--hm-ink);
  text-decoration: none;
  flex-shrink: 0;
}
.wordmark:hover { text-decoration: none; }
.hm-logo { display: block; width: auto; height: 28px; overflow: visible; }
.wordmark-text {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The logo draws once per browser session (chrome.js sets
   html.hm-logo-draw on the first page of a visit, before first paint of
   the header, and never again that session). Static in every other case,
   including reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  html.hm-logo-draw .hm-logo .d { animation: hm-logo-fade 240ms ease-out both; }
  html.hm-logo-draw .hm-logo .p { stroke-dasharray: 1; animation: hm-logo-draw 420ms cubic-bezier(.65, 0, .35, 1) 180ms both; }
  html.hm-logo-draw .hm-logo .l { transform-box: fill-box; transform-origin: center; animation: hm-logo-pop 360ms cubic-bezier(.34, 1.56, .64, 1) both; animation-delay: calc(120ms + var(--i) * 80ms); }
  html.hm-logo-draw .hm-logo .w { stroke-dasharray: 1; animation: hm-logo-draw 380ms cubic-bezier(.65, 0, .35, 1) both; animation-delay: calc(160ms + var(--i) * 14ms); }
}
@keyframes hm-logo-fade { from { opacity: 0; } }
@keyframes hm-logo-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes hm-logo-pop { from { transform: scale(.3); opacity: .3; } }

.site-nav-inner { display: flex; align-items: center; gap: 4px; }
.site-nav-inner a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 14px;
  border-radius: var(--hm-r-pill);
  color: var(--hm-ink-2);
  font: 500 15px/1 var(--hm-font-sans);
  white-space: nowrap;
  text-decoration: none;
  transition: color 120ms ease, background-color 120ms ease;
}
.site-nav-inner a:hover { color: var(--hm-ink); background: var(--hm-surface-2); text-decoration: none; }
.site-nav-inner a.is-active { color: var(--hm-ink); }
.site-nav-inner a.is-active::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 4px;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--hm-accent);
}
.site-nav-inner .site-nav-signin,
.site-nav-inner .site-nav-cta { display: none; }

.site-head-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.sign-in-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--hm-hit, 44px);
  padding: 0 12px;
  color: var(--hm-ink-2);
  font: 500 15px/1 var(--hm-font-sans);
  text-decoration: none;
  transition: color 120ms ease;
}
.sign-in-link:hover { color: var(--hm-ink); text-decoration: underline; text-underline-offset: 4px; }

.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 12px;
  border: 1px solid var(--hm-line-field);
  border-radius: var(--hm-r-pill);
  color: var(--hm-ink-2);
  font: 500 13px/1 var(--hm-font-sans);
  text-decoration: none;
  transition: color 120ms ease, border-color 120ms ease;
}
.lang-switch:hover { color: var(--hm-ink); border-color: var(--hm-ink-3); text-decoration: none; }
/* The visible 36px pill sits inside a 44px hit area. */
.lang-switch { position: relative; }
.lang-switch::before { content: ""; position: absolute; inset: -4px; }

.nav-toggle {
  display: none;
  position: relative;
  width: var(--hm-hit, 44px);
  height: var(--hm-hit, 44px);
  padding: 0;
  border: 1px solid var(--hm-line-field);
  border-radius: var(--hm-r-pill);
  background: transparent;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 4px;
}
.nav-toggle span {
  display: block;
  width: 16px;
  height: 1.5px;
  border-radius: 2px;
  background: var(--hm-ink);
  transition: transform 240ms cubic-bezier(.2, .8, .2, 1), opacity 120ms ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

/* Mid widths: the EN header carries five links plus sign-in, the switch
   and the CTA. Trim padding first, then drop "Modules" (still reachable
   from the page itself), before anything wraps. */
@media (min-width: 861px) and (max-width: 1180px) {
  .site-nav-inner a { padding: 0 10px; font-size: 14px; }
  .site-head-actions .btn-cta { padding: 0 16px; font-size: 14px; }
}
@media (min-width: 861px) and (max-width: 1040px) {
  html[lang="en"] .site-nav-inner a[href$="#modules"] { display: none; }
  .sign-in-link { padding: 0 8px; }
}

/* Phones and small tablets: a compact bar and a sheet menu. */
@media (max-width: 860px) {
  .site-head { height: 60px; }
  .hm-logo { height: 24px; transform-origin: left center; transition: transform 240ms cubic-bezier(.2, .8, .2, 1); }
  /* chrome.js adds .is-compact once the page has scrolled: the bar goes
     solid and the logo steps down, a transform only, so nothing below
     moves. */
  .site-head.is-compact { background: color-mix(in srgb, var(--hm-bg) 92%, transparent); border-bottom-color: var(--hm-line); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); }
  .site-head.is-compact .hm-logo { transform: scale(.88); }

  .site-head-actions .btn-cta,
  .site-head-actions .sign-in-link { display: none; }
  .nav-toggle { display: inline-flex; }

  .site-nav {
    position: absolute;
    top: 100%;
    left: 0;   /* the sticky .site-head is the containing block, and its */
    right: 0;  /* padding box is already the full viewport width */
    padding: 8px var(--hm-gutter) 16px;
    background: var(--hm-bg);
    border-bottom: 1px solid var(--hm-line-strong);
    box-shadow: var(--hm-shadow-float);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: opacity 240ms cubic-bezier(.2, .8, .2, 1), transform 240ms cubic-bezier(.2, .8, .2, 1), visibility 0s linear 240ms;
  }
  .site-nav.is-open {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity 240ms cubic-bezier(.2, .8, .2, 1), transform 240ms cubic-bezier(.2, .8, .2, 1), visibility 0s;
  }
  .site-head-inner { position: static; }
  .site-head { position: sticky; }
  .site-nav-inner { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav-inner a {
    min-height: 52px;
    padding: 0 4px;
    border-radius: 0;
    border-bottom: 1px solid var(--hm-line);
    font-size: 17px;
    color: var(--hm-ink);
  }
  .site-nav-inner a:hover { background: transparent; color: var(--hm-accent-ink); }
  .site-nav-inner a.is-active::after { left: auto; right: 8px; bottom: 50%; margin: 0 0 -2px; }
  .site-nav-inner .site-nav-signin { display: inline-flex; }
  .site-nav-inner .site-nav-cta {
    display: inline-flex;
    justify-content: center;
    margin-top: 16px;
    min-height: 52px;
    border: 0;
    border-radius: var(--hm-r-pill);
    background: var(--hm-accent);
    color: var(--hm-on-accent);
    font-weight: 600;
  }
  .site-nav-inner .site-nav-cta:hover { background: var(--hm-accent-hover); color: var(--hm-on-accent); }
}

/* ---------- Footer ---------- */
.site-foot {
  position: relative;
  z-index: 1;
  padding: 40px var(--hm-gutter) calc(40px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--hm-line);
  color: var(--hm-ink-2);
  font: 400 14px/1.5 var(--hm-font-sans);
}
.site-foot-inner {
  max-width: var(--hm-page-max);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 32px;
}
.foot-brand { display: inline-flex; align-items: center; gap: 12px; margin: 0; }
.hm-mark { flex-shrink: 0; }
.foot-legal { display: flex; flex-wrap: wrap; gap: 0 4px; margin: 0; }
.foot-legal a {
  display: inline-flex;
  align-items: center;
  min-height: var(--hm-hit, 44px);
  padding: 0 10px;
  color: var(--hm-ink-2);
  text-decoration: none;
  transition: color 120ms ease;
}
.foot-legal a:hover,
.foot-legal a:focus-visible { color: var(--hm-ink); text-decoration: underline; text-underline-offset: 4px; }
@media (max-width: 700px) {
  .site-foot-inner { flex-direction: column; align-items: flex-start; }
  .foot-legal { margin-left: -10px; }
  /* Room for the WhatsApp button (and the homepage's sticky CTA) to land
     on at the end of the page, so neither covers the last link. */
  .site-foot { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
}

/* ---------- WhatsApp ----------
 * A crimson outline on the dark surface rather than WhatsApp's own green,
 * so it stops being the one off-palette object on the page (brief section
 * 2). The glyph stays WhatsApp's, so it still reads as WhatsApp. No
 * heartbeat loop: motion here is feedback only. */
.whatsapp-fab {
  position: fixed;
  z-index: var(--hm-z-sticky);
  right: max(16px, calc((100vw - var(--hm-page-max)) / 2 - 72px));
  bottom: calc(16px + env(safe-area-inset-bottom));
  width: 52px;
  height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1.5px solid var(--hm-accent);
  background: var(--hm-surface);
  color: var(--hm-accent-ink);
  box-shadow: var(--hm-shadow-float);
  transition: transform 240ms cubic-bezier(.2, .8, .2, 1), opacity 240ms ease, background-color 120ms ease;
}
.whatsapp-fab:hover { background: var(--hm-surface-2); transform: translateY(-2px); text-decoration: none; }
.whatsapp-fab:active { transform: scale(.96); }
.whatsapp-fab-icon { width: 26px; height: 26px; }
/* script.js tucks it away while the homepage's request form is on screen. */
.whatsapp-fab.is-tucked { transform: translateY(140%); opacity: 0; pointer-events: none; }
@media (min-width: 1360px) {
  .whatsapp-fab { right: calc((100vw - var(--hm-page-max)) / 2 - 76px); }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .skip-link,
  .btn-cta,
  .btn-ghost,
  .site-head,
  .site-nav,
  .site-nav.is-open,
  .nav-toggle span,
  .hm-logo,
  .whatsapp-fab { transition: opacity 150ms linear; }
  .btn-cta:active,
  .btn-ghost:active,
  .whatsapp-fab:hover,
  .whatsapp-fab:active { transform: none; }
}
