/* ============================================================
   JOJO — shared chrome, layout primitives and motion.
   Imported by every page after tokens.css.
   ============================================================ */

/* ---- Wrappers ------------------------------------------------------- */
.wrap        { width: 100%; max-width: var(--wrap-wide);      margin-inline: auto; padding-inline: var(--gutter); }
.wrap--std   { max-width: var(--wrap-standard); }
.wrap--ed    { max-width: var(--wrap-editorial); }
.wrap--task  { max-width: var(--wrap-task); }

.section     { padding-block: var(--space-section); }
.section--sm { padding-block: var(--space-section-sm); }
.ground-deep { background: var(--paper-deep); }
/* Dark contexts.
   These REDEFINE the ink tokens rather than targeting elements. A page-level
   rule like `.panel .one-liner { color: var(--ink-muted) }` out-specifies any
   `.ground-dark p` selector we could write, and the result measures 2.23:1 —
   dark text on a dark ground. Remapping the token instead cascades to every
   descendant whatever its selector weight, so a component written once is
   correct on both grounds and cannot regress.

   --accent is deliberately NOT remapped: it stays the CTA fill, where paper
   text on it measures 5.9:1. Accent as *text* on pitch fails, so the spec
   label is pointed at --sand explicitly. */
.ground-dark, .on-dark {
  --ink:         rgba(255, 252, 250, 0.94);
  --ink-strong:  var(--paper);
  --ink-muted:   rgba(255, 252, 250, 0.80);
  --ink-faint:   rgba(255, 252, 250, 0.70);
  --rule:        rgba(255, 252, 250, 0.16);
  --rule-strong: rgba(255, 252, 250, 0.34);
  --paper-deep:  var(--on-dark-fill);
  color: var(--paper);
}
.ground-dark { background: var(--pitch); }
.ground-dark .spec--accent, .on-dark .spec--accent { color: var(--paper-muted); }
.ground-dark a:not(.cta), .on-dark a:not(.cta) { color: var(--paper); }

/* ---- Announcement --------------------------------------------------- */
.announce {
  background: var(--pitch);
  color: var(--paper);
  text-align: center;
  padding: 5px var(--s-3);
  min-height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 100;
}
.announce .spec {
  color: rgba(250, 246, 241, 0.92);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--s-2);
  font-size: 11.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.announce-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  text-decoration: none;
  color: inherit;
  transition: color var(--dur-state) var(--ease-out);
}
.announce-link:hover {
  color: #FFFFFF;
}
.announce-countdown-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: rgba(190, 123, 86, 0.22);
  border: 1px solid rgba(190, 123, 86, 0.45);
  padding: 2px 8px;
  border-radius: var(--r-pill);
  font-size: 11px;
  color: #F8D5C2;
}
.announce-countdown-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #E58B5C;
  box-shadow: 0 0 6px #E58B5C;
  animation: pulse-dot 2s infinite ease-in-out;
}
@keyframes pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.85); }
}
.announce-cta-text {
  font-weight: 700;
  color: var(--paper);
  white-space: nowrap;
}
.announce-arrow {
  display: inline-block;
  margin-left: 2px;
  color: var(--cognac);
  transition: transform var(--dur-move) var(--ease-back);
}
.announce-link:hover .announce-arrow {
  transform: translateX(3px);
}
@media (max-width: 680px) {
  .announce { padding-block: 6px; }
  .announce .spec { font-size: 10px; gap: 4px; line-height: 1.4; }
  .announce-sep--cta { display: none; }
}


/* ---- Spacing utilities ---------------------------------------------- */
.mt-1 { margin-top: var(--s-1); }
.mt-2 { margin-top: var(--s-2); }
.mt-3 { margin-top: var(--s-3); }
.mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); }
.mt-6 { margin-top: var(--s-6); }
.mt-7 { margin-top: var(--s-7); }
.mt-8 { margin-top: var(--s-8); }
.mb-2 { margin-bottom: var(--s-2); }
.mb-4 { margin-bottom: var(--s-4); }
.mb-6 { margin-bottom: var(--s-6); }

/* ---- Color utilities ------------------------------------------------ */
.spec--cognac  { color: var(--cognac); }
.spec--oxblood { color: var(--oxblood); }

/* ---- Nav ------------------------------------------------------------ */
.nav {
  position: sticky; top: 0; z-index: 90;
  background: rgba(250, 246, 241, 0.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
}
.nav[data-stuck="true"] { border-bottom-color: var(--rule-strong); }
.nav-inner {
  height: var(--nav-h);
  width: 100%;
  max-width: var(--wrap-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(16px, 2.5vw, 40px);
}
.logo {
  font-family: var(--font-display);
  font-size: 30px; line-height: 1; letter-spacing: 0.02em;
  color: var(--ink-strong); text-decoration: none;
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: 44px;
  min-width: 44px;
  justify-self: start;
}
.logo-img {
  display: block;
  height: 38px;
  width: auto;
  transition: transform var(--dur-move) var(--ease-back);
}
.logo:hover .logo-img {
  transform: translateY(-2px) scale(1.04);
}
.logo:has(.logo-img)::after {
  display: none;
  content: none;
}
/* The wordmark carries its own circle — fallback if text only */
.logo::after {
  content: ""; width: var(--c-dot-sm); height: var(--c-dot-sm); border-radius: 50%;
  background: var(--cognac); margin-bottom: var(--s-1);
  transition: transform var(--dur-move) var(--ease-back);
}
.logo:hover::after { transform: translateY(-4px) scale(1.25); }

.nav nav[aria-label="Main"] {
  justify-self: center;
}
.nav-links {
  list-style: none;
  display: flex;
  gap: clamp(12px, 1.5vw, 24px);
  padding: 0;
  margin: 0;
}
.nav-links a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-block: var(--s-2);
  font-size: var(--t-small);
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
/* The underline is a dot that travels — the circle doing the work a
   border-bottom would normally do. */
.nav-links a::after {
  content: ""; position: absolute; left: 50%; bottom: -2px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--accent);
  transform: translate(-50%, 4px) scale(0);
  transition: transform var(--dur-move) var(--ease-back);
}
.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after { transform: translate(-50%, 0) scale(1); }

.nav-actions {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: clamp(var(--s-3), 1.5vw, var(--s-5));
}
.quiz-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-block: var(--s-2);
  font-size: var(--t-small);
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
  white-space: nowrap;
}
.quiz-link:hover { border-color: var(--accent); color: var(--accent); }
.nav .cta { min-height: var(--cta-h-compact); padding-inline: var(--s-5); font-size: var(--t-cta); white-space: nowrap; }
.nav-mobile-cta { display: none; }

.menu-btn {
  display: none;
  width: 44px; height: 44px; margin-left: auto; margin-right: -8px;
  align-items: center; justify-content: center;
  background: none; border: none; color: var(--ink); cursor: pointer;
}

