/* ==========================================================================
   भक्ति Vilas, shared art direction
   --------------------------------------------------------------------------
   Loaded by every page, after app.css. This is the design language the whole
   site now shares: the section system, display type, the kicker, buttons,
   the dark page-header band, and all reveal motion.

   The premise, set on the home page and carried through here: oxblood is the
   brand's dominant surface, not its trim. Dark bands carry display type and
   imagery. Working areas (session lists, circle lists, settings, and every
   health explainer) stay on cream at full contrast, because the audience is
   65+ and those surfaces are read, not admired.

   Hand-written on purpose. The Tailwind CDN only emits rules for classes
   present at its first scan, so nothing here may depend on a utility class.
   Everything is visible by default: motion enhances, it never gates content.
   ========================================================================== */

/* ------------------------------------------------------------- foundations */

.bv-sec {
  position: relative;
  padding: clamp(72px, 9vw, 132px) clamp(20px, 5vw, 48px);
}
.bv-sec__in {
  position: relative;
  z-index: 1;
  max-width: 1280px;
  margin: 0 auto;
}

.bv-sec--dark   { background: var(--bv-maroon);      color: var(--bv-cream); }
.bv-sec--deep   { background: var(--bv-maroon-deep); color: var(--bv-cream); }
.bv-sec--light  { background: var(--bv-cream);       color: var(--bv-ink); }
.bv-sec--light-2{ background: var(--bv-cream-2);     color: var(--bv-ink); }

/* Display type. Libre Caslon Text throughout; the contrast comes from scale
   and measure, not from introducing a fourth family. */
.bv-dsp {
  margin: 0;
  font-family: "Libre Caslon Text", Georgia, serif;
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.bv-dsp--xl { font-size: clamp(2.9rem, 7vw, 5.5rem); }
.bv-dsp--lg { font-size: clamp(2.3rem, 5vw, 3.9rem); line-height: 1.1; }
.bv-dsp--md { font-size: clamp(1.9rem, 3.4vw, 2.8rem); line-height: 1.15; }
.bv-dsp--sm { font-size: clamp(1.5rem, 2.4vw, 2.05rem); line-height: 1.2; }

.bv-lede {
  font-family: Manrope, sans-serif;
  font-size: clamp(1.05rem, 1.5vw, 1.28rem);
  line-height: 1.65;
  max-width: 62ch;
  text-wrap: pretty;
}

/* One named kicker. Used once per section at most, and only where a section
   genuinely needs naming, so it reads as a brand mark rather than as the
   uppercase eyebrow that sits above every heading on a templated page. */
.bv-kicker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: Manrope, sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--bv-gold);
}
.bv-kicker::before {
  content: "";
  width: 34px;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}
/* on cream surfaces the gold needs to darken to hold 4.5:1 */
.bv-sec--light .bv-kicker,
.bv-sec--light-2 .bv-kicker { color: #8a6a12; }

/* --------------------------------------------------------------- buttons */

.bv-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 30px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: Manrope, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1),
              background-color 0.22s ease, color 0.22s ease,
              border-color 0.22s ease, box-shadow 0.22s ease;
}
.bv-cta:focus-visible { outline: 2px solid var(--bv-gold); outline-offset: 3px; }

.bv-cta--gold {
  background: var(--bv-gold);
  color: var(--bv-maroon-deep);
  box-shadow: 0 12px 30px -14px rgba(201, 162, 39, 0.7);
}
.bv-cta--gold:hover {
  background: var(--bv-gold-soft);
  transform: translateY(-2px);
  box-shadow: 0 18px 38px -14px rgba(201, 162, 39, 0.8);
}

.bv-cta--outline {
  background: rgba(255, 248, 245, 0.06);
  border-color: rgba(255, 248, 245, 0.42);
  color: var(--bv-cream);
}
.bv-cta--outline:hover {
  background: rgba(255, 248, 245, 0.14);
  border-color: var(--bv-cream);
  transform: translateY(-2px);
}

