/* =========================================================
   zg-ui.css — a small shared UI library. Companion: zg-ui.js (window.ZgUI).

   This is the start of one component library for every product we ship:
   The Zion Gathering first, then SEER, Oraqel Code and Identity Code. A
   product re-themes the whole set by redefining the --zg-* tokens in the
   first two blocks below; no component reads anything else. Zion Gathering
   binds them to its own tokens: the public ones from styles.css, and the
   --pv-* planner tokens inside body.planner-page, so the planner's dark
   theme follows with no extra rules.

   Two motion moods. Public pages are calm: gentle fades and lifts, nothing
   that startles. Planner pages (body.planner-page) are richer: springier
   easing and the gold burst. Nothing flashes or shakes anywhere. Under
   prefers-reduced-motion every animation here is replaced by its finished,
   still state.

   Text floor: nothing readable in this file is under 17px.

   Sections: 1 glow loader · 2 skeletons · 3 toast · 4 nudge · 5 halo button · 6 checks and burst ·
   7 stepper · 8 deck controls · 9 orbit deck · 10 stagger deck (with autoplay, tilt and glow) ·
   11 decision card · 12 fold and enter · 13 tick · 14 lamp switch · 15 site menus (ZgUI.siteNav) ·
   16 sheen and fill buttons · 17 announcement bar (ZgUI.bar) · 18 reveal on scroll (ZgUI.reveal) ·
   19 count-up (ZgUI.countUp) · 20 deck pause button.
   ========================================================= */

/* ---------------------------------------------------------------- tokens: public */
:root {
  --zg-accent: var(--gold);
  --zg-accent-bright: var(--gold-bright);
  --zg-accent-ink: var(--gold);
  --zg-surface: var(--parchment);
  --zg-surface-deep: var(--parchment-deep);
  --zg-ink: var(--ink);
  --zg-muted: var(--ink-soft);
  --zg-line: var(--hair-deep);
  --zg-line-soft: var(--hair);
  --zg-card-line: var(--hair-deep);
  --zg-field-line: var(--ink-faint);
  --zg-focus: var(--burgundy);
  --zg-tone-success: var(--gold);
  --zg-tone-info: var(--burgundy-bright);
  --zg-tone-warn: var(--danger);
  --zg-font-body: var(--sans);
  --zg-font-display: var(--serif);
  --zg-title-size: 28px;
  --zg-title-weight: 500;
  --zg-radius: 14px;
  /* Shapes: cards and photos, the things inside them, and anything pill-shaped. */
  --zg-radius-card: var(--radius-card, 20px);
  --zg-radius-inner: var(--radius-inner, 14px);
  --zg-radius-pill: var(--radius-pill, 999px);
  --zg-shadow: 0 1px 2px rgb(32 31 27 / 6%), 0 8px 24px rgb(32 31 27 / 9%);
  --zg-skel: color-mix(in srgb, var(--zg-ink) 7%, var(--zg-surface));
  --zg-skel-sheen: color-mix(in srgb, var(--zg-surface) 70%, transparent);
  /* the featured card of a deck: dark, with light text and a thin gold rule */
  --zg-feature: var(--burgundy);
  --zg-feature-ink: var(--parchment);
  --zg-feature-accent: var(--gold-bright);

  /* motion */
  --zg-ease: cubic-bezier(.22, 1, .36, 1);
  --zg-ease-spring: var(--zg-ease);
  --zg-ease-glide: cubic-bezier(.22, .75, .2, 1);
  --zg-breath: cubic-bezier(.65, 0, .35, 1);
  --zg-glow-duration: 2.4s;
  --zg-halo-turn: 10s;
  --zg-halo-turn-hover: 6s;
  --zg-halo-width: 2px;
  --zg-check-size: 28px;
  --zg-step-circle: 32px;
  --zg-step-hit: 44px;

  /* sheen / fill buttons (section 15) */
  --zg-sheen: rgb(255 240 196 / 58%);
  --zg-sheen-ms: 700ms;
  --zg-fill: color-mix(in srgb, var(--zg-accent-bright) 30%, transparent);
  --zg-btn-lift: -1px;
  --zg-btn-press: 2px;
  --zg-btn-shadow: 0 1px 2px rgb(32 31 27 / 14%), 0 6px 14px rgb(32 31 27 / 14%);
  --zg-btn-shadow-hover: 0 2px 4px rgb(32 31 27 / 16%), 0 10px 20px rgb(32 31 27 / 18%);
  --zg-btn-shadow-press: inset 0 2px 4px rgb(32 31 27 / 24%), 0 0 1px rgb(32 31 27 / 20%);
  /* announcement bar (section 17) and site menus (section 16) */
  --zg-bar-bg: var(--zg-feature);
  --zg-bar-ink: var(--zg-feature-ink);
  --zg-bar-accent: var(--zg-feature-accent);
  --zg-nav-row: 56px;
}

/* ---------------------------------------------------------------- tokens: planner (admin) */
/* The --pv-* tokens only exist once planner-shell.js adds planner-v2 (after sign-in),
   so each one falls back to its public twin and a planner page that is still on the
   sign-in screen draws toasts and loaders in the public colours instead of nothing. */
body.planner-page {
  --zg-accent: var(--pv-gold, var(--gold));
  --zg-accent-bright: var(--gold-bright);
  --zg-accent-ink: var(--pv-gold-dark, var(--gold));
  --zg-surface: var(--pv-surface, var(--parchment));
  --zg-surface-deep: var(--pv-tint, var(--parchment-deep));
  --zg-ink: var(--pv-ink, var(--ink));
  --zg-muted: var(--pv-muted, var(--ink-soft));
  --zg-line: var(--pv-line, var(--hair-deep));
  --zg-line-soft: var(--pv-line, var(--hair));
  --zg-card-line: var(--pv-gold-light, var(--hair-deep));
  --zg-field-line: var(--pv-muted, var(--ink-faint));
  --zg-focus: var(--pv-gold-dark, var(--burgundy));
  --zg-tone-success: var(--pv-good, var(--gold));
  --zg-tone-info: var(--pv-c-manage, var(--burgundy-bright));
  --zg-tone-warn: var(--pv-c-quick, var(--danger));
  --zg-font-display: var(--sans);
  --zg-title-size: 22px;
  --zg-title-weight: 600;
  --zg-radius: var(--pv-radius-inset, 14px);
  --zg-shadow: var(--pv-shadow, 0 1px 2px rgb(32 31 27 / 6%), 0 8px 24px rgb(32 31 27 / 9%));
  --zg-feature: var(--pv-ink, var(--burgundy));
  --zg-feature-ink: var(--pv-surface, var(--parchment));
  --zg-feature-accent: var(--gold-bright);
  /* A var() inside a custom property is resolved where it is declared, so tokens
     built from other tokens are declared again here, below the planner's own. */
  --zg-skel: color-mix(in srgb, var(--zg-ink) 7%, var(--zg-surface));
  --zg-skel-sheen: color-mix(in srgb, var(--zg-surface) 70%, transparent);
  --zg-ease-spring: cubic-bezier(.34, 1.45, .64, 1);
  --zg-halo-turn: 7s;
  --zg-halo-turn-hover: 4s;
}
html[data-theme=dark] body.planner-page {
  --zg-skel-sheen: color-mix(in srgb, var(--zg-ink) 9%, transparent);
}

/* ---------------------------------------------------------------- shared helpers */
.zg-sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ================================================================
   1. Breathing glow loader
   A small surface-coloured disc with a blurred accent halo behind it that
   breathes like a candle. <span class="zg-glow" aria-hidden="true"></span>
   ================================================================ */
.zg-glow {
  position: relative; display: inline-block; flex: none; width: 40px; height: 40px; vertical-align: middle;
}
.zg-glow::before,
.zg-glow::after {
  content: ""; position: absolute; left: 50%; top: 50%; border-radius: 50%;
}
.zg-glow::before {
  width: 26px; height: 26px; margin: -13px 0 0 -13px;
  background: var(--zg-accent-bright); filter: blur(9px); opacity: .45;
  animation: zg-breathe var(--zg-glow-duration) var(--zg-breath) infinite;
}
.zg-glow::after {
  width: 18px; height: 18px; margin: -9px 0 0 -9px;
  background: var(--zg-surface);
  box-shadow: 0 0 0 1px var(--zg-line), 0 1px 3px rgb(32 31 27 / 16%);
}
@keyframes zg-breathe {
  0%, 100% { transform: scale(1); opacity: .45; }
  50% { transform: scale(1.5); opacity: .8; }
}

.zg-loading {
  display: flex; align-items: center; gap: 12px; color: var(--zg-muted);
  font-family: var(--zg-font-body); font-size: 18px; line-height: 1.5;
}
.zg-loading-text { min-width: 0; }

/* The planner and a few public pages already print plain "Loading..." text in
   these places. Rather than edit every page, each one gains the same glow here,
   in CSS alone: the text, the markup and the behaviour are untouched. A
   pseudo-element cannot hold two layers, so the halo is the disc's own
   box-shadow breathing instead of a separate blurred disc; the look is the same.
   Most of the planner's messages carry .plan-loading; the ids are listed too so
   a message that loses that class keeps its glow. */
:where(.plan-loading, .planner-loading, .house-loading,
  #records-loading, #ops-loading, #lodging-loading, #checkin-loading, #it-loading, #fl-loading,
  #finance-loading, #plan-loading, #ops-teaching-loading, #ops-publish-loading,
  #command-loading, #memory-loading, #meeting-loading, #v-loading):not([hidden]) {
  display: flex; align-items: center; gap: 12px;
}
:where(#v-loading):not([hidden]) { justify-content: center; }
.event-card:where(#loading-card, #pay-loading) .event-card-label {
  display: flex; align-items: center; gap: 12px;
}
:where(.plan-loading, .planner-loading, .house-loading,
  #records-loading, #ops-loading, #lodging-loading, #checkin-loading, #it-loading, #fl-loading,
  #finance-loading, #plan-loading, #ops-teaching-loading, #ops-publish-loading,
  #command-loading, #memory-loading, #meeting-loading, #v-loading)::before,
.event-card:where(#loading-card, #pay-loading) .event-card-label::before {
  content: ""; flex: none; box-sizing: border-box; width: 18px; height: 18px; margin: 5px 4px; border-radius: 50%;
  background: var(--zg-surface); border: 1px solid var(--zg-line);
  box-shadow: 0 0 12px 3px var(--zg-accent-bright);
  box-shadow: 0 0 10px 2px color-mix(in srgb, var(--zg-accent-bright) 45%, transparent);
  animation: zg-breathe-lite var(--zg-glow-duration) var(--zg-breath) infinite;
}
@keyframes zg-breathe-lite {
  0%, 100% { box-shadow: 0 0 10px 2px color-mix(in srgb, var(--zg-accent-bright) 45%, transparent); }
  50% { box-shadow: 0 0 20px 9px color-mix(in srgb, var(--zg-accent-bright) 80%, transparent); }
}

/* ================================================================
   2. Skeletons
   Quiet placeholder blocks in a slightly deeper tone with a slow soft sheen.
   ZgUI.skeleton('rows' | 'cards' | 'decisions', count) writes the markup.
   ================================================================ */
.zg-skel {
  position: relative; display: block; overflow: hidden; border-radius: 8px; background: var(--zg-skel);
}
.zg-skel::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(100deg, transparent 0%, var(--zg-skel-sheen) 50%, transparent 100%);
  animation: zg-sheen 2.6s ease-in-out infinite;
}
@keyframes zg-sheen {
  0% { transform: translateX(-100%); }
  65%, 100% { transform: translateX(100%); }
}
.zg-skel-line { height: 16px; width: var(--zg-w, 100%); max-width: 100%; }
.zg-skel-short { --zg-w: 45%; }
.zg-skel-mid { --zg-w: 72%; }
.zg-skel-title { height: 24px; width: 55%; border-radius: 8px; }
.zg-skel-circle { flex: none; width: 48px; height: 48px; border-radius: 50%; }
.zg-skel-media { height: 120px; border-radius: 10px; }
.zg-skel-card {
  display: grid; gap: 14px; padding: 20px; box-sizing: border-box;
  border: 1px solid var(--zg-card-line); border-radius: var(--zg-radius); background: var(--zg-surface);
}
.zg-skeleton { display: grid; gap: 0; }
.zg-skeleton-cards { gap: 16px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); }
.zg-skeleton-decisions { gap: 16px; }
.zg-skel-row {
  display: flex; align-items: center; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--zg-line-soft);
}
.zg-skel-row:last-child { border-bottom: 0; }
.zg-skel-stack { flex: 1; min-width: 0; display: grid; gap: 10px; }

