/* v2_app/assets/paywall_gates.css — Surface D (paywall gates, no-leak).

   Companion to gating.py and the gated tabs (summary / outlook / trends /
   reports / overview) and the drawer "Best this week" list. Only LAYOUT and the
   shared blur + footer-fade recipe live here; every color, type, and spacing token
   stays inline in the .py files via theme.py, so theme.py remains the single
   source of truth for values (same split as bands_tab.css).

   Uses the :root CSS variables already defined in styles.css (--page-bg,
   --border, etc.), so the two files never drift on values. Dash auto-serves
   everything in assets/, so no wiring is needed.

   NOTE ON THE LEAK (founder-accepted, v1): the hybrid-blur surfaces blur the
   REAL DOM elements, so a determined user can still read the underlying values
   in devtools. This is the accepted v1 tradeoff (see gating.py) — a true
   no-leak build would swap the blurred elements for server-rendered images. The
   Outlook and Trends surfaces render blurred GHOST DECOYS (fake, representative
   shapes carrying no real values) instead, so those leak nothing.
   ========================================================================== */


/* ---- Hybrid blur -----------------------------------------------------------
   The one shared "value is content, but withheld" recipe: heavy blur + full
   grayscale so shape/richness reads but no number or hot/cold hue survives.
   Toned to ~0.78 opacity / regular weight so blurred bold/large type reads as
   one calm muted layer instead of jarring at full ink (the handoff's global
   blur-tuning rule). A tab adds this class ONLY for free users, so it is always
   safe to blur whatever carries it. */
.pw-blur {
    filter: blur(4px) grayscale(1);
    opacity: 0.78;
    font-weight: 400 !important;
    pointer-events: none;
    user-select: none;
    -webkit-user-select: none;
}
/* Children carry their own inline weights (legend counts, <b> place names, the
   drawer pill), so tone them down too — the blurred layer must read as ONE calm
   muted weight, not a mix of bold and regular. */
.pw-blur * { font-weight: 400 !important; }


/* ---- Gate panel + footer fade scrim + bottom-sheet footer ------------------
   The gated tab content and the footer CTA stack in one flex column. The footer
   is a full-width BOTTOM SHEET: sticky to the bottom of the scrolling host
   (.region-modal-body / #drawer-secondary-content / .sheet-pane) and full-bled
   over the host's --sp-3 padding on its left, right, and bottom edges so it sits
   flush — top corners rounded only, top border + upward shadow (the sheet chrome
   is inline in gating.py). Being flush to the bottom, it seals everything below
   its top edge: no transparent gutter, no blurred content or backdrop peeking
   past. The gate is a flex column that grows to fill the host, so margin-top:auto
   on the footer floats it to the base even when the gated content is short. */
.pw-gate {
    position: relative;
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
}
/* The drawer panel + mobile sheet hosts set their padding INLINE (in
   build_secondary_skeleton / bottom_sheet.py), so CSS can't zero it. Make them
   flex columns instead, so .pw-gate fills them and the footer's margin-top:auto +
   negative bottom margin can float the sheet to the base and full-bleed over the
   inline padding. (The modal body is already a flex column via styles.css.) */
#drawer-secondary-content:has(> .pw-gate),
.sheet-pane:has(> .pw-gate) { display: flex; flex-direction: column; }

.pw-footer {
    position: sticky;
    bottom: calc(-1 * var(--sp-3));          /* stick flush to the host's border-box base while long content scrolls */
    z-index: 2;
    /* top:auto floats the sheet to the base when content is short; L/R/bottom
       full-bleed over the host's --sp-3 padding so the sheet is flush on all
       three edges (no 12px gutter) and seals below its top edge. */
    margin: auto calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3));
}
/* Full-bleeding over the side padding makes the modal body's scrollWidth exceed
   its client width by a phantom sliver; clip it so no horizontal scrollbar. NOT
   applied to .sheet-pane: making the pane a scroll container steals the sticky
   footer's scrollport from the real scroller (.offcanvas-body), which un-pins the
   sheet on mobile. The mobile sheet's host is border-box (no phantom sliver), so
   it needs no guard. (The desktop drawer panel already clips overflow-x inline.) */