/* ---- Mobile drawer -------------------------------------------------- */
.drawer {
  display: none;
  border-top: 1px solid var(--rule);
  background: var(--paper);
}
.drawer ul { list-style: none; padding: var(--s-3) var(--gutter) var(--s-6); margin: 0; }
.drawer a {
  display: flex; align-items: center; gap: var(--s-3);
  min-height: 52px;
  font-family: var(--font-display); font-size: 26px; letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--ink-strong); text-decoration: none;
  border-bottom: 1px solid var(--rule);
}
.drawer li:not(.drawer-cta-li):last-child a { border-bottom: 0; }

/* Mobile Drawer CTA Button */
.drawer .drawer-cta-li {
  margin-top: var(--s-5);
  padding-top: var(--s-2);
  border-bottom: 0 !important;
}
.drawer .drawer-cta-li a.cta {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  width: 100% !important;
  min-height: 52px !important;
  padding: 0 var(--s-6) !important;
  border-radius: var(--r-pill) !important;
  background: var(--accent) !important;
  color: #FAF6F1 !important; /* Visible light cream text on brown */
  font-family: var(--font-label) !important;
  font-size: 13px !important;
  font-weight: 700 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  text-decoration: none !important;
  border: none !important;
  box-shadow: 0 4px 16px rgba(138, 90, 59, 0.28) !important;
  transition: background var(--dur-state) var(--ease-out), transform var(--dur-tap) var(--ease-out) !important;
}
.drawer .drawer-cta-li a.cta span {
  color: #FAF6F1 !important;
}
.drawer .drawer-cta-li a.cta:hover {
  background: var(--accent-deep, #73482D) !important;
  color: #FFFFFF !important;
}
.drawer .drawer-cta-li a.cta:hover span {
  color: #FFFFFF !important;
}
.drawer .drawer-cta-li a.cta:active {
  transform: scale(0.98) !important;
}

@media (max-width: 1024px) {
  .nav-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .nav-links, .nav nav[aria-label="Main"], .nav-actions { display: none; }
  .nav-mobile-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 36px;
    padding: 0 16px;
    margin-left: auto;
    margin-right: 8px;
    background: var(--accent);
    color: #FAF6F1 !important;
    font-family: var(--font-label);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none !important;
    border: none;
    border-radius: var(--r-pill);
    box-shadow: 0 2px 10px rgba(138, 90, 59, 0.28);
    white-space: nowrap;
    line-height: 1;
    transition: background var(--dur-state) var(--ease-out), transform var(--dur-tap) var(--ease-out);
  }
  .nav-mobile-cta:hover {
    background: var(--accent-deep, #73482D);
    color: #FFFFFF !important;
    text-decoration: none !important;
  }
  .nav-mobile-cta:active {
    transform: scale(0.96);
  }
  .menu-btn { display: inline-flex; margin-left: 0; }
  .drawer {
    display: block;
    max-height: 0;
    overflow: hidden;
    transition: max-height var(--dur-move) var(--ease-inout), box-shadow var(--dur-move) ease;
    border-bottom: 1px solid transparent;
  }
  .drawer.open {
    max-height: 85vh;
    overflow-y: auto;
    border-bottom: 1px solid var(--rule);
    box-shadow: 0 16px 36px rgba(28, 28, 28, 0.12);
  }
}

/* ---- Footer --------------------------------------------------------- */
footer.site {
  background: var(--pitch); color: rgba(250, 246, 241, 0.72);
  padding: var(--space-section-sm) 0 var(--s-7);
}
footer.site .logo { color: var(--paper); font-size: 34px; min-height: 44px; display: inline-flex; align-items: center; }
footer.site .logo-img { height: 48px; width: auto; }
footer.site .logo::after { background: var(--cognac); }
.foot-inner {
  max-width: var(--wrap-wide); margin-inline: auto; padding-inline: var(--gutter);
  display: grid; grid-template-columns: 2.2fr 1fr 1.15fr 1.15fr; gap: var(--s-8);
}
.foot-inner > div > p { margin-top: var(--s-4); max-width: 36ch; font-size: var(--t-small); line-height: 1.6; color: var(--ink-muted); }
.foot-col ul { list-style: none; padding: 0; margin-top: var(--s-3); display: grid; gap: var(--s-1); }
.foot-col a {
  display: inline-flex; align-items: center; min-height: 44px;
  padding-block: 4px;
  color: rgba(250, 246, 241, 0.82); text-decoration: none; font-size: var(--t-small);
}
.foot-col a:hover { color: var(--paper); text-decoration: underline; text-underline-offset: 3px; }
.foot-base {
  max-width: var(--wrap-wide); margin: var(--s-8) auto 0; padding-inline: var(--gutter);
  padding-top: var(--s-5); border-top: 1px solid var(--rule-dark);
  display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-6); justify-content: space-between;
  align-items: center;
}
.foot-base .spec { font-size: var(--t-caption); }
@media (max-width: 768px) {
  .foot-inner { grid-template-columns: 1fr 1fr; gap: var(--s-7); }
  .foot-inner > div:first-child { grid-column: 1 / -1; }
}

/* ---- Charm portrait -------------------------------------------------
   The brand's own dog illustration, held inside a circle from the series.
   This is the site's primary image object: a dog drawn out of circles,
   inside a circle. */
.charm {
  position: relative; border-radius: 50%; overflow: hidden; flex: none;
  aspect-ratio: 1;
  background: var(--cream);
  display: grid; place-items: center;
  isolation: isolate;
  width: 100%; height: 100%;
}
.charm img {
  width: 100%; height: 100%;
  max-width: 66%; max-height: 66%;
  object-fit: contain;
  display: block;
}
.charm img[src*="puppy"]       { max-width: 72%; max-height: 62%; }
.charm img[src*="husky"]         { max-width: 72%; max-height: 66%; }
.charm img[src*="cohort-female"] { max-width: 72%; max-height: 66%; }
.charm img[src*="cohort-male"]   { max-width: 72%; max-height: 66%; }
.charm img[src*="cohort-puppy"]  { max-width: 72%; max-height: 66%; }


/* ---- Duotone plate & circle -----------------------------------------
   A real photograph, on the brand's ramp. Never a rounded card — it is a
   plate on the page, and it may be masked into a circle. */
.plate { position: relative; overflow: hidden; background: var(--paper-deep); }
.plate img { width: 100%; height: 100%; object-fit: cover; }
.plate--circle {
  border-radius: 50%;
  aspect-ratio: 1;
  width: var(--c-2);
}
.plate--circle.c1 { width: var(--c-1); }
.plate--circle.c2 { width: var(--c-2); }
.plate--circle.c3 { width: var(--c-3); }
.plate--circle.c4 { width: var(--c-4); }
.plate--circle.c5 { width: var(--c-5); }
.plate--circle.c6 { width: var(--c-6); }

/* ---- Disc utility family --------------------------------------------
   The circle is the atom. Every diameter comes from the --c-* series or .dot.
   Solid fills and hard edges only. No shadows, gradients, or opacity. */