/* ================================================================
   3. Toast
   ZgUI.toast(message, { tone, action, timeout }). One polite live region,
   bottom-centre on phones, bottom-right on desktop, three at most.
   ================================================================ */
.zg-toasts {
  position: fixed; z-index: 400; left: 16px; right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px) + var(--zg-toast-lift, 0px));
  display: flex; flex-direction: column; gap: 10px; pointer-events: none;
}
/* Keep clear of the fixed things pages already put along the bottom edge. */
body:has(#abel-fab) { --zg-toast-lift: 76px; }
body:has(.reserve-bar) { --zg-toast-lift: 92px; }
@media (min-width: 720px) {
  .zg-toasts {
    left: auto; right: 24px; width: min(440px, calc(100vw - 48px));
    bottom: calc(24px + env(safe-area-inset-bottom, 0px) + var(--zg-toast-lift, 0px));
  }
}
.zg-toast {
  position: relative; display: flex; align-items: flex-start; gap: 6px; box-sizing: border-box;
  padding: 10px 6px 10px 26px; pointer-events: auto;
  background: var(--zg-surface); color: var(--zg-ink);
  border: 1px solid var(--zg-card-line); border-radius: var(--zg-radius); box-shadow: var(--zg-shadow);
  font-family: var(--zg-font-body); font-size: 18px; line-height: 1.5;
  animation: zg-toast-in 220ms var(--zg-ease-spring) both;
  transition: opacity 200ms ease;
}
.zg-toast::before {
  content: ""; position: absolute; left: 11px; top: 14px; bottom: 14px; width: 4px; border-radius: 4px;
  background: var(--zg-toast-tone, var(--zg-accent));
}
.zg-toast[data-tone=success] { --zg-toast-tone: var(--zg-tone-success); }
.zg-toast[data-tone=info] { --zg-toast-tone: var(--zg-tone-info); }
.zg-toast[data-tone=warn] { --zg-toast-tone: var(--zg-tone-warn); }
.zg-toast.is-leaving { opacity: 0; pointer-events: none; }
.zg-toast-body { flex: 1; min-width: 0; padding: 7px 0; display: flex; flex-direction: column; align-items: flex-start; }
.zg-toast-msg { overflow-wrap: anywhere; }
.zg-toast-action {
  display: inline-flex; align-items: center; min-height: 44px; margin: 0 0 -7px; padding: 0; border: 0; background: none;
  color: var(--zg-accent-ink); font: inherit; font-weight: 600; text-decoration: underline; text-underline-offset: 4px; cursor: pointer;
}
.zg-toast-close {
  flex: none; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 10px;
  background: transparent; color: var(--zg-muted); cursor: pointer;
  transition: background-color 160ms ease, color 160ms ease;
}
.zg-toast-close:hover { background: var(--zg-surface-deep); color: var(--zg-ink); }
.zg-toast-close svg { width: 18px; height: 18px; display: block; }
.zg-toast :focus-visible, .zg-nudge :focus-visible { outline: 3px solid var(--zg-focus); outline-offset: 2px; }
@keyframes zg-toast-in {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

/* ================================================================
   4. Nudge card — "what to do next". ZgUI.nudge({ eyebrow, title, text, action }).
   ================================================================ */
.zg-nudge {
  position: relative; overflow: hidden; box-sizing: border-box; padding: 22px 26px 24px 30px;
  background: var(--zg-surface); color: var(--zg-ink);
  border: 1px solid var(--zg-card-line); border-radius: var(--zg-radius); box-shadow: var(--zg-shadow);
  font-family: var(--zg-font-body); animation: zg-rise 600ms var(--zg-ease) both;
}
.zg-nudge::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--zg-accent);
}
.zg-nudge-eyebrow {
  margin: 0; font-size: 17px; font-weight: 600; line-height: 1.4; letter-spacing: .12em; text-transform: uppercase; color: var(--zg-accent-ink);
}
.zg-nudge-title {
  margin: 8px 0 0; font-family: var(--zg-font-display); font-size: var(--zg-title-size); font-weight: var(--zg-title-weight);
  line-height: 1.2; letter-spacing: 0; color: var(--zg-ink);
}
.zg-nudge-text { margin: 10px 0 0; max-width: 60ch; font-size: 18px; line-height: 1.6; color: var(--zg-muted); }
.zg-nudge-action { margin-top: 18px; }
@keyframes zg-rise {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* ================================================================
   5. Halo button
   A thin gold ring that turns slowly around a primary button. Add .zg-halo to
   an existing .btn-primary (or any link or button); use it on one button per
   view. The ring sits just outside the button's own edge and is cut to a
   hairline with a mask, so the button keeps its background, size, text and
   layout, and the ring shows whatever sits behind the button. The button's own
   hover lift and press (the site's .btn-primary rules) stay in charge; the lift
   and press below only reach a button that has none of its own.
   ================================================================ */
@property --zg-angle {
  syntax: "<angle>"; inherits: false; initial-value: 0deg;
}
:where(.zg-halo) { position: relative; }
.zg-halo::before {
  content: ""; position: absolute; inset: calc(var(--zg-halo-width) * -1); box-sizing: border-box;
  border: var(--zg-halo-width) solid transparent; border-radius: inherit; pointer-events: none;
  background: conic-gradient(from var(--zg-angle, 0deg),
    color-mix(in srgb, var(--zg-accent) 40%, transparent) 0deg,
    var(--zg-accent-bright) 70deg,
    var(--zg-accent) 120deg,
    color-mix(in srgb, var(--zg-accent) 40%, transparent) 200deg,
    color-mix(in srgb, var(--zg-accent) 40%, transparent) 360deg) border-box;
  /* A mask only reads its alpha, so the colour in these two layers is never drawn. */
  -webkit-mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: .8;
  animation: zg-halo-turn var(--zg-halo-turn) linear infinite;
  transition: opacity 240ms ease;
}
@keyframes zg-halo-turn {
  from { --zg-angle: 0deg; }
  to { --zg-angle: 360deg; }
}
:where(.zg-halo) { transition: transform 180ms var(--zg-ease-spring); }
:where(.zg-halo):hover { transform: translateY(-1px); }
:where(.zg-halo):active { transform: scale(.985); }
.zg-halo:hover::before, .zg-halo:focus-visible::before {
  opacity: 1; animation-duration: var(--zg-halo-turn-hover);
}
/* No registered custom properties (older Safari and Firefox): zg-ui.js adds this
   class, and the ring stays put instead of stepping once a turn. */
.zg-no-property .zg-halo::before { animation: none; }

/* ================================================================
   6. Checks
   (a) .zg-check — a native checkbox whose two bars form an X when empty and
       morph into a tick when checked. The input stays a real checkbox:
       keyboard, form submission and labels are untouched.
       <label class="zg-check"><input type="checkbox"><span class="zg-check-box" aria-hidden="true"></span><span>Label</span></label>
   (b) ZgUI.burst(el) — see zg-ui.js; its dots are styled below.
   ================================================================ */
.zg-check {
  position: relative; display: inline-flex; align-items: center; gap: 14px; min-height: 44px;
  font-family: var(--zg-font-body); font-size: 18px; line-height: 1.4; color: var(--zg-ink); cursor: pointer;
}
.zg-check input {
  position: absolute; left: 0; top: 50%; width: var(--zg-check-size); height: var(--zg-check-size); margin: calc(var(--zg-check-size) / -2) 0 0;
  opacity: 0; cursor: pointer;
}
.zg-check-box {
  --zg-s: calc(var(--zg-check-size) - 4px);
  --zg-morph: var(--zg-breath);
  position: relative; flex: none; box-sizing: border-box; width: var(--zg-check-size); height: var(--zg-check-size);
  border: 2px solid var(--zg-field-line); border-radius: 8px; background: var(--zg-surface);
  transition: background-color 300ms var(--zg-morph), border-color 300ms var(--zg-morph);
}
body.planner-page .zg-check-box { --zg-morph: var(--zg-ease-spring); }
.zg-check-box::before,
.zg-check-box::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: calc(var(--zg-s) * .62); height: 3px; margin: -1.5px 0 0 calc(var(--zg-s) * -.31);
  border-radius: 3px; background: color-mix(in srgb, var(--zg-muted) 60%, transparent);
  transition: transform 300ms var(--zg-morph), background-color 300ms var(--zg-morph);
}
.zg-check-box::before { transform: rotate(45deg); }
.zg-check-box::after { transform: rotate(-45deg); }
.zg-check input:checked + .zg-check-box {
  border-color: var(--zg-accent-ink); background: color-mix(in srgb, var(--zg-accent) 14%, var(--zg-surface));
}
.zg-check input:checked + .zg-check-box::before,
.zg-check input:checked + .zg-check-box::after { background: var(--zg-accent-ink); }
.zg-check input:checked + .zg-check-box::before {
  transform: translate(calc(var(--zg-s) * -.177), calc(var(--zg-s) * .083)) rotate(48deg) scaleX(.46);
}
.zg-check input:checked + .zg-check-box::after {
  transform: translate(calc(var(--zg-s) * .104), calc(var(--zg-s) * -.02)) rotate(-48deg) scaleX(.9);
}
.zg-check input:focus-visible + .zg-check-box { outline: 3px solid var(--zg-focus); outline-offset: 3px; }
.zg-check input:disabled + .zg-check-box, .zg-check input:disabled ~ span:last-child { opacity: .55; }
.zg-check input:disabled, .zg-check:has(input:disabled) { cursor: not-allowed; }

.zg-burst { position: fixed; z-index: 450; width: 0; height: 0; pointer-events: none; }
.zg-burst i {
  position: absolute; left: -4px; top: -4px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--zg-accent-bright); box-shadow: 0 0 8px var(--zg-accent-bright);
  animation: zg-burst-out 500ms var(--zg-ease) both;
}
@keyframes zg-burst-out {
  from { opacity: 1; transform: rotate(var(--zg-a)) translateX(4px) scale(1); }
  to { opacity: 0; transform: rotate(var(--zg-a)) translateX(30px) scale(.4); }
}