.region-modal-body:has(.pw-gate) { overflow-x: hidden; }
/* .offcanvas-body has padding 0 (styles.css), so the -12px base offset used for
   the 12px-padded modal/drawer hosts would rest the sheet 12px too low here —
   pin it flush to the offcanvas edge instead. */
.sheet-pane > .pw-gate > .pw-footer { bottom: 0; }

/* Fade scrim that RIDES WITH the sticky footer. The old approach masked the gated
   CONTENT's own bottom edge, so the dissolve sat at the content's TRUE end — far
   below the sticky footer whenever the user scrolled up, leaving crisp content
   pinned right above the CTA. Instead we paint a soft fade band directly above the
   footer's top edge with a .pw-footer::before. Because .pw-footer is sticky (it
   establishes the containing block for this absolute child), the band rides at the
   same viewport height on EVERY scroll offset — so content is always softened just
   before it reaches the CTA, not only when its natural end is in view.
   It fades UP from the warm ground (--page-bg — the same ground the content sits
   on in every host: modal body / drawer host / sheet pane) to transparent, so the
   content dissolves into that ground with no new color introduced, then meets the
   footer's own crisp top border below. The content itself carries NO mask now, so
   there is exactly ONE fade band (no doubled effect). pointer-events:none keeps the
   band from swallowing taps.
   OPACITY CAP: the fade tops out at ~90% --page-bg (never full 100%) and HOLDS
   that 90% for the bottom stretch right above the CTA, so the content there is
   clearly obscured but a faint hint still shows through — never a fully blank
   band ("no content at all"). It ramps from that held 90% up to transparent. */
.pw-footer::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;                            /* sit flush on the footer's top edge, extend upward */
    height: 64px;
    pointer-events: none;
    /* Fallback for browsers without color-mix() (old Safari/Chrome): a plain
       90%-page-bg -> transparent ramp (page-bg is the fixed #f8f6f3). Without it
       the whole `background` would be dropped and crisp content would sit against
       the CTA. The color-mix line below overrides it (adding the short 90% hold)
       where supported. */
    background: linear-gradient(to top, rgba(248, 246, 243, 0.9), transparent);
    background: linear-gradient(to top,
        color-mix(in srgb, var(--page-bg) 90%, transparent) 0%,   /* held 90% cap right above the CTA */
        color-mix(in srgb, var(--page-bg) 90%, transparent) 20%,  /* short hold so it never reads as blank */
        transparent 100%);                                        /* smooth ramp to clear going up */
}
/* Keep the sheet itself painting ABOVE the fade band so its upward separator
   shadow (inline in gating.py) still reads as a crisp line, not covered by the
   pseudo-element. The sheet is the footer's only child. */
.pw-footer > div { position: relative; }


/* ---- Inline CTA (mostly-free tabs: Reports donut, Overview bar) -------------
   The full E-1 subscribe block, one tier smaller (gating.inline_cta). It sits as
   a plain SIBLING directly below the blurred .pw-blur species content — static
   flow, so NO sticky, NO high z-index, NO dissolve (that's the footer card's
   job). A top hairline + top padding set it off from the blurred block above.
   Being a sibling (not a child) of .pw-blur is what keeps the button clickable —
   .pw-blur sets pointer-events:none, which would kill a nested button. */
.pw-inline-cta {
    margin-top: var(--sp-4);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--border);
    position: relative;
}

/* Overview's pin popover is a narrow micro-surface (capped ~336px), so tighten
   the inline CTA's top gap + hairline padding there. This one selector covers
   both the desktop hover popover and the mobile tap popover — the inline CTA is
   a descendant of .ov-pin-popover in both. */
.ov-pin-popover .pw-inline-cta {
    margin-top: var(--sp-3);
    padding-top: var(--sp-3);
}


/* ---- Skeleton primitives (empty structure, keep the labels) ----------------
   Neutral grey tracks / chips / rings. Legacy primitives from the earlier
   skeleton approach; the Outlook and Trends surfaces now use blurred GHOST
   DECOYS (fake, representative shapes) instead of empty skeletons — kept here
   only for any remaining callers. Neutral grey, no data. */
.pw-skel {
    background: #e6e8ee;
    border-radius: 5px;
    display: inline-block;
}
.pw-skel-pill { border-radius: 999px; }