.disc {
  border-radius: 50%;
  aspect-ratio: 1;
  flex: none;
  display: grid;
  place-items: center;
  position: relative;
  box-sizing: border-box;
}

/* Size modifiers */
.disc.c1 { width: var(--c-1); height: var(--c-1); }
.disc.c2 { width: var(--c-2); height: var(--c-2); }
.disc.c3 { width: var(--c-3); height: var(--c-3); }
.disc.c4 { width: var(--c-4); height: var(--c-4); }
.disc.c5 { width: var(--c-5); height: var(--c-5); }
.disc.c6 { width: var(--c-6); height: var(--c-6); }
.disc.c7 { width: var(--c-7); height: var(--c-7); }
.disc.c8 { width: var(--c-8); height: var(--c-8); }
.disc.c9 { width: var(--c-9); height: var(--c-9); }
.disc.dot-lg { width: var(--c-dot-lg); height: var(--c-dot-lg); }
.disc.dot    { width: var(--c-dot);    height: var(--c-dot); }
.disc.dot-sm { width: var(--c-dot-sm); height: var(--c-dot-sm); }

/* Fill modifiers */
.disc--pitch   { background: var(--pitch); color: var(--paper); }
.disc--paper   { background: var(--paper); color: var(--pitch); }
.disc--oxblood { background: var(--oxblood); color: var(--paper); }
.disc--cognac  { background: var(--cognac); color: var(--paper); }
.disc--tan     { background: var(--tan); color: var(--paper); }
.disc--tan svg { fill: var(--paper); color: var(--paper); }
.disc--deep    { background: var(--paper-deep); color: var(--ink); }

/* Special state modifiers */
.disc--ring {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--rule-strong);
}

.disc--inner-ring {
  position: relative;
}
.disc--inner-ring::before {
  content: "";
  position: absolute;
  inset: 14%;
  border-radius: 50%;
  border: 2px solid var(--paper);
  pointer-events: none;
}

.disc--blocked {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--rule-strong);
  position: relative;
  overflow: hidden;
}
.disc--blocked::after {
  content: "";
  position: absolute;
  top: 50%;
  left: -10%;
  width: 120%;
  height: 1px;
  background: var(--rule-strong);
  transform: translateY(-50%) rotate(45deg);
  pointer-events: none;
}

.disc--beads {
  background-image: url('img/art/beads.svg');
  /* NOT `contain`: beads.svg is a 240px field at pitch 8, so a --c-6 (84px)
     disc shrinks each bead to ~1px and the field reads as a solid tan fill —
     and a solid disc already means LOCKED. Status would then be carried by
     colour alone, which design law 4 forbids. Showing 1/4 of the field holds
     ~9 beads across at every step of the series. The trade: bead pitch scales
     with the disc instead of staying at the charm's absolute pitch. */
  background-size: 400%;
  background-repeat: no-repeat;
  background-position: center;
}

/* ---- Photo tier ------------------------------------------------------
   Full color natural photography per updated creative direction. */
.duotone {
  position: relative;
  overflow: hidden;
}
.duotone img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.duotone::after,
.duotone--pitch::after {
  display: none;
}

/* ---- Ratio & Entity Icons ------------------------------------------ */
.icon-dog,
.icon-handler {
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
}
.icon-dog {
  color: var(--accent);
}
.disc--tan .icon-dog {
  color: var(--paper);
  fill: var(--paper);
}
.disc--pitch .icon-dog,
.on-dark .icon-dog,
.ground-dark .icon-dog {
  color: var(--paper);
  fill: var(--paper);
}
.icon-handler {
  color: var(--ink-strong);
  stroke: currentColor;
}
.disc--pitch .icon-handler,
.on-dark .icon-handler,
.ground-dark .icon-handler {
  color: var(--paper);
  stroke: var(--paper);
}

.icon-female,
.cohort-female-icon {
  color: var(--cohort-female);
}
.icon-male,
.cohort-male-icon {
  color: var(--cohort-male);
}

/* ---- Cohort Identity Emblem Marks (Female / Male) ---------------- */
.cohort-mark,
.fill-mark {
  width: var(--mark-size, 180px);
  height: var(--mark-size, 180px);
  border-radius: 50%;
  background: var(--paper);
  border: 1.5px solid var(--rule-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 18px rgba(42, 30, 24, 0.05);
  overflow: hidden;
  margin-inline: auto;
  transition: transform var(--dur-state) var(--ease-out), box-shadow var(--dur-state) var(--ease-out);
  flex-shrink: 0;
}
.cohort-mark:hover,
.fill-mark:hover {
  transform: scale(1.03);
  box-shadow: 0 8px 24px rgba(42, 30, 24, 0.08);
}
.cohort-mark--female,
.fill-mark--female {
  border-color: var(--cohort-female-border);
}
.cohort-mark--male,
.fill-mark--male {
  border-color: var(--cohort-male-border);
}
.cohort-mark--puppy,
.fill-mark--puppy {
  border-color: var(--rule-strong);
}
.cohort-mark__img,
.fill-mark__img,
.cohort-mark .charm__knockout,
.fill-mark .charm__knockout {
  width: 86%;
  height: 86%;
  object-fit: contain;
  display: block;
}

.cohort-mark--sm {
  --mark-size: 72px;
}
.cohort-mark--portrait {
  --mark-size: 180px;
}
.hero-inner__discs .cohort-mark {
  --mark-size: 130px;
}
.register__disc.cohort-mark {
  --mark-size: 96px;
}
.split__graphic {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
}
.split__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  margin-top: var(--s-5);
}

.plate figcaption,
.plate-caption {
  margin-top: var(--s-3);
  display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5); justify-content: space-between;
}


/* ---- Spec row — real numbers, in the label voice --------------------- */
.spec-row {
  display: flex; flex-wrap: wrap; gap: var(--s-5) var(--s-8);
  padding-top: var(--s-5); border-top: 1px solid var(--rule);
}
.spec-item strong {
  display: block; margin-top: var(--s-2);
  font-family: var(--font-display); font-weight: 400; font-size: 40px;
  line-height: 1; color: var(--ink-strong);
}
.spec-item p { font-size: 14px; color: var(--ink-muted); margin-top: var(--s-2); max-width: 30ch; }

/* ---- Motion ----------------------------------------------------------
   One utility, two axes. Sections opt in with data-reveal; children stagger
   with --i. Delays overlap (90ms against a 520ms reveal) so the next element
   is already moving before the previous settles — sequential fade-up at one
   uniform duration is the template-demo signature. */
/* Scoped to .js (set by an inline script in <head>) so that without
   JavaScript — or if the script fails — every element is simply visible.
   Content must never be able to get stuck at opacity 0. */