/* ================================================================
   7. Stepper — one form in a few calm steps. ZgUI.stepper(form, opts) in zg-ui.js.
   Markup it builds: a .zg-stepper header (numbered circles joined by connectors,
   or on a phone the circles and one "Step 2 of 4 · About you" line), then
   .zg-steps holding each .zg-step panel with its Back / Continue row. Only the
   current panel is shown; the others are [hidden] but their fields still submit.
   Public pages are calm: the step leaving fades and slips 16px, the step arriving
   comes in from 16px the other side, 260ms, and nothing animates height.
   ================================================================ */
.zg-stepper {
  margin: 28px 0 30px; scroll-margin-top: 112px;
  font-family: var(--zg-font-body); color: var(--zg-ink);
}
.zg-stepper-list { display: flex; align-items: flex-start; margin: 0; padding: 0; list-style: none; }
.zg-stepper-item {
  position: relative; display: flex; flex-direction: column; align-items: center; flex: 1 1 0; min-width: 0;
}
/* The connector reaches from the middle of the step before to the middle of this one. */
.zg-stepper-item + .zg-stepper-item::before,
.zg-stepper-item + .zg-stepper-item::after {
  content: ""; position: absolute; top: calc(var(--zg-step-hit) / 2 - 1px); left: -50%; width: 100%; height: 2px; border-radius: 2px;
}
.zg-stepper-item + .zg-stepper-item::before { background: var(--zg-line); }
.zg-stepper-item + .zg-stepper-item::after {
  background: var(--zg-accent); transform: scaleX(0); transform-origin: left center;
  transition: transform 400ms var(--zg-ease);
}
.zg-stepper-item[data-status=current]::after,
.zg-stepper-item[data-status=complete]::after { transform: scaleX(1); }

.zg-stepper-dot {
  position: relative; z-index: 1; display: grid; place-items: center; flex: none;
  width: var(--zg-step-hit); height: var(--zg-step-hit); margin: 0; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: inherit; font: inherit; cursor: default; -webkit-tap-highlight-color: transparent;
}
.zg-stepper-dot:not(:disabled) { cursor: pointer; }
.zg-stepper .zg-stepper-dot:focus-visible { outline: 3px solid var(--zg-focus); outline-offset: 0; }
.zg-stepper-circle {
  position: relative; display: grid; place-items: center; box-sizing: border-box;
  width: var(--zg-step-circle); height: var(--zg-step-circle);
  border: 2px solid var(--zg-field-line); border-radius: 50%; background: var(--zg-surface); color: var(--zg-muted);
  font-size: 17px; font-weight: 600; line-height: 1;
  transition: background-color 260ms var(--zg-ease), border-color 260ms var(--zg-ease), color 260ms var(--zg-ease), box-shadow 260ms var(--zg-ease);
}
.zg-stepper-num { transition: opacity 160ms ease; }
.zg-stepper-circle svg {
  position: absolute; width: 18px; height: 18px; opacity: 0; transform: scale(.6);
  transition: opacity 200ms ease, transform 260ms var(--zg-ease);
}
.zg-stepper-item[data-status=current] .zg-stepper-circle {
  border-color: var(--zg-accent); color: var(--zg-ink);
  background: color-mix(in srgb, var(--zg-accent) 16%, var(--zg-surface));
  box-shadow: 0 0 0 3px var(--zg-surface), 0 0 0 5px var(--zg-accent);
}
.zg-stepper-item[data-status=complete] .zg-stepper-circle {
  border-color: var(--zg-accent); background: var(--zg-accent); color: var(--zg-surface);
}
.zg-stepper-item[data-status=complete] .zg-stepper-num { opacity: 0; }
.zg-stepper-item[data-status=complete] .zg-stepper-circle svg { opacity: 1; transform: none; }
.zg-stepper-dot:not(:disabled):hover .zg-stepper-circle {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--zg-accent) 24%, transparent);
}
.zg-stepper-title {
  box-sizing: border-box; max-width: 100%; margin-top: 4px; padding: 0 6px; text-align: center;
  font-size: 17px; line-height: 1.3; color: var(--zg-muted); overflow-wrap: anywhere;
}
.zg-stepper-item[data-status=current] .zg-stepper-title { color: var(--zg-ink); font-weight: 600; }
.zg-stepper-now {
  display: none; margin: 8px 0 0; text-align: center; font-size: 18px; line-height: 1.4; font-weight: 600; color: var(--zg-ink);
}
@media (max-width: 560px) {
  .zg-stepper-title { display: none; }
  .zg-stepper-now { display: block; }
}

.zg-steps { position: relative; }
.zg-step { min-width: 0; }
.zg-step[hidden] { display: none !important; }
.zg-step.is-leaving {
  position: absolute; top: 0; left: 0; right: 0; pointer-events: none;
  animation: zg-step-out 260ms var(--zg-ease) both;
}
.zg-step.is-entering { animation: zg-step-in 260ms var(--zg-ease) both; }
/* While one step slips out, nothing may push the page wider than the screen. */
@supports (overflow: clip) {
  .zg-steps.is-switching { overflow-x: clip; }
}
@keyframes zg-step-in {
  from { opacity: 0; transform: translateX(calc(16px * var(--zg-dir, 1))); }
  to { opacity: 1; transform: none; }
}
@keyframes zg-step-out {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: translateX(calc(-16px * var(--zg-dir, 1))); }
}

.zg-step-nav { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 32px; }
.zg-step-nav:empty { display: none; }
.zg-step-next {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  min-height: 48px; margin-left: auto; padding-top: 8px; padding-bottom: 8px; line-height: 1.2;
}
.zg-step-back {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  min-height: 48px; padding: 8px 22px; border: 1px solid var(--zg-line); border-radius: 12px;
  background: transparent; color: var(--zg-muted); cursor: pointer;
  font-family: var(--zg-font-body); font-size: 18px; font-weight: 500; line-height: 1.2;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}
.zg-step-back:hover { background: var(--zg-surface-deep); border-color: var(--zg-field-line); color: var(--zg-ink); }
@media (max-width: 560px) {
  .zg-step-next { flex: 1 1 auto; }
}

/* ================================================================
   8. Deck controls — shared by both decks below.
   Previous, the dots and Next, built by ZgUI and put straight after the deck. The dots
   are 44px targets labelled with each card's title; the two buttons are 48px and say
   what they do. On a phone the dots sit above two wide buttons, from 601px they share
   one row.
   ================================================================ */
.zg-deck-controls {
  display: flex; align-items: center; justify-content: center; gap: 8px 14px;
  max-width: 100%; margin: 24px auto 0; font-family: var(--zg-font-body); color: var(--zg-ink);
}
.zg-deck-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; box-sizing: border-box;
  min-width: 48px; min-height: 48px; margin: 0; padding: 0 20px 0 14px;
  border: 1px solid var(--zg-field-line); border-radius: 999px; background: var(--zg-surface); color: var(--zg-ink);
  font: inherit; font-size: 18px; font-weight: 600; line-height: 1.2; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.zg-deck-next { padding: 0 14px 0 20px; }
.zg-deck-btn svg { flex: none; width: 20px; height: 20px; }
.zg-deck-btn:hover { background: var(--zg-surface-deep); border-color: var(--zg-accent-ink); }
.zg-deck-btn:active { background: var(--zg-surface-deep); }
.zg-deck-controls :focus-visible { outline: 3px solid var(--zg-focus); outline-offset: 2px; }
.zg-deck-dots { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; min-width: 0; }
.zg-deck-dot {
  display: grid; place-items: center; width: 44px; height: 44px; margin: 0; padding: 0; border: 0; border-radius: 50%;
  background: transparent; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.zg-deck-dot::before {
  content: ""; box-sizing: border-box; width: 14px; height: 14px; border: 2px solid var(--zg-accent-ink); border-radius: 50%;
  background: transparent;
}
.zg-deck-dot:hover::before { background: color-mix(in srgb, var(--zg-accent) 30%, transparent); }
.zg-deck-dot[aria-current="true"]::before { background: var(--zg-accent-ink); transform: scale(1.3); }
@media (prefers-reduced-motion: no-preference) {
  .zg-deck-btn { transition: background-color 180ms ease, border-color 180ms ease, transform 180ms var(--zg-ease); }
  .zg-deck-btn:active { transform: scale(.97); }
  .zg-deck-dot::before { transition: background-color 300ms var(--zg-ease), transform 300ms var(--zg-ease); }
}
@media (max-width: 600px) {
  .zg-deck-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 12px; }
  .zg-deck-dots { grid-column: 1 / -1; order: -1; }
  .zg-deck-btn { width: 100%; }
}
/* A quiet link under a deck ("See every gathering"). */
.zg-deck-more { margin: 14px 0 0; text-align: center; }

/* ================================================================
   9. Orbit deck — ZgUI.orbitDeck(container). A list of cards, sitting in one grid cell,
   becomes a small 3D deck: the current card faces forward at full size; the two beside
   it sit behind and to the sides, turned in about 28 degrees, a little smaller and
   dimmed; any others tuck away behind the front one. The stage holds the perspective.
   ZgUI sets data-slot on each card (0 front, -1 left, 1 right, anything else tucked)
   and CSS does the rest, so a page can restyle the poses without touching the script.
   Cards stay links: the front one follows its link, the others only come forward.
   Up to 600px wide the poses flatten (a gentler turn, a deeper peek at the edges) so
   the front card stays easy to read. Under reduced motion there is no perspective and
   no turn: the same layout, flat, and the cards swap places in one frame.
   ================================================================ */