.bv-cta--solid { background: var(--bv-maroon); color: var(--bv-cream); }
.bv-cta--solid:hover { background: var(--bv-maroon-deep); transform: translateY(-2px); }

.bv-cta--quiet {
  background: transparent;
  border-color: rgba(60, 3, 12, 0.28);
  color: var(--bv-maroon);
}
.bv-cta--quiet:hover {
  background: var(--bv-maroon);
  border-color: var(--bv-maroon);
  color: var(--bv-cream);
  transform: translateY(-2px);
}

.bv-cta--sm { padding: 11px 22px; font-size: 0.92rem; }
.bv-cta svg { width: 18px; height: 18px; flex: 0 0 auto; }
.bv-cta--sm svg { width: 16px; height: 16px; }

/* ----------------------------------------------------------------- header */
/* Pages whose first band is dark carry `bv-dark-top` on <body>. There the
   header dissolves into the band instead of sitting on it as a cream slab,
   and returns to the shared cream treatment the moment the page scrolls.
   Scoped through #top-app-bar so specificity beats the Tailwind utilities in
   the markup without reaching for !important. */

body.bv-dark-top #top-app-bar { position: fixed; left: 0; right: 0; }
#top-app-bar { transition: background-color 0.35s ease, border-color 0.35s ease; }
[id^="bv-"], .bv-anchor { scroll-margin-top: 96px; }

body.bv-dark-top:not(.bv-scrolled) #top-app-bar {
  /* not a bar: a soft ceiling scrim, so cream nav text keeps its contrast
     against whatever sits underneath it */
  background: linear-gradient(to bottom, rgba(42, 2, 8, 0.62), rgba(42, 2, 8, 0.18) 62%, rgba(42, 2, 8, 0));
  backdrop-filter: none;
  box-shadow: none;
  border-bottom-color: transparent;
  height: 84px;
}
body.bv-dark-top:not(.bv-scrolled) #top-app-bar h1,
body.bv-dark-top:not(.bv-scrolled) #top-app-bar nav a,
body.bv-dark-top:not(.bv-scrolled) #top-app-bar [data-bv-action="menu"] {
  color: var(--bv-cream);
}
body.bv-dark-top:not(.bv-scrolled) #top-app-bar nav a[class*="text-secondary"] {
  color: rgba(255, 248, 245, 0.86);
}
body.bv-dark-top:not(.bv-scrolled) #top-app-bar nav a[class*="text-secondary"]:hover {
  color: var(--bv-cream);
}
body.bv-dark-top:not(.bv-scrolled) #top-app-bar .bv-radio,
body.bv-dark-top:not(.bv-scrolled) #top-app-bar .bv-picker__btn {
  background: rgba(255, 248, 245, 0.1);
  border-color: rgba(255, 248, 245, 0.3);
  color: var(--bv-cream);
}
body.bv-dark-top:not(.bv-scrolled) #top-app-bar .bv-radio:hover,
body.bv-dark-top:not(.bv-scrolled) #top-app-bar .bv-picker__btn:hover {
  background: rgba(255, 248, 245, 0.2);
  border-color: rgba(255, 248, 245, 0.55);
}
body.bv-dark-top:not(.bv-scrolled) #top-app-bar [data-auth-open] {
  background: var(--bv-gold);
  color: var(--bv-maroon-deep);
}
/* the joined/disabled state must not be repainted as a live gold button */
body.bv-dark-top:not(.bv-scrolled) #top-app-bar [data-auth-open][disabled] {
  background: rgba(255, 248, 245, 0.16);
  color: rgba(255, 248, 245, 0.55);
}

/* ------------------------------------------------------- page header band */
/* The inner pages are product surfaces: someone is here to book a session,
   find a circle or change a plan. They get the brand's dark band as a header
   so the site reads as one thing, and then the work happens on cream. */