[data-reveal] { --i: 0; }
.js [data-reveal] > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--dur-reveal) var(--ease-out),
              transform var(--dur-reveal) var(--ease-out);
}
.js [data-reveal].in > * { opacity: 1; transform: none; }
[data-reveal].in > *:nth-child(1) { transition-delay: 0ms; }
[data-reveal].in > *:nth-child(2) { transition-delay: 90ms; }
[data-reveal].in > *:nth-child(3) { transition-delay: 165ms; }
[data-reveal].in > *:nth-child(4) { transition-delay: 230ms; }
[data-reveal].in > *:nth-child(5) { transition-delay: 285ms; }
[data-reveal].in > *:nth-child(n+6) { transition-delay: 330ms; }

/* Circles enter by scaling from their own centre — the brand's unit
   assembling, not a generic fade. */
.js [data-pop] { opacity: 0; transform: scale(0.72); transition: opacity var(--dur-move) var(--ease-out), transform var(--dur-reveal) var(--ease-back); }
.js [data-pop].in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] > *, .js [data-pop] { opacity: 1 !important; transform: none !important; }
}

/* ---- Pending note — honest about what is not decided yet ------------- */
.pending {
  border-left: 2px solid var(--cognac);
  padding: var(--s-4) 0 var(--s-4) var(--s-5);
  background: linear-gradient(90deg, rgba(176, 118, 63, 0.06), transparent 60%);
}

/* ---- Copy law & bracket register (P1.6) ----------------------------- */
mark.todo {
  background-color: var(--cream);
  color: var(--oxblood);
  /* The cream fill is near-invisible on --paper-deep (#F4E3D3 on #F2E5D7),
     so brackets vanished in QA screenshots on every deep-ground section.
     The rule carries the flag on any ground. */
  border-bottom: 1px solid var(--oxblood);
  padding-block: 0;
  padding-inline: 2px;
  font-weight: inherit;
}


/* ============================================================
   ACCESSIBLE FAQ ACCORDION
   ============================================================ */
.faq-list {
  border-top: 1px solid var(--rule-strong);
  list-style: none;
  padding: 0;
  margin-top: var(--s-6);
}
.faq-body {
  padding-bottom: var(--s-6);
  padding-right: var(--s-8);
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--ink-muted);
}
.faq-body p + p {
  margin-top: var(--s-3);
}

/* ---- Cohort Badges & Mutual-Exclusion UI ----------------------------- */
.badge-cohort {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-label);
  font-size: var(--t-spec);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-pill);
  line-height: 1.2;
}
.badge-cohort--male {
  color: var(--cohort-male);
  background: var(--cohort-male-bg);
  border: 1px solid var(--cohort-male-border);
}
.badge-cohort--female {
  color: var(--cohort-female);
  background: var(--cohort-female-bg);
  border: 1px solid var(--cohort-female-border);
}
.badge-cohort--open {
  color: var(--cohort-open);
  background: var(--cohort-open-bg);
  border: 1px solid var(--cohort-open-border);
}
.badge-cohort--locked {
  color: var(--cohort-locked);
  background: var(--cohort-locked-bg);
  border: 1px solid rgba(138, 37, 37, 0.28);
}
.badge-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

/* ---- Close band partial (P1.4) --------------------------------------
   Dark closing CTA band on --pitch ground.
   No background photo, no gradient, no box-shadow, no centered stack.
   Two columns on >=900px; left: label voice eyebrow + --d-2 Bebas heading;
   right, bottom-aligned: one .cta only; far right: .disc.c5.disc--paper.
   Under 900px: single column, disc hidden. */


/* ============================================================
   SECTION GRAMMAR — the only section shapes on the site (P1.7)
   ============================================================ */

/* TODO: Remove .cohort-card, .rule-card, .vision-lens-console, .hero-plate, and any *-card class from all CSS once Phase 2–3 stop using them */

/* .sec — section wrapper: padding-block var(--space-section); .sec--sm uses --space-section-sm. Grounds via existing .ground-deep / .ground-dark.on-dark. */
.sec {
  padding-block: var(--space-section);
  position: relative;
  width: 100%;
}
.sec--sm {
  padding-block: var(--space-section-sm);
}

/* .sec-head — grid: label voice eyebrow (ONLY when it carries data; otherwise omit the element) above an h2.display at --d-2, optional lead at --t-lead with max-width --wrap-editorial. Left aligned. Never centered. */
.sec-head {
  display: grid;
  gap: var(--s-3);
  text-align: left;
  margin-bottom: var(--s-7);
}
.sec-head .spec,
.sec-head .eyebrow {
  text-align: left;
}
.sec-head .display,
.sec-head h2.display {
  font-family: var(--font-display);
  font-size: var(--d-2);
  line-height: 1.04;
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  color: var(--ink-strong);
  margin: 0;
  text-align: left;
  text-wrap: balance;
}
.on-dark .sec-head .display,
.on-dark .sec-head h2.display {
  color: var(--paper);
}
.sec-head .lead {
  font-family: var(--font-body);
  font-size: var(--t-lead);
  line-height: var(--lh-body);
  max-width: var(--wrap-editorial);
  color: var(--ink-muted);
  margin: 0;
  text-align: left;
  text-wrap: pretty;
}
.on-dark .sec-head .lead {
  color: var(--paper-muted);
}

/* .split — two-column 7/5 grid at ≥900px (text 7, graphic 5), gap var(--s-8); .split--flip puts graphic left. Single column below. This is the ONLY text+image shape. */
.split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-6);
  align-items: start;
}
@media (min-width: 1024px) {
  .split {
    grid-template-columns: 7fr 5fr;
    gap: var(--s-8);
  }
  .split--flip {
    grid-template-columns: 5fr 7fr;
  }
}

/* .register — two explicit variants, never an implied one.
   .register--rows: a vertical list where each row is [disc][hairline leader][label voice spec][title + one line].
   .register--axis: N discs on one horizontal axis, equal gaps of var(--c-6), captions beneath each, wrapping to .register--rows under 560px. Disc sizes carry information via .c2…c8. */
.register--axis {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--c-6);
  align-items: start;
  list-style: none;
  padding: 0;
  margin: 0;
  width: 100%;
}
.register--axis .register__item {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  flex: 0 0 auto;
}
.register--axis .register__caption {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  max-width: 22ch;
}
.register--axis .register__title {
  font-family: var(--font-display);
  font-size: var(--d-4, 28px);
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--ink-strong);
  margin: 0;
}
.on-dark .register--axis .register__title {
  color: var(--paper);
}
.register--axis .register__desc {
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--ink-muted);
  margin: 0;
}
.on-dark .register--axis .register__desc {
  color: var(--paper-muted);
}
@media (max-width: 1024px) and (min-width: 601px) {
  .register--axis {
    flex-wrap: wrap;
    gap: var(--s-6);
  }
}
@media (max-width: 600px) {
  .register--axis {
    flex-direction: column;
    gap: var(--s-5);
  }
  .register--axis .register__item {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--s-4);
    align-items: start;
    width: 100%;
  }
}