.zg-orbit.zg-orbit {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; justify-items: center; align-items: start;
  scroll-margin-top: 112px;
  container-type: inline-size; perspective: 1500px; perspective-origin: 50% 30%; padding: 10px 0 18px;
  touch-action: pan-y pinch-zoom;
}
@supports (overflow: clip) {
  .zg-orbit.zg-orbit { overflow-x: clip; }
}
.zg-orbit > .zg-orbit-card {
  --zg-w: min(540px, 50cqw);
  --zg-x: calc(var(--zg-w) * .62);
  --zg-turn: 28deg;
  --zg-depth: 240px;
  grid-area: 1 / 1; position: relative; box-sizing: border-box; width: var(--zg-w); max-width: 100%; align-self: stretch; margin: 0;
  background: var(--zg-surface); -webkit-tap-highlight-color: transparent;
  transform: translate3d(0, 0, calc(var(--zg-depth) * -1.8)) scale(.88); opacity: 0; z-index: 1; pointer-events: none;
  transition: none;   /* the page's own card transition must not play when the deck first sets the poses */
}
@container (max-width: 600px) {
  .zg-orbit > .zg-orbit-card { --zg-w: min(460px, 100cqw - 48px); --zg-x: calc(var(--zg-w) * .17); --zg-turn: 12deg; --zg-depth: 110px; }
}
@supports not (width: 1cqw) {
  .zg-orbit > .zg-orbit-card { --zg-w: min(540px, 50vw); }
  @media (max-width: 600px) {
    .zg-orbit > .zg-orbit-card { --zg-w: min(460px, 100vw - 72px); --zg-x: calc(var(--zg-w) * .17); --zg-turn: 12deg; --zg-depth: 110px; }
  }
}
.zg-orbit > .zg-orbit-card[data-slot="0"] { transform: none; opacity: 1; z-index: 3; pointer-events: auto; }
.zg-orbit > .zg-orbit-card[data-slot="-1"],
.zg-orbit > .zg-orbit-card[data-slot="1"] { opacity: 1; z-index: 2; pointer-events: auto; cursor: pointer; }
.zg-orbit > .zg-orbit-card[data-slot="-1"] {
  transform: translate3d(calc(var(--zg-x) * -1), 0, calc(var(--zg-depth) * -1)) rotateY(var(--zg-turn)) scale(.9);
}
.zg-orbit > .zg-orbit-card[data-slot="1"] {
  transform: translate3d(var(--zg-x), 0, calc(var(--zg-depth) * -1)) rotateY(calc(var(--zg-turn) * -1)) scale(.9);
}
/* The dimming is a veil over the card, so only its opacity ever animates. */
.zg-orbit > .zg-orbit-card::after {
  content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: color-mix(in srgb, var(--zg-surface) 45%, transparent); opacity: 1;
}
.zg-orbit > .zg-orbit-card[data-slot="0"]::after { opacity: 0; }
@media (hover: hover) {
  .zg-orbit > .zg-orbit-card[data-slot="-1"]:hover::after,
  .zg-orbit > .zg-orbit-card[data-slot="1"]:hover::after { opacity: .5; }
}
.zg-orbit > .zg-orbit-card:focus-visible { outline: 3px solid var(--zg-focus); outline-offset: 4px; }
@media (prefers-reduced-motion: no-preference) {
  .zg-orbit.is-ready > .zg-orbit-card { transition: transform 600ms var(--zg-ease), opacity 600ms var(--zg-ease); }
  .zg-orbit.is-ready > .zg-orbit-card::after { transition: opacity 600ms var(--zg-ease); }
}
@media (prefers-reduced-motion: reduce) {
  .zg-orbit.zg-orbit { perspective: none; }
  .zg-orbit > .zg-orbit-card { --zg-w: min(480px, 48cqw); --zg-x: calc(var(--zg-w) * .55); }
  .zg-orbit > .zg-orbit-card[data-slot="-1"] { transform: translate3d(calc(var(--zg-x) * -1), 0, 0) scale(.9); }
  .zg-orbit > .zg-orbit-card[data-slot="1"] { transform: translate3d(var(--zg-x), 0, 0) scale(.9); }
  .zg-orbit > .zg-orbit-card:not([data-slot="0"]):not([data-slot="-1"]):not([data-slot="1"]) { transform: scale(.88); }
}
@container (max-width: 600px) {
  @media (prefers-reduced-motion: reduce) {
    .zg-orbit > .zg-orbit-card { --zg-w: min(460px, 100cqw - 48px); --zg-x: calc(var(--zg-w) * .17); }
  }
}

/* Zion Gathering bindings: the homepage cards (.gathering-card) carry page rules of their own
   (the editorial first/last card is a two-column grid), so these are written to out-rank them. */
.zg-orbit.zg-orbit > .zg-orbit-card.zg-orbit-card {
  grid-area: 1 / 1; display: flex; flex-direction: column; gap: 0; padding: 0;
}
.zg-orbit.zg-orbit > .zg-orbit-card.zg-orbit-card .gathering-card-image { height: 260px; min-height: 0; order: 0; flex: none; }
.zg-orbit.zg-orbit > .zg-orbit-card.zg-orbit-card .gathering-card-body { flex: 1; padding: 24px; }
@container (max-width: 600px) {
  .zg-orbit.zg-orbit > .zg-orbit-card.zg-orbit-card .gathering-card-image { height: 200px; }
  .zg-orbit.zg-orbit > .zg-orbit-card.zg-orbit-card .gathering-card-body { padding: 20px; }
}

/* ================================================================
   10. Stagger deck — ZgUI.staggerDeck(container). Quotations in one grid cell, fanned
   out: the centre card is raised and featured (dark, light text, a thin gold rule), and
   the cards either side alternate a little up and down with a 2 degree tilt, in surface
   colour with a 1px line. Clicking a card or Previous / Next makes it the centre; the
   card that wraps round to the far side jumps there instead of sliding across the
   others. ZgUI sets data-slot on each card (-2 to 2); the spread is worked out from the
   stage's own width, so every card stays on screen at 375px and on a wide desktop alike.
   Each quotation is held to --zg-lines lines; the front card offers the rest.
   Under reduced motion there is no tilt and no slide.
   ================================================================ */
.zg-stagger.zg-stagger {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; justify-items: center; align-items: stretch;
  container-type: inline-size; margin: 8px 0 0; padding: 44px 0 26px; border: 0; scroll-margin-top: 112px;
  touch-action: pan-y pinch-zoom;
}
@supports (overflow: clip) {
  .zg-stagger.zg-stagger { overflow-x: clip; }
}
.zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card {
  --zg-w: min(400px, 100cqw - 32px);
  --zg-step: min(var(--zg-w) * .67, (100cqw - var(--zg-w)) / (2 * var(--zg-max, 1)));
  grid-area: 1 / 1; display: flex; flex-direction: column; box-sizing: border-box; align-self: stretch;
  width: var(--zg-w); max-width: none; margin: 0; padding: 30px 26px 22px;
  border-style: solid; border-width: 1px; border-radius: var(--zg-radius-card);
}
@supports not (width: 1cqw) {
  .zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card { --zg-w: min(400px, 100vw - 56px); --zg-step: calc(var(--zg-w) * .3); }
}
.zg-stagger.has-open.has-open > .zg-stagger-card.zg-stagger-card:not(.is-open) { align-self: start; }
/* A card's place in the fan is written with the separate translate / rotate / scale properties,
   leaving transform free for the pointer tilt below; each one is eased on its own. --zg-glow is
   the soft gold halo a hovered card gains; it always holds two shadows so the list can ease. */
.zg-stagger > .zg-stagger-card[data-slot] {
  --zg-o: 0; --zg-y: 0px; --zg-r: 0deg; --zg-s: .94;
  background: var(--zg-surface); color: var(--zg-ink); border-color: var(--zg-line);
  box-shadow: var(--zg-shadow), var(--zg-glow, 0 0 0 0 transparent, 0 0 0 0 transparent);
  translate: calc(var(--zg-o) * var(--zg-step)) var(--zg-y); rotate: var(--zg-r); scale: var(--zg-s);
  transform: perspective(900px) rotateX(var(--zg-tilt-x, 0deg)) rotateY(var(--zg-tilt-y, 0deg));
  opacity: 0; z-index: 1; pointer-events: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: none;
}
.zg-stagger > .zg-stagger-card[data-slot="0"] {
  --zg-y: -22px; --zg-s: 1; z-index: 6; opacity: 1; pointer-events: auto; cursor: default;
  background: var(--zg-feature); color: var(--zg-feature-ink);
  border-color: color-mix(in srgb, var(--zg-feature-accent) 55%, var(--zg-feature));
  box-shadow: 0 2px 4px rgb(0 0 0 / 14%), 0 24px 48px rgb(32 31 27 / 30%), var(--zg-glow, 0 0 0 0 transparent, 0 0 0 0 transparent);
}
.zg-stagger > .zg-stagger-card[data-slot="-1"] { --zg-o: -1; --zg-y: 14px; --zg-r: -2deg; z-index: 5; opacity: 1; pointer-events: auto; }
.zg-stagger > .zg-stagger-card[data-slot="1"] { --zg-o: 1; --zg-y: 14px; --zg-r: 2deg; z-index: 5; opacity: 1; pointer-events: auto; }
.zg-stagger > .zg-stagger-card[data-slot="-2"] { --zg-o: -2; --zg-y: -4px; --zg-r: 2deg; z-index: 4; opacity: 1; pointer-events: auto; }
.zg-stagger > .zg-stagger-card[data-slot="2"] { --zg-o: 2; --zg-y: -4px; --zg-r: -2deg; z-index: 4; opacity: 1; pointer-events: auto; }
.zg-stagger > .zg-stagger-card:focus-visible,
.zg-stagger > .zg-stagger-card :focus-visible { outline: 3px solid var(--zg-focus); outline-offset: 3px; }
.zg-stagger > .zg-stagger-card[data-slot="0"] :focus-visible { outline-color: var(--zg-feature-accent); }
@media (prefers-reduced-motion: no-preference) {
  .zg-stagger.is-ready > .zg-stagger-card {
    transition: translate 500ms var(--zg-ease), rotate 500ms var(--zg-ease), scale 500ms var(--zg-ease), opacity 500ms var(--zg-ease),
      background-color 500ms var(--zg-ease), color 500ms var(--zg-ease), border-color 500ms var(--zg-ease),
      box-shadow 500ms var(--zg-ease), transform 220ms var(--zg-ease);
  }
}
@media (prefers-reduced-motion: reduce) {
  .zg-stagger > .zg-stagger-card[data-slot] { --zg-r: 0deg; transform: none; }
}
/* A mouse resting on a card: a soft gold glow (the slight tilt toward the pointer is drawn by zg-ui.js, only
   for a mouse or pen, never a finger). */
@media (hover: hover) and (pointer: fine) {
  .zg-stagger > .zg-stagger-card[data-slot]:hover {
    --zg-glow: 0 0 0 1px color-mix(in srgb, var(--zg-accent-bright) 60%, transparent),
      0 12px 44px color-mix(in srgb, var(--zg-accent-bright) 42%, transparent);
  }
}

/* The words on a card. ZgUI marks the quotation, its attribution, the name and the meta line
   (.zg-q-text, .zg-q-by, .zg-q-name, .zg-q-meta) whatever the page called them; five classes
   out-rank the page's own testimonial rules. Quote 20px, name 18px, meta 17px. */
.zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card .zg-q-text {
  margin: 0 0 22px; font-family: var(--zg-font-display); font-size: 20px; font-style: italic; font-weight: 500;
  line-height: 1.5; letter-spacing: 0; color: inherit;
}
.zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card.testimonial .zg-q-text { margin-top: 26px; }
.zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card .zg-q-by {
  display: block; margin: auto 0 0; padding: 16px 0 0; border: 0; border-top: 1px solid var(--zg-line-soft);
  font-style: normal; color: inherit;
}
.zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card .zg-q-name {
  display: block; margin: 0; font-family: var(--zg-font-body); font-size: 18px; font-weight: 600; font-style: normal;
  line-height: 1.4; letter-spacing: 0; color: inherit;
}
.zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card .zg-q-meta {
  display: block; margin: 2px 0 0; font-family: var(--zg-font-body); font-size: 17px; font-style: normal; font-weight: 400;
  line-height: 1.4; letter-spacing: 0; color: var(--zg-muted);
}
.zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card[data-slot="0"] .zg-q-by { border-top-color: var(--zg-feature-accent); }
.zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card[data-slot="0"] .zg-q-meta { color: color-mix(in srgb, var(--zg-feature-ink) 78%, transparent); }
.zg-stagger > .zg-stagger-card a { color: var(--zg-accent-ink); }
.zg-stagger > .zg-stagger-card[data-slot="0"] a { color: var(--zg-feature-accent); }
/* The opening quotation mark: the testimonials page draws its own, the gathering page puts one before the text. */
.zg-stagger > .zg-stagger-card.testimonial::before { top: 12px; left: 22px; color: var(--zg-accent-ink); }
.zg-stagger > .zg-stagger-card[data-slot="0"].testimonial::before,
.zg-stagger > .zg-stagger-card[data-slot="0"] .zg-q-text::before { color: var(--zg-feature-accent); }

