/*
 * DIVSA App Shell — Phase 1 canonical frontend geometry.
 *
 * One page, one shell, one content gutter. Component roots and historical
 * .tap-container nodes are semantic children only; they do not create another
 * viewport/container contract.
 */
:root{
  --tap-shell-gutter:28px;
  --tap-shell-content-max:var(--tap-content-max,1160px);
}

.tap-app-shell{
  box-sizing:border-box;
  display:block;
  inline-size:100%;
  min-inline-size:0;
  max-inline-size:none;
  margin:0;
}

.tap-shell-container{
  box-sizing:border-box;
  inline-size:min(100%,calc(var(--tap-shell-content-max) + (2 * var(--tap-shell-gutter))));
  min-inline-size:0;
  margin-inline:auto;
  padding-inline:var(--tap-shell-gutter);
}

/* The shell owns page geometry. Direct application surfaces are mount points. */
.tap-shell-container > :where(.tap-surface,.tap-root,.tap-home-root,.tap-booking-root,.tap-dashboard-root,.tap-consult-root){
  box-sizing:border-box;
  inline-size:100%;
  max-inline-size:none;
  min-inline-size:0;
  margin-inline:0;
  padding-inline:0;
}

/* Historical .tap-container elements remain valid grouping hooks but no longer
   add a second 16px gutter or a second 1120px max-width inside the shell. */
.tap-app-shell .tap-container{
  box-sizing:border-box;
  inline-size:100%;
  max-inline-size:none;
  min-inline-size:0;
  margin-inline:0;
  padding-inline:0;
}

/* Nested surface wrappers must never become another geometry owner. */
.tap-app-shell .tap-surface{
  inline-size:100%;
  max-inline-size:none;
  min-inline-size:0;
}

/* Root clipping hid width defects in the old architecture. The shell now lets
   component overflow remain observable so it can be fixed at the component. */
.tap-app-shell :where(.tap-root,.tap-home-root,.tap-booking-root,.tap-dashboard-root,.tap-consult-root){
  max-inline-size:none;
  min-inline-size:0;
}

/* Shortcodes now use a semantic .tap-surface wrapper. Roots inside it obey the
   same single-shell geometry contract instead of becoming a second container. */
.tap-app-shell .tap-surface > :where(.tap-root,.tap-home-root,.tap-booking-root,.tap-dashboard-root,.tap-consult-root,.tap-astrologer-panel-root){
  box-sizing:border-box;
  inline-size:100%;
  max-inline-size:none;
  min-inline-size:0;
  margin-inline:0;
  padding-inline:0;
}

@media (max-width:767.98px){
  :root{--tap-shell-gutter:16px}
}
@media (min-width:768px) and (max-width:1023.98px){
  :root{--tap-shell-gutter:24px}
}
@media (min-width:1024px){
  :root{--tap-shell-gutter:28px}
}


/* Phase 7 fixed-surface clearance — the shell reserves measured fixed UI once.
   Individual pages/cards must not add nav/sticky padding of their own. */
.tap-shell-container{padding-block-end:var(--tap-page-bottom-clearance,0px)}
body.tap-has-active-nav{scroll-padding-block-end:calc(var(--tap-bottom-nav-h) + var(--tap-shell-gutter))}
body.tap-has-transaction-sticky{scroll-padding-block-end:calc(var(--tap-fixed-stack-h) + var(--tap-shell-gutter))}


/* Phase 7 canonical fixed surfaces. These rules consume geometry measured by
   tap-chrome.js; no component guesses another fixed element's height. */
.tap-toast,.tap-toast-region .tap-toast{
  inset-block-end:calc(var(--tap-fixed-stack-h) + var(--tap-pwa-h) + 14px);
  z-index:var(--tap-layer-toast)
}
.tap-pwa-bar{
  inset-block-end:calc(var(--tap-fixed-stack-h) + 12px);
  z-index:var(--tap-layer-fab)
}
.tap-wa-fab,#tap-wa-float{
  box-sizing:border-box;
  inset-inline-end:max(16px,var(--tap-safe-right));
  inset-block-end:max(16px,var(--tap-safe-bottom));
  z-index:var(--tap-layer-fab)
}
body.tap-has-active-nav:not(.tap-has-transaction-sticky) :is(.tap-wa-fab,#tap-wa-float){
  inset-block-end:calc(var(--tap-bottom-nav-h) + 16px)
}
body.tap-has-active-nav .tap-sam-sticky-buy{
  inset-block-end:calc(var(--tap-bottom-nav-h) + var(--tap-fixed-gap))
}
body:not(.tap-has-active-nav) .tap-sam-sticky-buy{
  inset-block-end:max(var(--tap-fixed-gap),var(--tap-safe-bottom))
}
body.tap-transaction-route :is(.tap-wa-fab,#tap-wa-float),
body.tap-has-transaction-sticky :is(.tap-wa-fab,#tap-wa-float),
body.tap-has-pwa-prompt :is(.tap-wa-fab,#tap-wa-float){display:none}
html.tap-noscroll :is(.tap-bottomnav,.tap-sticky,.tap-pwa-bar,.tap-wa-fab,#tap-wa-float){
  visibility:hidden;pointer-events:none
}
@media(min-width:768px){
  .tap-wa-fab,#tap-wa-float{inset-inline-end:max(20px,var(--tap-safe-right));inset-block-end:max(20px,var(--tap-safe-bottom))}
}

/* ══════════════════════════════════════════════════════════════════════════
   FIXED-SURFACE CLEARANCE MUST NOT DEPEND ON JAVASCRIPT (audited 2026-08-27)

   --tap-page-bottom-clearance defaults to 0px in tap-tokens.css and only grows
   when tap-chrome.js measure() publishes a value. measure() runs inside
   requestAnimationFrame, so until that frame lands — and never at all if the
   script is deferred behind a slow network, blocked, or the page is restored
   from bfcache — the shell reserves NOTHING while a fixed bottom nav and a
   fixed transaction bar are painted over the page. The result on a real phone
   is the sticky "Reserve Your Name" bar sitting on top of the participation
   row and the last paragraph of copy.

   These floors come from the server-rendered body classes, so they apply at
   first paint with no script at all. max() means the measured value still
   wins the moment it arrives — this raises the floor, it never caps the
   real measurement.
   ══════════════════════════════════════════════════════════════════════════ */
body.tap-has-bottomnav .tap-shell-container{
  padding-block-end:max(
    var(--tap-page-bottom-clearance, 0px),
    calc(72px + var(--tap-safe-bottom, 0px) + 12px)
  );
}

/* Offering permalinks also carry the fixed price + CTA bar above the nav. */
body.tap-has-bottomnav.single-tap_puja .tap-shell-container,
body.tap-has-bottomnav.single-tap_chadhava .tap-shell-container,
body.tap-has-bottomnav.single-tap_healing .tap-shell-container{
  padding-block-end:max(
    var(--tap-page-bottom-clearance, 0px),
    calc(72px + 84px + var(--tap-safe-bottom, 0px) + 16px)
  );
}

/* Without a bottom nav the transaction bar is still fixed on these routes. */
body:not(.tap-has-bottomnav).single-tap_puja .tap-shell-container,
body:not(.tap-has-bottomnav).single-tap_chadhava .tap-shell-container,
body:not(.tap-has-bottomnav).single-tap_healing .tap-shell-container{
  padding-block-end:max(
    var(--tap-page-bottom-clearance, 0px),
    calc(84px + var(--tap-safe-bottom, 0px) + 16px)
  );
}