.register--rows {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  list-style: none;
  padding: 0;
  margin: 0;
  width: 100%;
}
.register--rows .register__row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3) var(--s-5);
  align-items: start;
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--rule);
}
.register--rows .register__disc {
  grid-row: 1 / 3;
}
.register--rows .register__meta {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  min-width: 0;
}
.register--rows .register__leader {
  flex: 1 1 auto;
  border-bottom: 1px solid var(--rule);
  min-width: 16px;
}
.register--rows .register__spec {
  font-family: var(--font-label);
  font-size: var(--t-spec);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  white-space: normal;
}
.on-dark .register--rows .register__spec {
  color: var(--paper-muted);
}
.register--rows .register__body {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  min-width: 0;
}
@media (max-width: 600px) {
  .register--rows .register__row {
    gap: var(--s-2) var(--s-3);
  }
  .register--rows .disc {
    width: var(--c-6);
    height: var(--c-6);
  }
  .register--rows .register__leader {
    display: none;
  }
}
.register--rows .register__title {
  font-family: var(--font-display);
  font-size: var(--d-4, 28px);
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--ink-strong);
  margin: 0;
}
.on-dark .register--rows .register__title {
  color: var(--paper);
}
.register--rows .register__desc {
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--ink-muted);
  margin: 0;
}
.on-dark .register--rows .register__desc {
  color: var(--paper-muted);
}

/* .ledger — rule-held key/value column (existing booking summary pattern): hairline top rule, rows of label voice key + Noto value, no fill, no border. Replaces every card. */
.ledger {
  border-top: 1px solid var(--rule);
  list-style: none;
  padding: 0;
  margin: 0;
  background: none;
  border-left: none;
  border-right: none;
  width: 100%;
}
.ledger__row,
.ledger-row {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: var(--s-3) var(--s-4);
  padding-block: var(--s-3);
  border-bottom: 1px solid var(--rule);
  align-items: baseline;
}
@media (max-width: 600px) {
  .ledger__row,
  .ledger-row {
    grid-template-columns: 1fr;
    gap: var(--s-1);
  }
}
.ledger--wide .ledger__row,
.ledger--wide .ledger-row {
  grid-template-columns: minmax(200px, 340px) 1fr;
}
@media (max-width: 768px) {
  .ledger--wide .ledger__row,
  .ledger--wide .ledger-row {
    grid-template-columns: 1fr;
    gap: var(--s-1);
  }
}
.ledger__key,
.ledger-key {
  font-family: var(--font-label);
  font-size: var(--t-spec);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.on-dark .ledger__key,
.on-dark .ledger-key {
  color: var(--paper-muted);
}
.ledger__val,
.ledger-val {
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--ink-strong);
}
.on-dark .ledger__val,
.on-dark .ledger-val {
  color: var(--paper);
}

/* .trio — three real facts in a row: each is a big Bebas number at --d-3 above a label-voice caption. Max one per page. Never four. */
.trio {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-6);
  padding-block: var(--s-5);
  list-style: none;
  margin: 0;
  padding-inline: 0;
  width: 100%;
}
@media (max-width: 600px) {
  .trio {
    grid-template-columns: 1fr;
    gap: var(--s-5);
  }
}
.trio__item {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}
.trio__num {
  font-family: var(--font-display);
  font-size: var(--d-3);
  line-height: 1;
  color: var(--ink-strong);
}
.on-dark .trio__num {
  color: var(--paper);
}
.trio__caption {
  font-family: var(--font-label);
  font-size: var(--t-spec);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.on-dark .trio__caption {
  color: var(--paper-muted);
}

/* .dotrule — a horizontal dotted rule built from --c-dot-sm discs at --s-5 spacing.
   .dotrule--gap punches a gap of var(--c-6) into it at inline-start offset var(--c-2) measured from the wrap's content edge (so on home it sits under the gap between the hero discs). It is the section boundary at EVERY seam, including ground changes: the gap in the rule is the split restated, the site's one structural device. The gap carries a label-voice count only when there is something at that boundary the reader could count; otherwise the gap is unlabelled. */
.dotrule {
  display: flex;
  align-items: center;
  width: 100%;
  height: var(--c-dot-sm);
  color: var(--rule-strong);
  margin-block: var(--s-6);
  position: relative;
  overflow: hidden;
}
.on-dark .dotrule {
  color: var(--paper-muted);
}
.dotrule::before,
.dotrule--gap::before {
  content: "";
  display: block;
  flex: 1 1 100%;
  width: 100%;
  height: var(--c-dot-sm);
  background-image: radial-gradient(circle at 4px 4px, currentColor 4px, transparent 4.5px);
  background-size: var(--s-5) var(--c-dot-sm);
  background-repeat: repeat-x;
  background-position: left center;
  margin-right: 0;
}
.dotrule--gap::after {
  display: none;
}
.dotrule__count {
  font-family: var(--font-label);
  font-size: var(--t-spec);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  position: absolute;
  left: var(--c-2);
  padding-inline: var(--s-2);
  background: var(--paper);
  text-align: center;
  pointer-events: none;
}
.on-dark .dotrule__count,
.ground-dark .dotrule__count {
  color: var(--paper-muted);
  background: var(--pitch);
}
.ground-deep .dotrule__count {
  background: var(--paper-deep);
}
@media (max-width: 768px) {
  .dotrule__count {
    left: var(--c-4);
  }
}

/* .faq — hairline-separated <details><summary> rows (native disclosure, no JS), summary min-height 56px, marker replaced by a --c-dot disc that turns oxblood when open. */
.faq {
  border-top: 1px solid var(--rule);
  width: 100%;
  list-style: none;
  padding: 0;
  margin: 0;
}
.faq details {
  border-bottom: 1px solid var(--rule);
}
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 56px;
  padding-block: var(--s-3);
  cursor: pointer;
  list-style: none;
  font-family: var(--font-body);
  font-size: var(--t-body-lg, 18px);
  font-weight: 600;
  color: var(--ink-strong);
  user-select: none;
}
.faq summary::-webkit-details-marker,
.faq summary::marker {
  display: none;
  content: "";
}
.faq summary::after {
  content: "";
  display: block;
  flex: none;
  width: var(--c-dot);
  height: var(--c-dot);
  border-radius: 50%;
  background-color: var(--ink-muted);
  transition: background-color var(--dur-state) var(--ease-out);
}
.faq details[open] > summary::after {
  background-color: var(--oxblood);
}
.faq .faq-content,
.faq .faq__content,
.faq details > p,
.faq details > div {
  padding-bottom: var(--s-5);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--ink-muted);
  max-width: var(--wrap-editorial);
}
.on-dark .faq summary {
  color: var(--paper);
}
.on-dark .faq summary::after {
  background-color: var(--paper-muted);
}
.on-dark .faq details[open] > summary::after {
  background-color: var(--oxblood);
}
.on-dark .faq .faq-content,
.on-dark .faq details > p,
.on-dark .faq details > div {
  color: var(--paper-muted);
}