.zg-clamp {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: var(--zg-lines, 8); line-clamp: var(--zg-lines, 8);
  overflow: hidden;
}
.zg-stagger-card.is-open .zg-clamp { display: block; -webkit-line-clamp: none; line-clamp: none; overflow: visible; }
.zg-stagger-more {
  align-self: flex-start; min-height: 44px; margin: -10px 0 10px; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-family: var(--zg-font-body); font-size: 18px; font-weight: 600; font-style: normal; line-height: 1.3;
  color: var(--zg-accent-ink); text-decoration: underline; text-underline-offset: 4px;
}
.zg-stagger-more[hidden] { display: none; }
.zg-stagger > .zg-stagger-card[data-slot="0"] .zg-stagger-more { color: var(--zg-feature-accent); }

/* ================================================================
   11. Decision card — one thing that needs a person, with the reasons in plain words.
   ZgUI.decision({ title, href, tone, chips, facts, done, open }) writes the markup:
   a title link, small labelled chips (.zg-chip, one per reason), a line of facts, and
   two actions: .zg-decision-done (the quick answer) and .zg-decision-open (the long way).
   The coloured edge follows data-tone (late, wait, gap). A note under the facts
   (.zg-decision-note) is where a page explains why an action did not go through.
   ================================================================ */
.zg-decision {
  --zg-edge: var(--zg-accent);
  position: relative; overflow: hidden; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 14px 22px; align-items: center;
  box-sizing: border-box; padding: 16px 20px 16px 26px;
  background: var(--zg-surface); color: var(--zg-ink);
  border: 1px solid var(--zg-card-line); border-radius: var(--zg-radius);
  box-shadow: var(--zg-shadow); font-family: var(--zg-font-body);
}
.zg-decision::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px; background: var(--zg-edge); }
.zg-decision[data-tone=late] { --zg-edge: var(--zg-tone-warn); }
.zg-decision[data-tone=wait] { --zg-edge: var(--zg-tone-info); }
.zg-decision-main { min-width: 0; }
.zg-decision-title {
  display: inline-block; font-size: 20px; font-weight: 600; line-height: 1.35; color: var(--zg-ink);
  text-decoration: none; overflow-wrap: anywhere;
}
.zg-decision-title:hover { text-decoration: underline; text-underline-offset: 4px; }
.zg-decision :focus-visible { outline: 3px solid var(--zg-focus); outline-offset: 3px; }
.zg-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 0; padding: 0; list-style: none; }
.zg-chip {
  --zg-chip: var(--zg-muted);
  display: inline-flex; align-items: center; box-sizing: border-box; max-width: 100%; min-height: 32px; margin: 0; padding: 3px 12px;
  border: 1px solid var(--zg-chip); border-radius: 18px;
  background: var(--zg-surface); color: var(--zg-chip);
  font-size: 17px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere;
}
@supports (color: color-mix(in srgb, red 10%, white)) {
  .zg-chip {
    border-color: color-mix(in srgb, var(--zg-chip) 42%, transparent);
    background: color-mix(in srgb, var(--zg-chip) 11%, var(--zg-surface));
  }
}
.zg-chip[data-tone=late] { --zg-chip: var(--zg-tone-warn); }
.zg-chip[data-tone=wait] { --zg-chip: var(--zg-tone-info); }
.zg-chip[data-tone=gap] { --zg-chip: var(--zg-accent-ink); }
.zg-chip[data-tone=good] { --zg-chip: var(--zg-tone-success); }
.zg-decision-facts { margin: 10px 0 0; font-size: 17px; line-height: 1.45; color: var(--zg-muted); }
.zg-decision-note { margin: 10px 0 0; font-size: 17px; line-height: 1.5; color: var(--zg-ink); }
.zg-decision-note[data-tone=warn] { color: var(--zg-tone-warn); font-weight: 600; }
.zg-decision-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.zg-decision-done {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; min-height: 48px; margin: 0; padding: 0 22px;
  border: 1px solid var(--zg-accent-ink); border-radius: calc(var(--zg-radius) - 4px);
  background: var(--zg-surface-deep); color: var(--zg-ink);
  font: inherit; font-size: 18px; font-weight: 600; line-height: 1.2; white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
@supports (color: color-mix(in srgb, red 10%, white)) {
  .zg-decision-done { background: color-mix(in srgb, var(--zg-accent) 16%, var(--zg-surface)); }
}
.zg-decision-done:hover:not(:disabled) { background: var(--zg-surface-deep); border-color: var(--zg-accent-ink); }
.zg-decision-done:disabled { opacity: .65; cursor: wait; }
.zg-decision-open {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; min-height: 48px; padding: 0 14px;
  font-size: 18px; font-weight: 600; color: var(--zg-accent-ink); text-decoration: underline; text-underline-offset: 4px;
}
@media (max-width: 640px) {
  .zg-decision { grid-template-columns: minmax(0, 1fr); padding: 16px 16px 14px 22px; }
  .zg-decision-actions { justify-content: stretch; flex-wrap: nowrap; }
  .zg-decision-done { flex: 1 1 auto; }
  .zg-decision-open:first-child { margin-left: -14px; }
}
@media (prefers-reduced-motion: no-preference) {
  .zg-decision-done { transition: transform 180ms var(--zg-ease-spring), background-color 160ms ease; }
  .zg-decision-done:hover:not(:disabled) { transform: translateY(-1px); }
  .zg-decision-done:active:not(:disabled) { transform: scale(.98); }
}

/* ================================================================
   12. Fold and enter — a list item leaving or arriving.
   ZgUI.fold(el, done) shrinks el to nothing (height, spacing and opacity, 320ms) and
   removes it; ZgUI.enter(el) lets a new one settle in with a small spring. Both do
   nothing visible under reduced motion: fold removes the item at once.
   ================================================================ */
.zg-folding { overflow: hidden; pointer-events: none; animation: zg-fold 320ms var(--zg-ease-glide) both; }
@keyframes zg-fold {
  to { height: 0; margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; opacity: 0; }
}
.zg-entering { animation: zg-enter 460ms var(--zg-ease-spring) both; }
@keyframes zg-enter {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to { opacity: 1; transform: none; }
}

/* ================================================================
   13. Tick — a mark that folds from a cross into a check inside a button. The same two bars
   as .zg-check, without the box. ZgUI.tick(button) swaps the button's label for it and says
   how long to let it play.
   ================================================================ */
.zg-tick {
  --zg-s: 24px;
  position: relative; display: inline-block; flex: none; width: 24px; height: 24px; vertical-align: middle; opacity: 0;
  transition: opacity 160ms ease;
}
.zg-tick.is-on { opacity: 1; }
.zg-tick::before,
.zg-tick::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: calc(var(--zg-s) * .62); height: 3px; margin: -1.5px 0 0 calc(var(--zg-s) * -.31);
  border-radius: 3px; background: currentColor; transition: transform 320ms var(--zg-ease-spring);
}
.zg-tick::before { transform: rotate(45deg); }
.zg-tick::after { transform: rotate(-45deg); }
.zg-tick.is-on::before { transform: translate(calc(var(--zg-s) * -.177), calc(var(--zg-s) * .083)) rotate(48deg) scaleX(.46); }
.zg-tick.is-on::after { transform: translate(calc(var(--zg-s) * .104), calc(var(--zg-s) * -.02)) rotate(-48deg) scaleX(.9); }
/* A button is disabled while its answer is saved; once it shows the check it is not dimmed. */
.zg-ticked:disabled { opacity: 1 !important; cursor: default !important; }

/* ================================================================
   14. Lamp switch — a 56 x 32 track with a sliding thumb, for a setting that is on or off
   (the planner's Dark switch). When on, the track holds a soft candle-gold glow. The look
   follows aria-checked on the switch it sits in, or .is-on when it stands alone:
   <button role="switch" aria-checked="false"><span class="zg-lamp" aria-hidden="true"><span class="zg-lamp-thumb"></span></span>Dark</button>
   The thumb glides 400ms; under reduced motion it jumps.
   ================================================================ */
.zg-lamp {
  position: relative; display: inline-block; flex: none; box-sizing: border-box; width: 56px; height: 32px;
  border: 1px solid var(--zg-field-line); border-radius: 999px; background: var(--zg-surface-deep);
  box-shadow: inset 0 1px 2px rgb(32 31 27 / 14%);
  transition: background-color 400ms var(--zg-ease-glide), border-color 400ms var(--zg-ease-glide), box-shadow 400ms var(--zg-ease-glide);
}
.zg-lamp-thumb {
  position: absolute; left: 3px; top: 3px; box-sizing: border-box; width: 24px; height: 24px; border-radius: 50%;
  background: var(--zg-surface); border: 1px solid var(--zg-field-line); box-shadow: 0 1px 3px rgb(32 31 27 / 24%);
  transition: transform 400ms var(--zg-ease-glide), background-color 400ms var(--zg-ease-glide), border-color 400ms var(--zg-ease-glide), box-shadow 400ms var(--zg-ease-glide);
}
.zg-lamp.is-on,
[aria-checked="true"] > .zg-lamp {
  border-color: var(--zg-accent);
  background: var(--zg-surface-deep);
  box-shadow: 0 0 16px 2px var(--zg-accent), inset 0 0 8px var(--zg-accent);
}
.zg-lamp.is-on .zg-lamp-thumb,
[aria-checked="true"] > .zg-lamp .zg-lamp-thumb {
  transform: translateX(24px); background: var(--zg-accent-bright); border-color: var(--zg-accent-bright);
  box-shadow: 0 0 10px 3px var(--zg-accent-bright);
}
@supports (color: color-mix(in srgb, red 10%, white)) {
  .zg-lamp.is-on,
  [aria-checked="true"] > .zg-lamp {
    background: color-mix(in srgb, var(--zg-accent) 30%, var(--zg-surface-deep));
    box-shadow: 0 0 16px 2px color-mix(in srgb, var(--zg-accent-bright) 42%, transparent),
      inset 0 0 8px color-mix(in srgb, var(--zg-accent-bright) 26%, transparent);
  }
  .zg-lamp.is-on .zg-lamp-thumb,
  [aria-checked="true"] > .zg-lamp .zg-lamp-thumb {
    box-shadow: 0 0 10px 3px color-mix(in srgb, var(--zg-accent-bright) 70%, transparent);
  }
}

/* A loading message the page already prints, given a placeholder in place of the glow:
   ZgUI.skeletonize(node, kind, count) adds this class. */
.zg-has-skeleton:not([hidden]) { display: block; }
.zg-has-skeleton::before { display: none; }

/* ================================================================
   15. Site menus — ZgUI.siteNav(header). A short header: the brand, a few links, and two disclosure
   menus (a button with aria-expanded that opens a list of links). From 1100px wide the links sit in
   one row and a menu opens as a card under its button (on click, or after a short hover; Escape or a
   click elsewhere closes it, the arrow keys move through it). Narrower than that the row becomes one
   Menu button and a sheet that slides down from the header, with 56px rows, a Close button, and the
   page behind it held still. Markup (see ZgUI.siteNav in zg-ui.js):
     <header class="zg-header" data-zg-nav><nav class="zg-nav">
       brand, <button class="zg-nav-toggle" data-zg-nav-toggle>, <div class="zg-nav-panel" data-zg-nav-panel>
         <ul class="zg-nav-list"> <li class="zg-menu" data-zg-menu><button class="zg-menu-btn" data-zg-menu-button>
         <div class="zg-menu-pop"><ul class="zg-menu-list"><li><a class="zg-menu-link">…
   Without scripting the sheet is simply open and the menus show on hover or focus.
   ================================================================ */