.bv-pagehead {
  position: relative;
  overflow: hidden;
  background: var(--bv-maroon-deep);
  color: var(--bv-cream);
  padding: calc(84px + clamp(40px, 6vw, 76px)) clamp(20px, 5vw, 48px) clamp(44px, 6vw, 78px);
}
.bv-pagehead__in {
  position: relative;
  z-index: 1;
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 26px 40px;
}
.bv-pagehead__copy { max-width: 46ch; }
.bv-pagehead .bv-kicker { margin-bottom: 18px; }
.bv-pagehead .bv-dsp { color: var(--bv-cream); }
.bv-pagehead__lede {
  margin: 20px 0 0;
  max-width: 54ch;
  font-family: Manrope, sans-serif;
  font-size: clamp(1rem, 1.3vw, 1.14rem);
  line-height: 1.7;
  color: rgba(255, 248, 245, 0.8);
  text-wrap: pretty;
}
.bv-pagehead__aside {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

/* one large, very faint mandala anchored bottom-right of the band */
.bv-pagehead__mark {
  position: absolute;
  z-index: 0;
  right: -6vmin;
  bottom: -26vmin;
  width: 46vmin;
  height: 46vmin;
  color: var(--bv-gold);
  opacity: 0.13;
  pointer-events: none;
}
.bv-pagehead__mark svg { width: 100%; height: 100%; display: block; stroke-width: 0.7; }

@media (max-width: 720px) {
  .bv-pagehead__in { align-items: flex-start; }
  .bv-pagehead__mark { width: 62vmin; height: 62vmin; bottom: -34vmin; }
}

/* ------------------------------------------------------- section headings */
/* Used on the cream working areas: a heading with an optional note pushed to
   the far side. Replaces the centred heading-over-grid rhythm that made
   every section on every page read the same. */

.bv-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px 32px;
  margin-bottom: clamp(24px, 3.2vw, 40px);
}
.bv-head .bv-dsp { color: var(--bv-maroon); }
.bv-head p {
  margin: 0;
  max-width: 40ch;
  font-family: Manrope, sans-serif;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--bv-muted);
}

/* ================================================================= motion */
/* Rule: content is visible at rest. Reveals animate an element that already
   renders, so a listener that never fires costs an animation, not a section.
   Bug 1 in memory.md was exactly this failure and it blanked whole pages. */

@keyframes bvRise {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}
@keyframes bvFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes bvWipe {
  from { opacity: 0; clip-path: inset(0 0 100% 0); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); }
}
@keyframes bvGrow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.bv-rv.is-in       { animation: bvRise 0.85s cubic-bezier(0.16, 1, 0.3, 1) both; }
.bv-rv--wipe.is-in { animation: bvWipe 1s cubic-bezier(0.16, 1, 0.3, 1) both; }
.bv-rv--fade.is-in { animation: bvFade 1.1s ease both; }
.bv-rv[data-d="1"].is-in { animation-delay: 0.08s; }
.bv-rv[data-d="2"].is-in { animation-delay: 0.16s; }
.bv-rv[data-d="3"].is-in { animation-delay: 0.24s; }
.bv-rv[data-d="4"].is-in { animation-delay: 0.32s; }
.bv-rv[data-d="5"].is-in { animation-delay: 0.40s; }
.bv-rv[data-d="6"].is-in { animation-delay: 0.48s; }

/* the page header band animates on load rather than on scroll: it is always
   in view, so waiting for an intersection would mean it never fires */
.bv-pagehead__copy > * { animation: bvRise 0.85s cubic-bezier(0.16, 1, 0.3, 1) both; }
.bv-pagehead .bv-kicker { animation-delay: 0.08s; }
.bv-pagehead .bv-dsp    { animation-delay: 0.16s; }
.bv-pagehead__lede      { animation-delay: 0.26s; }
.bv-pagehead__aside     { animation: bvFade 1s ease 0.36s both; }

@media (prefers-reduced-motion: reduce) {
  .bv-rv,
  .bv-rv.is-in,
  .bv-pagehead__copy > *,
  .bv-pagehead__aside {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }
}

/* the mobile bottom nav is fixed at 80px tall and would otherwise sit on top
   of the last thing on every page */
@media (max-width: 767px) {
  body { padding-bottom: calc(80px + env(safe-area-inset-bottom, 0px)); }
}