/* .text-link — an inline Noto link in --accent with a 1px underline offset 3px, min-height 24px; the only non-button link style. */
.text-link {
  font-family: var(--font-body);
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  transition: color var(--dur-state) var(--ease-out);
}
.text-link:hover {
  color: var(--oxblood);
}
.on-dark .text-link {
  color: var(--paper);
}
.on-dark .text-link:hover {
  color: var(--cream);
}

/* .spec-row — a <ul> of label-voice facts separated by " · " (via ::before on li+li), wrapping to two columns under 560px. */
ul.spec-row,
.spec-row {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-3);
  font-family: var(--font-label);
  font-size: var(--t-spec);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  border-top: none;
}
.on-dark ul.spec-row,
.on-dark .spec-row {
  color: var(--paper-muted);
}
ul.spec-row > li,
.spec-row > li {
  display: inline-flex;
  align-items: center;
}
ul.spec-row > li + li::before,
.spec-row > li + li::before {
  content: "·";
  margin-right: var(--s-3);
  color: var(--rule-strong);
}
@media (max-width: 600px) {
  ul.spec-row,
  .spec-row {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--s-3);
  }
  ul.spec-row > li + li::before,
  .spec-row > li + li::before {
    display: none;
  }
}
/* Legacy .spec-item fallback */
.spec-row > .spec-item strong {
  display: block; margin-top: var(--s-2);
  font-family: var(--font-display); font-weight: 400; font-size: 40px;
  line-height: 1; color: var(--ink-strong);
}
.spec-row > .spec-item p { font-size: 14px; color: var(--ink-muted); margin-top: var(--s-2); max-width: 30ch; }

/* ============================================================
   HERO GRAMMAR (P1.8 / P3.1)
   The text column is identical on every inner page. The graphic
   column carries one disc per thing the page is about (sessions 2,
   park 4, puppy 1, people 3, FAQ 0). Cardinality is information;
   nothing else in the hero varies.
   ============================================================ */
.hero-inner {
  padding-block: var(--space-section-sm) var(--space-section);
  position: relative;
  width: 100%;
}
.hero-inner__grid {
  max-width: var(--wrap-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-7);
  align-items: center;
}
@media (min-width: 1024px) {
  .hero-inner__grid {
    grid-template-columns: 1fr auto;
    gap: clamp(32px, 5vw, 64px);
    align-items: center;
  }
}
.hero-inner__text {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  align-items: flex-start;
}
.hero-inner__eyebrow {
  font-family: var(--font-label);
  font-size: var(--t-spec);
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--accent);
}
.hero-inner__h1,
.hero-inner h1.display {
  font-family: var(--font-display);
  font-size: var(--d-hero-sub);
  line-height: 1.02;
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  color: var(--ink-strong);
  margin: 0;
  max-width: 100%;
  text-wrap: balance;
}
.hero-inner__lead,
.hero-inner .lead {
  font-family: var(--font-body);
  font-size: var(--t-lead);
  line-height: var(--lh-body);
  color: var(--ink-muted);
  max-width: 100%;
  margin: 0;
  text-wrap: balance;
}
.hero-inner__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  margin-top: var(--s-2);
}
@media (max-width: 600px) {
  .hero-inner__actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }
}
.hero-inner__discs {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: clamp(24px, 3.5vw, 48px);
  list-style: none;
  padding: 0;
  margin: 0;
  width: 100%;
}
.hero-inner__discs > li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  text-align: center;
  flex-shrink: 0;
  min-width: 0;
}
.hero-inner__discs .spec {
  display: block;
  text-align: center;
  font-family: var(--font-label);
  font-size: var(--t-spec);
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-faint);
  line-height: 1.35;
  overflow-wrap: break-word;
  word-break: break-word;
}
@media (min-width: 1024px) {
  .hero-inner__discs {
    margin-top: 0;
    justify-content: flex-end;
  }
  .hero-inner__discs > li {
    min-width: 150px;
  }
  .hero-inner__discs .disc.c2 { width: var(--c-4); height: var(--c-4); }
  .hero-inner__discs .disc.c3 { width: var(--c-5); height: var(--c-5); }
  .hero-inner__discs .disc.c4 { width: var(--c-6); height: var(--c-6); }
  .hero-inner__discs .disc.c5 { width: var(--c-7); height: var(--c-7); }
  .hero-inner__discs .disc.c6 { width: var(--c-8); height: var(--c-8); }
}
@media (max-width: 1024px) {
  .hero-inner__discs {
    justify-content: center;
    margin-top: var(--s-5);
    gap: var(--c-7);
  }
  /* Stepped down one notch on one centred axis */
  .hero-inner__discs .disc.c2 { width: var(--c-3); height: var(--c-3); }
  .hero-inner__discs .disc.c3 { width: var(--c-4); height: var(--c-4); }
  .hero-inner__discs .disc.c4 { width: var(--c-5); height: var(--c-5); }
  .hero-inner__discs .disc.c5 { width: var(--c-6); height: var(--c-6); }
  .hero-inner__discs .disc.c6 { width: var(--c-7); height: var(--c-7); }
}
@media (max-width: 600px) {
  .hero-inner__discs {
    gap: var(--s-3);
  }
  .hero-inner__discs > li {
    max-width: 120px;
  }
  .hero-inner__discs .cohort-mark {
    --mark-size: 80px;
  }
}
.hero-inner__rule {
  border: 0;
  border-top: 1px solid var(--rule);
  color: var(--rule);
  width: calc(100% - 2 * var(--gutter));
  max-width: calc(var(--wrap-wide) - 2 * var(--gutter));
  margin-inline: auto;
  margin-block: var(--s-6) var(--s-4);
}
.hero-inner__footer {
  width: 100%;
  max-width: var(--wrap-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ============================================================
   .lockstate — the cohort lock drawn as a state machine (P2.3)
   ------------------------------------------------------------
   One drawing, three places: home ("The fear, answered", vertical),
   sessions #lock (P3.3, horizontal with sequence numbers), booking
   (P5.4, the slot row states). Built once here so the marketing site
   and the operating software are visibly the same system.

   MARKUP CONTRACT — the component is an ordered list, because the
   states ARE a sequence (a slot opens, then locks, then only matching
   dogs are offered it). Only .lockstate__mark is required on a state.

     <ol class="lockstate" aria-label="How one slot resolves">
       <li class="lockstate__state">
         <span class="lockstate__seq spec">01</span>          OPTIONAL
         <span class="lockstate__mark"><span class="disc c6 disc--beads"></span></span>
         <span class="lockstate__label spec">Open</span>      OPTIONAL
         <p class="lockstate__note">One sentence.</p>         OPTIONAL
       </li>
       … two more states …
     </ol>

   AXIS
     default          vertical: mark left, seq/label/note right.
     .lockstate--x    horizontal from 900px up (seq above the mark,
                      label and note below); vertical below 900px, so a
                      consumer never needs its own media query.

   DISC SIZE
     --lockstate-mark must name the SAME --c-* token as the .disc.cN
     inside .lockstate__mark; the leaders are drawn from it.
     .lockstate--c5 / --c6 (default) / --c7 set the pair together.
     --lockstate-gap is the distance between states and steps with the
     series, so the leader length is always a series measurement.

   LEADERS
     A hairline runs along the axis from each mark to the next, drawn as
     a flex child of .lockstate__mark that fills the remaining track and
     reaches across the gap by a negative margin. The last state has no
     leader, so the drawing never overflows its container.

   STATES ARE DRAWN, NEVER COLOURED (design law 4): open = .disc--beads,
   locked female = .disc--pitch, locked male = .disc--pitch.disc--inner-ring,
   blocked / offered elsewhere = .disc--ring, current = .disc--oxblood.
   The words in .lockstate__label carry the difference.
   ============================================================ */
.lockstate {
  --lockstate-mark: var(--c-6);
  --lockstate-gap: var(--c-8);
  display: grid;
  grid-auto-flow: row;
  gap: 0; /* on the vertical axis the leader IS the gap; see below */
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
}
.lockstate--c5 { --lockstate-mark: var(--c-5); }
.lockstate--c6 { --lockstate-mark: var(--c-6); }
.lockstate--c7 { --lockstate-mark: var(--c-7); }

.lockstate__state {
  display: grid;
  grid-template-columns: var(--lockstate-mark) minmax(0, 1fr);
  column-gap: var(--s-4);
  row-gap: var(--s-1);
  align-items: start;
}

.lockstate__mark {
  grid-column: 1;
  grid-row: 1 / -1;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
}

/* The hairline leader. On the vertical axis the states abut (gap 0) and the
   leader carries the whole distance, so it is never shorter than
   --lockstate-gap and stretches if the caption beside it runs longer. The
   last state has no leader, so the drawing never overruns its container. */
.lockstate__state:not(:last-child) > .lockstate__mark::after {
  content: "";
  display: block;
  flex: 1 1 auto;
  width: 1px;
  min-height: var(--lockstate-gap);
  background: var(--rule-strong);
}
.on-dark .lockstate__state:not(:last-child) > .lockstate__mark::after {
  background: var(--rule-dark);
}

.lockstate__seq {
  grid-column: 2;
  color: var(--ink-faint);
}

.lockstate__label {
  grid-column: 2;
  color: var(--ink-strong);
}
.on-dark .lockstate__label {
  color: var(--paper);
}

.lockstate__note {
  grid-column: 2;
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--t-small);
  line-height: var(--lh-body);
  color: var(--ink-muted);
  max-width: 46ch;
}
.on-dark .lockstate__note {
  color: var(--cream);
}

/* ---- Horizontal axis (P3.3 lays the explainer out this way) --------- */
@media (min-width: 1024px) {
  .lockstate--x {
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    /* On the horizontal axis the track width is fixed by the grid, so the
       gap is a real gap and the leader reaches across it. */
    gap: var(--lockstate-gap);
    align-items: start;
  }
  .lockstate--x .lockstate__state {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--s-2);
  }
  .lockstate--x .lockstate__mark {
    grid-column: 1;
    grid-row: auto;
    align-self: auto;
    flex-direction: row;
    align-items: center;
    width: 100%;
  }
  .lockstate--x .lockstate__state:not(:last-child) > .lockstate__mark::after {
    width: auto;
    min-height: 0;
    height: 1px;
    min-width: var(--s-4);
    margin-block-end: 0;
    margin-inline-end: calc(-1 * var(--lockstate-gap));
  }
  .lockstate--x .lockstate__seq,
  .lockstate--x .lockstate__label,
  .lockstate--x .lockstate__note {
    grid-column: 1;
  }
}