.zg-nav-toggle, .zg-nav-close { display: none; }
.zg-nav-panel { margin-left: auto; }
.zg-nav-list { display: flex; align-items: center; gap: 4px; margin: 0; padding: 0; list-style: none; }
.zg-nav-list > li { margin: 0; padding: 0; }
.zg-nav-list > li:has(> [hidden]:only-child) { display: none; }
.zg-nav-link,
.zg-menu-btn {
  display: inline-flex; align-items: center; gap: 8px; box-sizing: border-box; min-height: 48px; margin: 0; padding: 0 16px;
  border: 1px solid transparent; border-radius: var(--zg-radius-pill); background: transparent; color: var(--zg-ink);
  font-family: var(--zg-font-body); font-size: 17px; font-weight: 500; line-height: 1.2; letter-spacing: .01em; white-space: nowrap;
  text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color 180ms ease, border-color 180ms ease, color 180ms ease;
}
.zg-nav-link:hover, .zg-menu-btn:hover, .zg-menu-btn[aria-expanded="true"] {
  background: color-mix(in srgb, var(--zg-accent) 10%, var(--zg-surface)); border-color: var(--zg-line); color: var(--zg-ink);
}
.zg-nav-link[aria-current], .zg-menu-btn[data-current], .zg-menu:has([aria-current]) > .zg-menu-btn {
  color: var(--zg-accent-ink); border-color: color-mix(in srgb, var(--zg-accent) 55%, transparent);
  background: color-mix(in srgb, var(--zg-accent) 9%, var(--zg-surface));
}
.zg-menu-chev { flex: none; width: 14px; height: 14px; transition: transform 200ms var(--zg-ease); }
.zg-menu-btn[aria-expanded="true"] .zg-menu-chev { transform: rotate(180deg); }
.zg-header :is(a, button):focus-visible { outline: 3px solid var(--zg-focus); outline-offset: 2px; }

.zg-menu { position: relative; }
.zg-menu-pop {
  position: absolute; top: calc(100% + 10px); left: 0; z-index: 5; box-sizing: border-box; min-width: 340px; max-width: min(430px, calc(100vw - 32px));
  background: var(--zg-surface); border: 1px solid var(--zg-card-line); border-radius: var(--zg-radius-card);
  box-shadow: 0 2px 4px rgb(32 31 27 / 6%), 0 18px 48px rgb(32 31 27 / 18%);
  visibility: hidden; opacity: 0; translate: 0 -6px;
  transition: opacity 180ms var(--zg-ease), translate 180ms var(--zg-ease), visibility 0s linear 180ms;
}
/* Keeps the pointer inside the menu while it crosses the gap under the button. */
.zg-menu-pop::before { content: ""; position: absolute; left: 0; right: 0; top: -12px; height: 12px; }
.zg-menu[data-align="end"] > .zg-menu-pop { left: auto; right: 0; }
.zg-menu.is-open > .zg-menu-pop { visibility: visible; opacity: 1; translate: 0 0; transition-delay: 0s; }
.zg-menu-list { margin: 0; padding: 8px; list-style: none; }
.zg-menu-list > li { margin: 0; padding: 0; }
.zg-menu-link {
  display: flex; flex-direction: column; gap: 2px; box-sizing: border-box; padding: 12px 16px; border-radius: var(--zg-radius-inner);
  color: var(--zg-ink); font-family: var(--zg-font-body); font-size: 18px; font-weight: 600; line-height: 1.3; text-decoration: none;
  transition: background-color 160ms ease;
}
.zg-menu-link:hover, .zg-menu-link:focus-visible { background: color-mix(in srgb, var(--zg-accent) 12%, var(--zg-surface)); color: var(--zg-ink); }
.zg-menu-sub { font-size: 17px; font-weight: 400; line-height: 1.35; color: var(--zg-muted); }
.zg-menu-link[aria-current] { background: color-mix(in srgb, var(--zg-accent) 9%, var(--zg-surface)); }
.zg-menu-link[aria-current] .zg-menu-name { color: var(--zg-accent-ink); }
.zg-menu-list > .zg-menu-more { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--zg-line-soft); }
.zg-menu-more .zg-menu-link { flex-direction: row; align-items: center; justify-content: space-between; color: var(--zg-accent-ink); }
.zg-nav-list > .zg-nav-cta-item { margin-left: 8px; }
.zg-nav-cta { display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; min-height: 48px; margin: 0; white-space: nowrap; }

@media (max-width: 1099px) {
  .zg-nav-toggle {
    display: inline-flex; align-items: center; gap: 10px; box-sizing: border-box; min-height: 48px; margin: 0 0 0 auto; padding: 0 18px 0 14px;
    border: 1px solid var(--zg-field-line); border-radius: var(--zg-radius-pill); background: var(--zg-surface); color: var(--zg-ink);
    font-family: var(--zg-font-body); font-size: 18px; font-weight: 600; line-height: 1; cursor: pointer; -webkit-tap-highlight-color: transparent;
    transition: background-color 160ms ease, border-color 160ms ease;
  }
  .zg-nav-toggle:hover, .zg-nav-toggle[aria-expanded="true"] { background: var(--zg-surface-deep); border-color: var(--zg-accent-ink); }
  .zg-nav-toggle-icon { position: relative; flex: none; width: 22px; height: 16px; }
  .zg-nav-toggle-icon i {
    position: absolute; left: 0; width: 22px; height: 2px; border-radius: 2px; background: currentColor;
    transition: transform 240ms var(--zg-ease), top 240ms var(--zg-ease), opacity 160ms ease;
  }
  .zg-nav-toggle-icon i:nth-child(1) { top: 0; }
  .zg-nav-toggle-icon i:nth-child(2) { top: 7px; }
  .zg-nav-toggle-icon i:nth-child(3) { top: 14px; }
  .zg-nav-toggle[aria-expanded="true"] .zg-nav-toggle-icon i:nth-child(1) { top: 7px; transform: rotate(45deg); }
  .zg-nav-toggle[aria-expanded="true"] .zg-nav-toggle-icon i:nth-child(2) { opacity: 0; }
  .zg-nav-toggle[aria-expanded="true"] .zg-nav-toggle-icon i:nth-child(3) { top: 7px; transform: rotate(-45deg); }

  .zg-nav-panel {
    position: absolute; left: 0; right: 0; top: 100%; z-index: 1; box-sizing: border-box; margin: 0;
    max-height: calc(100vh - var(--zg-nav-bottom, 100px)); max-height: calc(100dvh - var(--zg-nav-bottom, 100px));
    overflow-y: auto; overscroll-behavior: contain; padding: 4px 20px 24px;
    background: var(--zg-surface); border-bottom: 2px solid var(--zg-accent); box-shadow: 0 28px 40px -14px rgb(32 31 27 / 34%);
    visibility: hidden; opacity: 0; translate: 0 -12px;
    transition: opacity 220ms var(--zg-ease), translate 220ms var(--zg-ease), visibility 0s linear 220ms;
  }
  .zg-header.is-open .zg-nav-panel { visibility: visible; opacity: 1; translate: 0 0; transition-delay: 0s; }
  /* The page behind the sheet is dimmed and held still; a click on the dimmed part closes the sheet. */
  .zg-header.is-open::after {
    content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 100vh; z-index: -1; background: rgb(24 23 19 / 46%);
  }
  html.zg-nav-locked, html.zg-nav-locked body { overflow: hidden; }

  .zg-nav-list { flex-direction: column; align-items: stretch; gap: 0; }
  .zg-nav-list > li { border-bottom: 1px solid var(--zg-line-soft); }
  .zg-nav-list > li:last-child { border-bottom: 0; }
  .zg-nav-link, .zg-menu-btn {
    width: 100%; min-height: var(--zg-nav-row); padding: 0 6px; border: 0; border-radius: 0; justify-content: space-between;
    background: transparent; font-size: 20px; font-weight: 600; white-space: normal; text-align: left;
  }
  .zg-nav-link:hover, .zg-menu-btn:hover, .zg-menu-btn[aria-expanded="true"] { background: transparent; border-color: transparent; color: var(--zg-accent-ink); }
  .zg-nav-link[aria-current], .zg-menu-btn[data-current], .zg-menu:has([aria-current]) > .zg-menu-btn { background: transparent; border-color: transparent; }
  .zg-menu-chev { width: 18px; height: 18px; }

  .zg-menu-pop {
    position: static; display: grid; grid-template-rows: 0fr; min-width: 0; max-width: none; border: 0; border-radius: 0; background: transparent;
    box-shadow: none; opacity: 1; translate: none; visibility: hidden;
    transition: grid-template-rows 260ms var(--zg-ease), visibility 0s linear 260ms;
  }
  .zg-menu-pop::before { display: none; }
  .zg-menu.is-open > .zg-menu-pop { grid-template-rows: 1fr; visibility: visible; transition-delay: 0s; }
  .zg-menu-list { min-height: 0; overflow: hidden; padding: 0 0 10px; }
  .zg-menu-link {
    min-height: var(--zg-nav-row); justify-content: center; margin: 0 0 4px 6px; padding: 10px 12px 10px 18px;
    border-left: 3px solid var(--zg-line); border-radius: 0 var(--zg-radius-inner) var(--zg-radius-inner) 0; font-size: 20px;
  }
  .zg-menu-link[aria-current] { border-left-color: var(--zg-accent); }
  .zg-menu-list > .zg-menu-more { margin-top: 0; padding-top: 0; border-top: 0; }
  .zg-nav-list > .zg-nav-cta-item { margin: 0; padding: 16px 0 6px; }
  .zg-nav-cta { display: flex; width: 100%; min-height: var(--zg-nav-row); font-size: 20px; }
  .zg-nav-close {
    display: flex; align-items: center; justify-content: center; width: 100%; min-height: var(--zg-nav-row); margin: 10px 0 0; padding: 0 20px;
    border: 1px solid var(--zg-field-line); border-radius: var(--zg-radius-pill); background: transparent; color: var(--zg-ink);
    font-family: var(--zg-font-body); font-size: 20px; font-weight: 600; line-height: 1.2; cursor: pointer; -webkit-tap-highlight-color: transparent;
  }
  .zg-nav-close:hover { background: var(--zg-surface-deep); border-color: var(--zg-accent-ink); }
}
@media (scripting: none) {
  .zg-nav-toggle, .zg-nav-close, .zg-menu-chev { display: none; }
}
@media (scripting: none) and (max-width: 1099px) {
  .zg-nav-panel { position: static; visibility: visible; opacity: 1; translate: none; max-height: none; box-shadow: none; }
  .zg-menu-pop { grid-template-rows: 1fr; visibility: visible; }
}
@media (scripting: none) and (min-width: 1100px) {
  .zg-menu:hover > .zg-menu-pop, .zg-menu:focus-within > .zg-menu-pop { visibility: visible; opacity: 1; translate: 0 0; transition-delay: 0s; }
}

/* ================================================================
   16. Sheen and fill buttons. .zg-sheen on a primary button: a gold sheen sweeps across once on hover
   or keyboard focus (about 700ms, masked by the button's own shape), the button rises 1px, and sinks in
   when pressed. .zg-fill on a secondary (outlined) button: a soft gold tint grows in from the left.
   An arrow inside either (<span class="zg-arrow" aria-hidden="true">→</span>) nudges 3px. Colours, the
   depth of the shadow and the lift are the --zg-sheen / --zg-fill / --zg-btn-* tokens. Zion Gathering
   binds them to its own buttons below. Under reduced motion only the colours change.
   ================================================================ */
.zg-sheen,
.public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary) {
  position: relative; isolation: isolate;
  box-shadow: var(--zg-btn-shadow);
  transition: transform 200ms var(--zg-ease), box-shadow 200ms var(--zg-ease), background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}
