/* ============================================================================
   sitebuilder-blocks.css — PUBLIC BLOCK POLISH
   ----------------------------------------------------------------------------
   Loaded by BlockRenderer::blocksCss(), which emits a same-origin <link> at the
   head of the rendered block stream (exactly like contact-prefs.css). That means
   it applies BOTH on the live tenant site (SiteBuilder::public) and inside the
   builder's preview iframe — the canvas and the published page stay WYSIWYG.

   Rules here are strictly ADDITIVE on top of sitebuilder.css (which loads first,
   so equal-specificity rules here win by document order). No new markup, no new
   block field: every selector targets classes BlockRenderer already emits, so
   existing tenant pages keep rendering and only gain the polish.

   Conventions honoured:
     * RTL/LTR — logical properties only (inset-inline-*, border-inline-*,
       margin-inline-*). Nothing here uses left/right.
     * Light + dark — colour comes exclusively from the design tokens in
       variables.css, which the [data-theme] roots re-point for dark.
     * Reduced motion — every animation/transition added here is wrapped in
       @media (prefers-reduced-motion: no-preference) or neutralised in the
       reduce block at the bottom.
     * Edit mode — BlockRenderer adds data-block-id to every block root ONLY in
       edit mode, so `:not([data-block-id])` is a reliable "public render" test.
       Scroll-driven reveal is public-only: in the builder the blocks must be
       fully painted and correctly positioned for the selection overlay to
       measure them.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1. ANCHOR TARGETS
   A block's optional `anchor` becomes the id on its root <section> (or the
   spacer <div>). The public layout's nav is FIXED, so a bare #fragment jump
   parks the section's heading underneath it. Give every anchored top-level
   block the nav's height as scroll margin so "#about" lands correctly — from a
   nav click, an in-page CTA or a direct /p/about#story link.
   Scoped to DIRECT children of .sb-site so ids generated inside a block (the
   FAQ collapsible targets) are untouched.
   --------------------------------------------------------------------------- */
.sb-site > [id] { scroll-margin-block-start: calc(var(--nav-h) + var(--s-4)); }

/* ---------------------------------------------------------------------------
   2. SCROLL REVEAL — CSS only, no JavaScript
   Uses a scroll-progress (view) timeline, so there is no IntersectionObserver
   and nothing to load: the strict CSP is untouched. Guarded three ways —
     * @supports  browsers without animation-timeline never apply it, so the
                  content is simply always visible (never hidden by a fallback);
     * :not([data-block-id])  edit mode opts out entirely;
     * no-preference  reduced-motion users opt out entirely.
   The range ENDS at `entry 70%`, i.e. well before the block is fully on screen,
   so anything already in the viewport on load (the hero, and every block on a
   page shorter than the viewport) is at 100% progress = fully visible.
   --------------------------------------------------------------------------- */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Longhands on purpose: the `animation` shorthand would reset
       animation-duration, and a view-timeline animation needs it left at its
       initial value so the timeline (not a clock) drives progress. Should a
       browser support animation-timeline but resolve the duration to 0s, the
       animation lands on its END keyframe — i.e. fully visible. Failing safe
       towards VISIBLE is the whole point. */
    .sb-site > section:not([data-block-id]) {
      animation-name: sb-rv-in;
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: view();
      animation-range: entry 5% entry 70%;
    }
    /* The first block is the hero: it is above the fold by definition, so give
       it nothing to animate and avoid any chance of a first-paint flicker. */
    .sb-site > section:not([data-block-id]):first-child { animation-name: none; }
  }
}
@keyframes sb-rv-in {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------------
   3. HERO — a soft brand glow behind the headline
   .sb-hero is already position:relative + isolation:isolate, and its optional
   background image sits at z-index:-1; the glow goes one layer further back so
   it never covers either. Purely decorative and pointer-transparent.
   --------------------------------------------------------------------------- */
.sb-hero::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  block-size: 78%;
  z-index: -2;
  pointer-events: none;
  background: radial-gradient(70% 100% at 50% 0, var(--tint-strong), transparent 72%);
}