/* ============================================================
   Standard Closing Section (Above Footer) — Photo Backdrop + CTA
   ============================================================ */
.close-split {
  position: relative;
  background: var(--pitch) url("img/art/play-wide.jpg") center center / cover no-repeat;
  padding-block: clamp(64px, 8vw, 120px);
  overflow: hidden;
  border-top: 1px solid var(--rule-strong);
}

.close-split--park {
  background-image: url("img/art/play-wide.jpg");
}

.close-split--sessions {
  background-image: url("img/duo/hero-dog-play.jpg");
}

.close-split--puppy {
  background-image: url("img/puppy-hour.jpg");
}

.close-split--people {
  background-image: url("img/safety-handler.jpg");
}

.close-split--faq {
  background-image: url("img/art/play-wide.jpg");
}

.close-split::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    135deg,
    rgba(20, 18, 19, 0.92) 0%,
    rgba(24, 22, 23, 0.84) 50%,
    rgba(20, 18, 19, 0.94) 100%
  );
  pointer-events: none;
}

.close-split__inner {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-8);
  flex-wrap: wrap;
}

.close-split__text {
  max-width: 62ch;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.close-split__h {
  font-size: clamp(32px, 5vw, 60px);
  line-height: 1.05;
  color: var(--paper);
  margin: 0;
}

.close-split__lead {
  color: var(--paper-muted);
  font-size: var(--t-lead);
  line-height: var(--lh-body);
  margin: var(--s-2) 0 0;
  max-width: var(--measure);
  text-wrap: pretty;
}

.close-split__spec {
  color: var(--paper-muted);
  margin-top: var(--s-2);
  font-size: 12px;
  letter-spacing: var(--track-label, 0.08em);
}

.close-split__actions {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  align-items: stretch;
}

.close-split__actions .cta {
  min-width: 200px;
  justify-content: center;
  text-align: center;
  white-space: nowrap;
}

.close-split__cta {
  background: var(--paper);
  color: var(--pitch);
}

.close-split__cta:hover {
  background: var(--accent);
  color: var(--paper);
}

@media (max-width: 768px) {
  .close-split__actions {
    flex-direction: column;
    width: 100%;
    align-items: stretch;
    gap: var(--s-3);
  }
  .close-split__actions .cta {
    width: 100%;
    min-width: 0;
    white-space: normal;
    padding-inline: var(--s-4);
  }
}

/* ---- JOJO Dog Store — sub-footer teaser ---------------------------
   One idea: a brand dog-tag hanging between two giant type rows.
   --p (0→1) is written by chrome.js from scroll position.
   ------------------------------------------------------------------ */
.store-tease {
  --p: 0.5;
  --st-type: clamp(88px, 17vw, 280px);
  --st-tag: clamp(180px, 30vw, 440px);
  position: relative;
  overflow: hidden;
  background: var(--pitch);
  color: var(--paper);
  padding-top: var(--s-9);
  isolation: isolate;
}

.store-tease__sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
  font-size: var(--d-2);
}

.store-tease__stage { position: relative; }