.zg-sheen::after,
.public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary)::after {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: linear-gradient(100deg, transparent 38%, var(--zg-sheen) 50%, transparent 62%) no-repeat;
  background-size: 300% 100%; background-position: 100% 0;
}
.zg-sheen:hover::after, .zg-sheen:focus-visible::after,
.public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary):is(:hover, :focus-visible)::after {
  background-position: 0 0; transition: background-position var(--zg-sheen-ms) var(--zg-ease-glide);
}
.zg-sheen:hover,
.public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary):hover {
  transform: translateY(var(--zg-btn-lift)); box-shadow: var(--zg-btn-shadow-hover);
}
.zg-sheen:active,
.public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary):active {
  transform: translateY(var(--zg-btn-press)); box-shadow: var(--zg-btn-shadow-press); transition-duration: 90ms;
}
.zg-sheen:is(:disabled, [aria-disabled="true"])::after,
.public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary):is(:disabled, [aria-disabled="true"])::after { display: none; }
.zg-sheen:is(:disabled, [aria-disabled="true"]):hover,
.public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary):is(:disabled, [aria-disabled="true"]):hover { transform: none; box-shadow: var(--zg-btn-shadow); }

.zg-fill,
.public-site .btn-secondary {
  background-image: linear-gradient(90deg, var(--zg-fill), var(--zg-fill)); background-repeat: no-repeat; background-position: left center;
  background-size: 0% 100%;
  transition: background-size 420ms var(--zg-ease-glide), transform 200ms var(--zg-ease), box-shadow 200ms var(--zg-ease),
    border-color 200ms ease, color 200ms ease;
}
.zg-fill:hover, .zg-fill:focus-visible,
.public-site .btn-secondary:is(:hover, :focus-visible) { background-size: 100% 100%; }
.zg-fill:hover,
.public-site .btn-secondary:hover { transform: translateY(var(--zg-btn-lift)); box-shadow: var(--zg-btn-shadow-hover); }
.zg-fill:active,
.public-site .btn-secondary:active { transform: translateY(var(--zg-btn-press)); box-shadow: var(--zg-btn-shadow-press); transition-duration: 90ms; }

.zg-arrow { display: inline-block; margin-left: .4em; transition: translate 220ms var(--zg-ease); }
a:hover > .zg-arrow, button:hover > .zg-arrow, a:focus-visible > .zg-arrow, button:focus-visible > .zg-arrow,
a:hover .zg-arrow, button:hover .zg-arrow { translate: 3px 0; }

/* ================================================================
   17. Announcement bar — ZgUI.bar(opts). A slim dark bar above the header: a few facts, one link, and a
   button to dismiss it for the visit. It slides open when it arrives (nothing jumps), and every line is
   17px or larger; on a phone it wraps to two short lines. The whole text is the link.
   ================================================================ */
.zg-bar {
  display: grid; grid-template-rows: 0fr; position: relative; z-index: 2;
  background: var(--zg-bar-bg); color: var(--zg-bar-ink); font-family: var(--zg-font-body);
  transition: grid-template-rows 320ms var(--zg-ease);
}
.zg-bar.is-in { grid-template-rows: 1fr; }
.zg-bar-clip { min-height: 0; overflow: hidden; }
.zg-bar-inner { display: flex; align-items: center; justify-content: center; gap: 4px; max-width: 1440px; margin: 0 auto; padding: 2px 6px 2px 50px; }
/* The facts are flex items that wrap whole (a date is never split across two lines); on a phone the dots go and a gap
   separates them. */
.zg-bar-link {
  display: flex; flex-wrap: wrap; align-items: baseline; align-content: center; justify-content: center;
  flex: 0 1 auto; min-width: 0; box-sizing: border-box; min-height: 44px; padding: 8px 6px; color: inherit;
  font-size: 17px; line-height: 1.4; text-decoration: none;
}
.zg-bar-link:hover { color: inherit; }
.zg-bar-part { white-space: nowrap; }
.zg-bar-name { font-size: 18px; font-weight: 600; white-space: normal; }
.zg-bar-dot { margin: 0 .55em; color: var(--zg-bar-accent); }
.zg-bar-go {
  color: var(--zg-bar-accent); font-weight: 600; white-space: nowrap; text-decoration: underline; text-underline-offset: 4px;
  text-decoration-color: transparent; transition: text-decoration-color 160ms ease;
}
.zg-bar-link:hover .zg-bar-go, .zg-bar-link:focus-visible .zg-bar-go { text-decoration-color: currentColor; }
.zg-bar-close {
  flex: none; display: grid; place-items: center; width: 44px; height: 44px; margin: 0; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--zg-bar-ink); cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color 160ms ease;
}
.zg-bar-close:hover { background: rgb(255 255 255 / 12%); }
.zg-bar-close svg { width: 18px; height: 18px; display: block; }
.zg-bar :focus-visible { outline: 3px solid var(--zg-bar-accent); outline-offset: -3px; }
@media (max-width: 640px) {
  .zg-bar-inner { justify-content: space-between; padding: 0 4px 0 16px; }
  .zg-bar-link { flex: 1 1 auto; justify-content: flex-start; column-gap: .85em; padding: 6px 4px; }
  .zg-bar-dot { display: none; }
}

/* ================================================================
   18. Reveal on scroll — ZgUI.reveal(root). Elements marked data-zg-reveal ("rise" the default, "pop" or
   "fade") that start below the fold rise 16px and fade in once, a beat apart when several arrive
   together. The hidden state is only ever added by the script, to elements not yet on screen: with no
   script, no IntersectionObserver or reduced motion, nothing is hidden. Opacity and the separate
   translate / scale properties are used, so a card's own hover transform is left alone.
   ================================================================ */
.zg-reveal {
  opacity: 0; translate: 0 16px;
  transition: opacity 700ms var(--zg-ease) var(--zg-reveal-delay, 0ms), translate 700ms var(--zg-ease) var(--zg-reveal-delay, 0ms),
    scale 700ms var(--zg-ease) var(--zg-reveal-delay, 0ms);
}
.zg-reveal[data-zg-reveal="pop"] { translate: none; scale: .92; }
.zg-reveal[data-zg-reveal="fade"] { translate: none; }
.zg-reveal.zg-reveal-in { opacity: 1; translate: 0 0; scale: 1; }

/* ================================================================
   19. Count-up — ZgUI.countUp(el) / [data-zg-count="14"]. The number counts up from zero the first
   time it is seen. Digits keep a fixed width so nothing shifts while they change.
   ================================================================ */
.zg-count { font-variant-numeric: lining-nums tabular-nums; }

/* ================================================================
   20. Deck pause button — a deck given the autoplay option (data-zg-autoplay="7000") gets a Pause / Play
   button after Next. It is a full 48px control with a visible word; on a phone it has a row of its own.
   ================================================================ */
.zg-deck-pause { padding: 0 20px 0 14px; }
.zg-deck-pause svg[hidden] { display: none; }
@media (max-width: 600px) { .zg-deck-pause { grid-column: 1 / -1; } }

/* ================================================================
   Reduced motion: every animation above becomes its finished, still state.
   ================================================================ */
@media (prefers-reduced-motion: reduce) {
  .zg-folding { display: none; }
  .zg-entering { animation: none; }
  .zg-tick, .zg-tick::before, .zg-tick::after { transition: none; }
  .zg-lamp, .zg-lamp-thumb { transition: none; }
  .zg-decision-done { transition: none; }
  .zg-glow::before { animation: none; transform: scale(1.25); opacity: .6; }
  :where(.plan-loading, .planner-loading, .house-loading,
    #records-loading, #ops-loading, #lodging-loading, #checkin-loading, #it-loading, #fl-loading,
    #finance-loading, #plan-loading, #ops-teaching-loading, #ops-publish-loading,
    #command-loading, #memory-loading, #meeting-loading, #v-loading)::before,
  .event-card:where(#loading-card, #pay-loading) .event-card-label::before {
    animation: none; box-shadow: 0 0 14px 5px color-mix(in srgb, var(--zg-accent-bright) 60%, transparent);
  }
  .zg-skel::after { animation: none; display: none; }
  .zg-toast { animation: none; transition: none; }
  .zg-toast-close { transition: none; }
  .zg-nudge { animation: none; }
  .zg-halo::before { animation: none; transition: none; }
  :where(.zg-halo) { transition: none; }
  .zg-check-box, .zg-check-box::before, .zg-check-box::after { transition: none; }
  .zg-burst { display: none; }
  .zg-step.is-leaving, .zg-step.is-entering { animation: none; }
  .zg-stepper-item + .zg-stepper-item::after, .zg-stepper-circle, .zg-stepper-num, .zg-stepper-circle svg,
  .zg-step-back { transition: none; }
  /* Menus, buttons, the bar and the reveal change colour or appear, and nothing travels. */
  .zg-nav-panel, .zg-menu-pop, .zg-menu-chev, .zg-nav-toggle-icon i, .zg-nav-toggle, .zg-nav-link, .zg-menu-btn, .zg-menu-link { transition: none; }
  .zg-sheen, .zg-fill, .public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary, .btn-secondary) {
    transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
  }
  .zg-sheen::after, .public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary)::after { display: none; }
  .zg-sheen:hover, .zg-sheen:active, .zg-fill:hover, .zg-fill:active,
  .public-site :is(.btn-primary, .nav-cta, .pricing-tier-cta, .reserve-bar-btn-primary, .btn-secondary):is(:hover, :active) { transform: none; }
  .zg-arrow, a:hover .zg-arrow, button:hover .zg-arrow { transition: none; translate: none; }
  .zg-bar { transition: none; }
  .zg-bar-link, .zg-bar-go, .zg-bar-close { transition: none; }
  .zg-reveal { opacity: 1; translate: none; scale: 1; transition: none; }
}

@media print {
  .zg-toasts, .zg-burst, .zg-stepper, .zg-step-nav, .zg-deck-controls { display: none !important; }
  /* A deck prints as the plain list it started as. */
  .zg-orbit.zg-orbit, .zg-stagger.zg-stagger { display: block; padding: 0; perspective: none; overflow: visible; }
  .zg-orbit.zg-orbit > .zg-orbit-card.zg-orbit-card[data-slot],
  .zg-stagger.zg-stagger > .zg-stagger-card.zg-stagger-card[data-slot] {
    width: auto; margin: 0 0 16px; transform: none; translate: none; rotate: none; scale: none; opacity: 1; break-inside: avoid;
    color: var(--zg-ink); background: var(--zg-surface);
  }
  .zg-orbit > .zg-orbit-card::after { display: none; }
  .zg-bar, .zg-header .zg-nav-toggle, .zg-header .zg-nav-close { display: none !important; }
  .zg-reveal { opacity: 1 !important; translate: none !important; scale: none !important; }
}

/* ================================================================
   17. One button system for the whole public site (Jordan, 2026-10-11: "nice clean, rounded
   corner, 3D feel, animated selection, glowing buttons across the site"). Every button-like
   thing on a public page, whatever stylesheet first drew it, becomes one of three raised pills:
     gold      the main action: a gold-leaf face, a bevel, a lip underneath, deep ink lettering
     parchment the second action: a light face with a gold edge that warms on hover
     quiet     small actions (Sign out, Register for a gathering): a ghost pill that lights gold
   Each lifts on hover with a soft gold glow, sinks when pressed, and carries a gold ring for
   the keyboard. Choices (option cards, tick boxes, radio buttons, dropdowns, text boxes) glow
   gold when chosen or focused, and a tick or radio pops as it is picked. Links are pinned to
   their own colours here because styles.css turns every link gold on hover, which made a gold
   button's text vanish. Under reduced motion nothing moves; the colours and glows remain.
   ================================================================ */