/* ---------------------------------------------------------------------------
   4. STATS — hairline dividers between tiles
   The row is an auto-fit grid; a start-edge hairline on every tile but the
   first reads as a divider when they share a line and disappears cleanly when
   they wrap on narrow screens (see the media query at the end).
   --------------------------------------------------------------------------- */
.sb-stat + .sb-stat { border-inline-start: 1px solid var(--line); }
.sb-stat__label { letter-spacing: .01em; }

/* ---------------------------------------------------------------------------
   5. STEPS — a connector line down the numbered markers
   Turns the "how it works" list into a visual timeline. The connector is drawn
   from each step's marker to the next one; the marker is 38px wide and is the
   first item in the flex row, so its centre sits 19px from the INLINE START
   edge — which flips automatically in RTL.
   --------------------------------------------------------------------------- */
.sb-steps__list { position: relative; }
.sb-step { position: relative; }
.sb-step:not(:last-child)::before {
  content: "";
  position: absolute;
  inset-block-start: 42px;
  inset-block-end: calc(var(--s-6) * -1);
  inset-inline-start: 18px;
  inline-size: 2px;
  border-radius: 2px;
  background: linear-gradient(var(--line-brand), transparent);
}
.sb-step__num { position: relative; z-index: 1; }

/* ---------------------------------------------------------------------------
   6. GALLERY — quiet hover zoom on the photo strip
   The About page leans on the gallery for "here is the room you'll train in".
   --------------------------------------------------------------------------- */
.sb-gallery .sb-figure { overflow: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .sb-gallery .sb-figure img { transition: transform var(--dur-slow) var(--ease-out-expo); }
  .sb-gallery .sb-figure:hover img { transform: scale(1.045); }
}

/* ---------------------------------------------------------------------------
   7. DYNAMIC BLOCKS — live service / course / plan cards
   These carry the business's real inventory on the landing page, so they earn a
   little emphasis on hover. They are plain .card elements (unlike the course
   card, which already opts into .card--hover), so we simply give them the SAME
   hover state .card--hover defines — a fade of border + elevation, and NO pop:
   the house style is hover-fade, not hover-transform, and .card already carries
   the 180ms transition, so nothing new needs to move.
   --------------------------------------------------------------------------- */
.sb-service-card:hover,
.sb-plan-card:hover,
.sb-service-card:focus-within,
.sb-plan-card:focus-within {
  border-color: var(--line-brand);
  box-shadow: var(--shadow-lg), var(--glass-hi);
}

/* The meeting-type chips above the booking grid read as metadata, not actions. */
.sb-booking__type { font-weight: 600; }

/* ---------------------------------------------------------------------------
   8. SECTION HEADS — centre the heading of the proof/offer sections
   .section__head is a plain left-aligned block; on the long marketing pages the
   template builds, centred heads give the page a rhythm. Restricted to the
   block types the landing/about templates use as "section openers" so no other
   block's layout shifts.
   --------------------------------------------------------------------------- */
.sb-features > .section__head,
.sb-testimonials > .section__head,
.sb-pricing > .section__head,
.sb-faq > .section__head,
.sb-steps > .section__head { text-align: center; }
.sb-features > .section__head .page-title,
.sb-testimonials > .section__head .page-title,
.sb-pricing > .section__head .page-title,
.sb-faq > .section__head .page-title,
.sb-steps > .section__head .page-title { margin-inline: auto; }

/* ---------------------------------------------------------------------------
   9. NARROW SCREENS
   Once the stats wrap to one per line the vertical hairline is noise, and the
   steps connector has to shrink with the tighter gap.
   --------------------------------------------------------------------------- */
@media (max-width: 820px) {
  .sb-stat + .sb-stat { border-inline-start: 0; }
  .sb-step:not(:last-child)::before { inset-block-end: calc(var(--s-6) * -1); }
}

/* ---------------------------------------------------------------------------
   10. REDUCED MOTION — belt and braces
   The blocks above already gate on no-preference; this neutralises anything
   that slipped through (and any future addition to this sheet).
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .sb-site > section { animation-name: none !important; }
  .sb-gallery .sb-figure img { transition: none !important; transform: none !important; }
}