.store-tease__track {
  display: flex;
  align-items: center;
  gap: 0.22em;
  width: max-content;
  font-family: var(--font-display);
  font-size: var(--st-type);
  line-height: 0.82;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  white-space: nowrap;
  will-change: transform;
}

.store-tease__track i {
  flex: none;
  width: 0.2em;
  height: 0.2em;
  border-radius: 50%;
  background: var(--cognac);
}

.store-tease__track--a {
  position: relative;
  z-index: 1;
  color: var(--paper);
  transform: translate3d(calc(-6% - var(--p) * 20%), 0, 0);
}

.store-tease__track--b {
  position: relative;
  z-index: 3;
  margin-top: 0.06em;
  color: transparent;
  -webkit-text-stroke: 2px var(--paper);
  transform: translate3d(calc(-28% + var(--p) * 20%), 0, 0);
}

.store-tease__track--b i {
  background: transparent;
  box-shadow: inset 0 0 0 2px var(--cognac);
}

/* The pendant hangs from the top edge of the section and swings about
   that point; the tag scales and its rim spins as the reader scrolls. */
.store-tease__pendant {
  --st-cord: calc(var(--s-9) + var(--st-type) * 0.84 - var(--st-tag) * 0.5);
  position: absolute;
  z-index: 2;
  left: 50%;
  top: calc(var(--s-9) * -1);
  width: var(--st-tag);
  height: calc(var(--st-cord) + var(--st-tag));
  margin-left: calc(var(--st-tag) * -0.5);
  transform-origin: 50% 0;
  transform: rotate(calc((0.5 - var(--p)) * 18deg));
  will-change: transform;
}

.store-tease__cord {
  position: absolute;
  left: 50%;
  top: 0;
  width: 2px;
  margin-left: -1px;
  height: calc(var(--st-cord) + var(--st-tag) * 0.075);
  background: linear-gradient(var(--rule-dark), var(--paper-muted));
}

.store-tease__tag {
  position: absolute;
  left: 0;
  bottom: 0;
  width: var(--st-tag);
  height: var(--st-tag);
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 28%, rgba(255, 252, 250, 0.18), rgba(255, 252, 250, 0) 46%),
    var(--cognac);
  box-shadow:
    inset 0 0 0 calc(var(--st-tag) * 0.035) var(--accent-deep),
    inset 0 0 0 calc(var(--st-tag) * 0.04) rgba(255, 252, 250, 0.22),
    0 40px 80px rgba(0, 0, 0, 0.45);
  display: grid;
  place-items: center;
  transform-origin: 50% 12%;
  transform: scale(min(1, calc(0.7 + var(--p) * 0.6)));
}

.store-tease__hole {
  position: absolute;
  top: 5.5%;
  left: 50%;
  width: 4.5%;
  height: 4.5%;
  margin-left: -2.25%;
  border-radius: 50%;
  background: var(--pitch);
  box-shadow: 0 0 0 1.5px var(--paper-muted);
}

.store-tease__rim {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: rotate(calc(var(--p) * 220deg));
}

.store-tease__rim text {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 10px;
  letter-spacing: 0.2em;
  fill: var(--paper);
}

.store-tease__logo {
  width: 36%;
  height: auto;
  margin-top: 6%;
}

.store-tease__foot {
  position: relative;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4) var(--s-6);
  margin-top: var(--s-8);
  padding-block: var(--s-6);
}

.store-tease__foot::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--gutter);
  right: var(--gutter);
  border-top: 1px solid var(--rule-dark);
}

.store-tease__line {
  margin: 0;
  font-size: var(--t-lead);
  color: var(--paper-muted);
  max-width: 46ch;
}

.store-tease__link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 44px;
  font-family: var(--font-label);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--paper);
  text-decoration: none;
  border-bottom: 1px solid var(--cognac);
}

.store-tease__link span { transition: transform var(--dur-state) var(--ease-out); }
.store-tease__link:hover span { transform: translateX(4px); }
.store-tease__link:focus-visible { outline: 2px solid var(--paper); outline-offset: 4px; }

@media (max-width: 600px) {
  .store-tease__track--b { -webkit-text-stroke-width: 1.5px; }
  .store-tease__foot { margin-top: var(--s-7); }
}

@media (prefers-reduced-motion: reduce) {
  .store-tease { --p: 0.5 !important; }
  .store-tease__track,
  .store-tease__pendant { will-change: auto; }
}

/* ============================================================
   JOJO PRELOADER — Fullscreen white with top-to-bottom logo fill
   ============================================================ */
html.is-preloading,
html.is-preloading body {
  overflow: hidden !important;
  height: 100% !important;
}

.jojo-preloader {
  position: fixed !important;
  inset: 0 !important;
  width: 100vw !important;
  height: 100vh !important;
  z-index: 2147483647 !important;
  background-color: #ffffff !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  pointer-events: auto !important;
  opacity: 1 !important;
  transform: scale(1) !important;
  transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), visibility 0.6s !important;
}

.jojo-preloader.is-exiting {
  opacity: 0 !important;
  transform: scale(1.04) !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

.jojo-preloader__stage {
  position: relative !important;
  width: clamp(170px, 22vw, 250px) !important;
  aspect-ratio: 265.28 / 214.19 !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

.jojo-preloader__logo {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  display: block !important;
}

.jojo-preloader__logo--base {
  opacity: 0.14 !important;
}

.jojo-preloader__logo--fill {
  clip-path: inset(100% 0 0 0);
  -webkit-clip-path: inset(100% 0 0 0);
  animation: jojoLogoFill 1.8s cubic-bezier(0.65, 0, 0.35, 1) 0.1s forwards;
}

@keyframes jojoLogoFill {
  0% {
    clip-path: inset(100% 0 0 0);
    -webkit-clip-path: inset(100% 0 0 0);
  }
  100% {
    clip-path: inset(0% 0 0 0);
    -webkit-clip-path: inset(0% 0 0 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .jojo-preloader {
    display: none !important;
  }
}

/* ============================================================
   HOVER VIDEO LOOP COMPONENT (Option B)
   Progressive video overlay on cards/galleries. Zero layout shift.
   ============================================================ */
.has-hover-video {
  position: relative;
  overflow: hidden;
}

.hover-video,
.gallery-item__video,
.apparatus-card__video,
.xp-item__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  pointer-events: none;
  transition: opacity 350ms cubic-bezier(0.25, 1, 0.5, 1);
  z-index: 1;
}

@media (hover: hover) and (pointer: fine) {
  .has-hover-video:hover .hover-video,
  .apparatus-card:hover .apparatus-card__video,
  .apparatus-card:hover .hover-video,
  .gallery-item:hover .gallery-item__video,
  .gallery-item:hover .hover-video,
  .xp-item:hover .xp-item__video,
  .xp-item:hover .hover-video {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hover-video,
  .gallery-item__video,
  .apparatus-card__video,
  .xp-item__video {
    display: none !important;
  }
}