:root {
  --zg-gold-hi: #F4D486;
  --zg-gold-mid: #D9A645;
  --zg-gold-lo: #B9842A;
  --zg-gold-lip: #7E5513;
  --zg-gold-ink: #22190A;
  --zg-glow: rgb(214 163 66 / 30%);
  --zg-glow-strong: rgb(196 140 40 / 42%);
  --zg-press-ms: 90ms;
  --zg-raise-ms: 220ms;
}

/* ---- gold: the main action ---- */
:is(.public-site, .event-public) :not(#signin-block *):is(.btn-primary, .nav-cta, .reserve-bar-btn-primary, .pricing-tier-cta, .zgf-btn-primary, .btn-small.is-primary),
:is(.public-site, .event-public) :not(#signin-block *):is(a, button).btn-primary {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  border: 1px solid var(--zg-gold-lip) !important; border-radius: 999px !important;
  background: linear-gradient(180deg, var(--zg-gold-hi) 0%, var(--zg-gold-mid) 46%, var(--zg-gold-lo) 100%) !important;
  color: var(--zg-gold-ink) !important; font-weight: 700; letter-spacing: .01em; text-decoration: none !important;
  text-shadow: 0 1px 0 rgb(255 245 214 / 55%);
  box-shadow:
    inset 0 1px 0 rgb(255 252 236 / 85%),
    inset 0 -3px 0 rgb(126 85 19 / 32%),
    0 2px 0 var(--zg-gold-lip),
    0 8px 18px rgb(126 85 19 / 26%) !important;
  transition: transform var(--zg-raise-ms) var(--zg-ease), box-shadow var(--zg-raise-ms) var(--zg-ease), filter var(--zg-raise-ms) ease;
  cursor: pointer;
}
:is(.public-site, .event-public) :not(#signin-block *):is(.btn-primary, .nav-cta, .reserve-bar-btn-primary, .pricing-tier-cta, .zgf-btn-primary, .btn-small.is-primary):is(:hover, :focus-visible),
:is(.public-site, .event-public) :not(#signin-block *):is(a, button).btn-primary:is(:hover, :focus-visible) {
  color: var(--zg-gold-ink) !important; filter: saturate(1.08) brightness(1.03);
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgb(255 252 236 / 90%),
    inset 0 -3px 0 rgb(126 85 19 / 30%),
    0 3px 0 var(--zg-gold-lip),
    0 0 0 4px var(--zg-glow),
    0 14px 30px var(--zg-glow-strong) !important;
}
:is(.public-site, .event-public) :not(#signin-block *):is(.btn-primary, .nav-cta, .reserve-bar-btn-primary, .pricing-tier-cta, .zgf-btn-primary, .btn-small.is-primary):active,
:is(.public-site, .event-public) :not(#signin-block *):is(a, button).btn-primary:active {
  transform: translateY(2px); transition-duration: var(--zg-press-ms);
  box-shadow: inset 0 2px 6px rgb(92 60 12 / 38%), 0 0 0 var(--zg-gold-lip), 0 0 0 3px var(--zg-glow) !important;
}

/* ---- parchment: the second action ---- */
:is(.public-site, .event-public) :not(#signin-block *):is(.btn-secondary, .btn-small:not(.is-primary), .zgf-btn-secondary, .reserve-bar-btn:not(.reserve-bar-btn-primary)),
:is(.public-site, .event-public) :not(#signin-block *):is(a, button).btn-secondary {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  border: 1.5px solid var(--zg-gold-lo) !important; border-radius: 999px !important;
  /* A parchment face, with a gold tint that sweeps in from the left on hover (the first layer). */
  background-image: linear-gradient(90deg, var(--zg-fill), var(--zg-fill)), linear-gradient(180deg, #FFFFFF 0%, #FBF6EA 55%, #F2E7CF 100%) !important;
  background-size: 0% 100%, 100% 100% !important; background-repeat: no-repeat !important; background-position: left center, 0 0 !important;
  color: var(--zg-gold-ink) !important; font-weight: 600; text-decoration: none !important;
  box-shadow:
    inset 0 1px 0 #FFFFFF,
    inset 0 -2px 0 rgb(185 132 42 / 16%),
    0 2px 0 rgb(185 132 42 / 45%),
    0 6px 14px rgb(39 37 31 / 9%) !important;
  transition: transform var(--zg-raise-ms) var(--zg-ease), box-shadow var(--zg-raise-ms) var(--zg-ease), background-size 420ms var(--zg-ease-glide), border-color var(--zg-raise-ms) ease;
  cursor: pointer;
}
:is(.public-site, .event-public) :not(#signin-block *):is(.btn-secondary, .btn-small:not(.is-primary), .zgf-btn-secondary, .reserve-bar-btn:not(.reserve-bar-btn-primary)):is(:hover, :focus-visible),
:is(.public-site, .event-public) :not(#signin-block *):is(a, button).btn-secondary:is(:hover, :focus-visible) {
  color: var(--zg-gold-ink) !important; border-color: var(--zg-gold-mid) !important;
  background-size: 100% 100%, 100% 100% !important;
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 #FFFFFF,
    inset 0 -2px 0 rgb(185 132 42 / 20%),
    0 3px 0 rgb(185 132 42 / 55%),
    0 0 0 4px var(--zg-glow),
    0 12px 26px rgb(185 132 42 / 26%) !important;
}
:is(.public-site, .event-public) :not(#signin-block *):is(.btn-secondary, .btn-small:not(.is-primary), .zgf-btn-secondary, .reserve-bar-btn:not(.reserve-bar-btn-primary)):active,
:is(.public-site, .event-public) :not(#signin-block *):is(a, button).btn-secondary:active {
  transform: translateY(2px); transition-duration: var(--zg-press-ms);
  box-shadow: inset 0 2px 6px rgb(126 85 19 / 22%), 0 0 0 3px var(--zg-glow) !important;
}
:is(.public-site, .event-public) :not(#signin-block *):is(.btn-small, .btn-primary, .btn-secondary)[disabled] { opacity: .55; transform: none; cursor: default; filter: grayscale(.3); }

/* ---- quiet: small actions that used to be bare text ---- */
:is(.public-site, .event-public) :not(#signin-block *):is(.topbar-actions .link-btn, .zg-quiet) {
  display: inline-flex; align-items: center; justify-content: center; gap: .45em; min-height: 46px; padding: 0 20px;
  border: 1.5px solid rgb(185 132 42 / 45%); border-radius: 999px; background: rgb(255 255 255 / 70%);
  color: var(--zg-gold-ink) !important; font: 600 17px/1.2 var(--sans, inherit); text-decoration: none !important; cursor: pointer;
  box-shadow: 0 1px 0 rgb(185 132 42 / 25%), 0 4px 10px rgb(39 37 31 / 6%);
  transition: transform var(--zg-raise-ms) var(--zg-ease), box-shadow var(--zg-raise-ms) var(--zg-ease), background var(--zg-raise-ms) ease, border-color var(--zg-raise-ms) ease;
}
:is(.public-site, .event-public) :not(#signin-block *):is(.topbar-actions .link-btn, .zg-quiet):is(:hover, :focus-visible) {
  border-color: var(--zg-gold-mid); background: linear-gradient(180deg, #FFFDF6, #F6E7C3);
  transform: translateY(-1px); box-shadow: 0 0 0 4px var(--zg-glow), 0 8px 18px rgb(185 132 42 / 22%);
}
:is(.public-site, .event-public) :not(#signin-block *):is(.topbar-actions .link-btn, .zg-quiet):active { transform: translateY(1px); transition-duration: var(--zg-press-ms); }

/* ---- the keyboard's gold ring, on every control ---- */
:is(.public-site, .event-public) :not(#signin-block *):is(a, button, input, select, textarea, summary):focus-visible {
  outline: 3px solid var(--zg-gold-mid); outline-offset: 3px;
}

/* ---- choices: fields, ticks, radios and option cards ---- */
:is(.public-site, .event-public) :not(#signin-block *):is(input:not([type=checkbox]):not([type=radio]):not([type=hidden]), select, textarea) {
  border-radius: 14px; transition: border-color 180ms ease, box-shadow 220ms var(--zg-ease), background-color 180ms ease;
}
:is(.public-site, .event-public) :not(#signin-block *):is(input:not([type=checkbox]):not([type=radio]):not([type=hidden]), select, textarea):focus {
  border-color: var(--zg-gold-mid) !important; box-shadow: 0 0 0 4px var(--zg-glow), 0 4px 14px rgb(185 132 42 / 14%); outline: none;
}
:is(.public-site, .event-public) :not(#signin-block *):is(input[type=checkbox], input[type=radio]) { accent-color: var(--zg-gold-lo); }
:is(.public-site, .event-public) :not(#signin-block *):is(input[type=checkbox], input[type=radio]):checked { animation: zg-pick-pop 320ms var(--zg-ease); }
@keyframes zg-pick-pop { 0% { scale: .7; } 55% { scale: 1.22; } 100% { scale: 1; } }
/* A card that holds a choice (the registration's ways to attend, payment choices) glows and rises when chosen. */
:is(.public-site, .event-public) :not(#signin-block *):is(label, .choice, .option-card, .pay-choice):has(> input:is([type=radio], [type=checkbox])) {
  transition: border-color 200ms ease, box-shadow 260ms var(--zg-ease), transform 260ms var(--zg-ease), background-color 200ms ease;
}
:is(.public-site, .event-public) :not(#signin-block *):is(.choice, .option-card, .pay-choice, .choice-card):has(input:checked) {
  border-color: var(--zg-gold-mid) !important;
  box-shadow: 0 0 0 3px var(--zg-glow), 0 10px 24px rgb(185 132 42 / 20%) !important;
  transform: translateY(-2px);
}

/* ---- the green "signed in" dot on My account (public-enhancements.js adds it) ---- */
.zg-online-dot {
  display: inline-block; flex: none; width: 10px; height: 10px; margin-left: 8px; border-radius: 50%; vertical-align: middle;
  background: radial-gradient(circle at 35% 35%, #7BE0A0, #23944F 70%);
  box-shadow: 0 0 0 2px #FFFFFF, 0 0 6px rgb(35 148 79 / 60%);
  animation: zg-online 2.6s ease-in-out infinite;
}
@keyframes zg-online { 0%, 100% { box-shadow: 0 0 0 2px #FFFFFF, 0 0 4px rgb(35 148 79 / 50%); } 50% { box-shadow: 0 0 0 2px #FFFFFF, 0 0 12px rgb(35 148 79 / 85%); } }

@media (prefers-reduced-motion: reduce) {
  .zg-online-dot { animation: none; }
  :is(.public-site, .event-public) :not(#signin-block *):is(.btn-primary, .btn-secondary, .btn-small, .nav-cta, .reserve-bar-btn, .pricing-tier-cta, .zgf-btn, .topbar-actions .link-btn, .zg-quiet, .choice, .option-card, .pay-choice, .choice-card) {
    transition: none !important; transform: none !important;
  }
  :is(.public-site, .event-public) :not(#signin-block *):is(input[type=checkbox], input[type=radio]):checked { animation: none; }
}
