/* ============================================================================
   mm-page-mode.css — MailMoolah's ADDITIVE dual-mode header-offset contract.
   Served at `/css/mm-page-mode.css` (backend/app/main.py mounts `frontend/css/`
   at `/css`).

   Pairs with `/js/page-mode.js`, which stamps <html> with
   `data-page-mode="embedded|standalone"` + `page-mode-{embedded,standalone}`
   BEFORE first paint. Load order in <head> — the blocking script FIRST, this
   stylesheet after it:

       <script src="/js/page-mode.js?v=20260808"></script>
       <link rel="stylesheet" href="/css/mm-page-mode.css">

   THE MODEL IS ADDITIVE. The STANDALONE host ADDS the header offset; EMBEDDED
   adds nothing. There is deliberately NO subtractive `display:none` hide-CSS
   here — that per-page whack-a-mole is the failure mode this file replaces.

   This is a THIN SEMANTIC ADAPTER over shell geometry that SHARED_DASHBOARD
   already owns. It defines exactly one token and one helper class. It does not
   restyle, reset, or re-implement anything Tailwind or the shell provides.

   DEV_GUIDE #1: every length below is rem. There are zero authored px.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   THE TOKEN — --app-header-offset is the SINGLE SOURCE OF TRUTH for "how far
   down the page does the shell's fixed top chrome reach".

   MEASURED, not assumed. The DEV_GUIDE writes this token as `4rem` because
   INDIANMARRIAGE's `shared-header.js` renders a Tailwind `h-16` (4rem) bar.
   MailMoolah's header comes from a DIFFERENT source and is a different height:

     C:\SharedRepos\tools\SHARED_DASHBOARD\frontend\css\header-embed.css
       :root { --he-height: 3.75rem; }          <- the shell's own token
       .he-header { position: fixed; top: 0; height: var(--he-height); }

   and every one of the 54 MailMoolah pages that hard-codes body padding today
   uses `padding-top: 3.75rem` to clear it (header-embed.js sets the same value
   imperatively at js:1694). Hard-coding `4rem` here would open a 0.25rem gap
   under the header on every standalone page, so the token DEFERS TO THE SHELL'S
   OWN VARIABLE and only falls back to the measured literal when a page loads
   this file without `header-embed.css`. If the shell ever retunes its header,
   MailMoolah tracks it with no edit here.
---------------------------------------------------------------------------- */
:root {
  /* Height of the shell's fixed top bar (.he-header). */
  --mm-header-height: var(--he-height, 3.75rem);

  /* Height of the shell's SECOND fixed band, `.he-context-bar` (the APP-MENU
     breadcrumb strip: `position: fixed; top: var(--he-height); height: 2.5rem`,
     header-embed.css). It is rendered only on pages whose path matches an app
     menu — header-embed.js then pushes body padding to 6.25rem (js:3679, 3805)
     instead of 3.75rem. The shell signals this with an inline style, not a
     class, so CSS cannot detect it: a page that renders the context bar must
     OPT IN (see `html.mm-has-context-bar` below). Default 0rem keeps the token
     exactly equal to today's behaviour for every other page. */
  --mm-context-bar-height: 0rem;

  --app-header-offset: calc(var(--mm-header-height) + var(--mm-context-bar-height));
}

/* OPT-IN for the shell's second fixed band. Add `mm-has-context-bar` to the
   <html> tag (statically in the markup, so it is present before paint) on any
   page whose path matches a SHARED_DASHBOARD app menu — the same pages where
   header-embed.js pushes body padding to 6.25rem.

   Use THIS CLASS, not a bare `html { --mm-context-bar-height: 2.5rem }` rule in
   your own stylesheet: `:root` above has specificity (0,1,0) and a bare `html`
   selector only (0,0,1), so the default would SILENTLY WIN over your override no
   matter the source order. This class is (0,1,1) and beats it deterministically.
   An inline `style="--mm-context-bar-height:2.5rem"` on <html> also works. */
html.mm-has-context-bar {
  --mm-context-bar-height: 2.5rem;
}

/* EMBEDDED: the workspace shell owns the top chrome, so the page's own offset
   collapses to zero. Setting the token (not the padding) is what makes every
   consumer below — body padding, .page-sticky-top, any page that pins to
   var(--app-header-offset) — correct in both modes with no per-page override. */
html.page-mode-embedded {
  --app-header-offset: 0rem;
}

/* STANDALONE: add the offset so content clears the fixed shared header.

   Public/marketing pages such as index.html and recipient.html own in-flow or
   sticky page chrome instead of loading SHARED_DASHBOARD's fixed header. They
   opt out with `mm-page-owns-chrome`; applying the shell offset to them creates
   a conspicuous empty 3.75rem band before their own navigation. Keeping the
   default additive preserves every existing shared-header page while making
   the no-shell case explicit and reusable. */
html.page-mode-standalone body {
  padding-top: var(--app-header-offset);
}

html.page-mode-standalone body.mm-page-owns-chrome {
  padding-top: 0;
}

/* EMBEDDED: flush to the iframe top. `!important` is load-bearing and is the one
   deliberate use in this file: it is the only declaration that can beat the
   `style="padding-top: 3.75rem"` INLINE attribute still present on 54 unmigrated
   pages (MM-00 manifest §B). That makes this stylesheet fix embedded framing on
   those pages immediately, while leaving their standalone rendering byte-identical
   (an inline style outranks the non-important standalone rule above). */
html.page-mode-embedded body {
  padding-top: 0 !important;
}

/* ----------------------------------------------------------------------------
   .page-sticky-top — opt-in helper for a page-level sticky bar (filter row,
   table header strip, bulk-action bar) that Just Works in BOTH modes.
   Use `class="page-sticky-top"` INSTEAD of Tailwind's `sticky top-16` /
   `sticky top-20`: a hard-coded top offset floats over the content the moment
   the shell removes the header above it, which is exactly what
   scripts/ci_guard_embed_chrome.py check B fails on.

   z-index rationale (measured against header-embed.css, NOT copied from the
   reference site, which uses 1020): the shell stacks `.he-context-bar` at 999,
   `.he-header` at 1000 and `.he-mobile-nav` at 1050 — and the mobile nav panel
   and the header dropdowns open AT `top: var(--he-height)`, i.e. into exactly
   the band a page sticky bar occupies. A page bar must therefore sit BELOW all
   of them or it covers open shell menus. 900 leaves headroom for page-local
   layering underneath.
---------------------------------------------------------------------------- */
.page-sticky-top {
  position: sticky;
  top: var(--app-header-offset);
  z-index: 900;
}

/* In-page anchor targets land below the fixed chrome instead of underneath it.
   Same token, so it is correct in both modes. */
html.page-mode-standalone :target {
  scroll-margin-top: var(--app-header-offset);
}
