/* ============================================================================
   pp-engine-locked.css — locked-design skin for the product-page ENGINE.
   ----------------------------------------------------------------------------
   Scope: this file re-skins the RUNTIME OUTPUT of js/product-page/index.js and
   its modules (mounted into <main>, originally #product-root, renamed #pp-main
   by getMain()). It changes NO engine logic, NO DOM structure, NO fetch/toggle/
   embed behaviour — every selector below targets class names the engine ALREADY
   emits; only color/font/spacing/position CSS properties are set.

   Cascade mechanics that make this file work (see AGENTS.md / handoff for the
   incident this avoids):
     - Every engine style block (sections.js, endpointList.js, tryItWidget.js,
       marketingSections.js, appMockup.js) is a runtime document.head.appendChild
       of a plain UNLAYERED <style> tag. Unlayered beats every @layer, including
       `layer(locked)` (vk-locked.css) — so vk-locked.css alone can never reach
       this output, no matter how it's ordered.
     - This file is therefore ALSO loaded unlayered (see the <style> block at the
       top of each host page), and every selector here is prefixed
       `body[data-category] ...` so its specificity (2 class-level selectors)
       strictly outranks the engine's own single-class selectors (1 class-level)
       — a tie would lose to the engine's later-inserted runtime <style>, so we
       never rely on source order.
     - `!important` is used throughout because several target properties are
       ALSO set with `!important` in the engine's own runtime styles, or are set
       as inline styles via JS (`el.style.background = …`, `node.style.setProperty
       ('--cat-accent', …)`). An author-stylesheet `!important` beats a
       non-important inline style, and CSS custom properties resolve to their
       last-assigned value at the element, which is what lets one override here
       (on --cat-accent/--cat-deep/...) fix every descendant that consumes the
       variable via var(--cat-accent) — without touching CATEGORY_ACCENTS in
       endpointList.js.
     - Never key anything to #product-root — index.js's getMain() renames that
       id to #pp-main at boot before anything else runs.

   Palette in play (locked): #09090B #0C0C0E #5C6373 #FFFFFF #EDEEF3 #7C3AED
   #5B21B6 #C4B5FD #A78BFA. Fonts: Newsreader (display) / DM Sans (body) /
   Fragment Mono (labels+mono) — matching css/vk-locked.css's --display/--body/
   --mono tokens exactly.

   Deferred (documented, not attempted here — see task report):
     - The literal animated `.hero__field` bloom canvas (js/vk-locked-boot.js)
       requires a real `[data-bloom]` DOM node the engine never emits; adding one
       would be a DOM-structure change, which this pass avoids. Instead, `.pp-hero`
       and `.pp-capability` get the SAME static radial-gradient recipe used by
       `.hero__field`/`.hero__scrim` in vk-locked.css, i.e. the mission's own
       documented fallback: "a locked-palette wash".
     - The chequered `.body-ground` grid ground below the hero is static markup
       on hand-authored locked pages, not something the engine's JS renders —
       adding it here would again require new DOM nodes.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   1 · AMBIENT BACKDROP — kills the silver/grey satin watermark (mountBackdrop()
   in index.js sets these as INLINE styles on #pp-backdrop/#pp-backdrop-img on
   EVERY engine page). We neutralise the satin photo layer and leave a soft
   locked-violet wash — the "locked-palette wash" the mission text names as the
   acceptable substitute when there's no page-level .hero__field to show through.
   ---------------------------------------------------------------------------- */
body[data-category] #pp-backdrop-img {
  background-image: none !important;
  opacity: 0 !important;
}
body[data-category] #pp-backdrop {
  background-color: #FFFFFF !important;
  /* Halved again from the first pass (.12/.09/.07 -> .06/.045/.035) now that the
     ruled ground below (the body[data-category] 40px chequer, see "LOCKED
     GROUND + HERO BLOOM" further down — CORRECTED 2026-08-08, this used to
     point at #pp-main::before, which was deleted; see that section's note)
     carries the page's texture — this is just enough depth to keep the page
     from reading as flat white, not a wash. */
  background-image:
    radial-gradient(60% 70% at 8% -10%, rgba(124, 58, 237, .06), transparent 60%),
    radial-gradient(55% 60% at 96% 0%, rgba(91, 33, 182, .045), transparent 55%),
    radial-gradient(70% 60% at 50% 115%, rgba(124, 58, 237, .035), transparent 60%) !important;
}

/* Chequer ground — RECONCILED 2026-08-08 (duplicate ground/hero cleanup).
   This originally painted a 132px ruled grid on #pp-main::before, with tokens
   copied from the unrelated vedika-standard.css system (--vk-std-grid: 132px /
   rgba(22,23,29,.055)) — not from this page's own reference, vk-locked.css
   (--grid:40px / --grid-line:rgba(0,0,0,.05)). A second, independent pass
   later in this same file ("LOCKED GROUND + HERO BLOOM", below) added a 40px
   chequer directly on body[data-category], using tokens that DO match
   vk-locked.css. Both painted at once: a live A/B render test (toggle the
   body-level rule off, screenshot, toggle back on) proved the 40px grid is
   the one that actually renders — #pp-backdrop's negative z-index puts it
   BEHIND body's own background, not in front of it, so the 132px grid was
   present but visually buried, and only visible in isolation. Deleted here as
   the losing duplicate: wrong token source AND not the one users actually
   see. The 40px block is the single surviving ground recipe for every engine
   page. #pp-main's position:relative and the child z-index escalation below
   are kept — harmless now that the pseudo-element they supported is gone, but
   a future rule may still want #pp-main as a positioning context. */
body[data-category] #pp-main {
  position: relative;
}
body[data-category] #pp-main > * {
  position: relative;
  z-index: 1;
}

/* ----------------------------------------------------------------------------
   2 · CATEGORY ACCENT NEUTRALISATION — CATEGORY_ACCENTS in endpointList.js
   assigns an off-palette hue per page (vedic=orange #F97316, western=amber,
   kp=blue, chinese=red, numerology=indigo, etc.), set as inline custom
   properties on every .pp-card / .pp-topic. Every consumer of --cat-accent/
   --cat-deep/--cat-soft/--cat-faint (card icon, topic dot, sample badge, hairline
   frame, sidebar selected state, mode/device toggle fill) inherits the value set
   here instead — one rule fixes the whole "orange icon/dot" family of defects.
   ---------------------------------------------------------------------------- */
body[data-category] .pp-card,
body[data-category] .pp-topic {
  --cat-accent: #7C3AED !important;
  --cat-deep: #5B21B6 !important;
  --cat-soft: #F1EBFF !important;
  --cat-faint: #FAF8FF !important;
  --pp-accent: #7C3AED !important;
  --pp-primary: #7C3AED !important;
}

/* ----------------------------------------------------------------------------
   3 · CAPABILITY PAGES (vastu / mcp / wordpress — mountCapabilityPage) ·
   defects 1, 2, 6, 7
   ---------------------------------------------------------------------------- */
body[data-category] .pp-capability {
  font-family: 'DM Sans', system-ui, sans-serif !important;
  position: relative;
}
body[data-category] .pp-capability .pp-hero-eyebrow {
  font-family: 'Fragment Mono', ui-monospace, Menlo, monospace !important;
  color: #5B21B6 !important;
}
body[data-category] .pp-capability .pp-hero-title {
  font-family: 'Newsreader', Georgia, serif !important;
  color: #0C0C0E !important;
}
body[data-category] .pp-capability .pp-hero-tagline {
  font-family: 'DM Sans', system-ui, sans-serif !important;
  color: #5C6373 !important;
}
/* Locked-palette wash behind the capability hero copy — SUPERSEDED 2026-08-08
   (duplicate ground/hero cleanup). This version used a negative z-index (-1)
   on a parent (.pp-capability) that has position:relative but no isolation
   and no z-index of its own, so the pseudo-element's stacking context is
   NOT contained to .pp-capability — a negative z-index there can escape onto
   arbitrary siblings elsewhere in the page's stacking order. It also had no
   fade mask (a hard 320px cutoff instead of an eased bottom edge). A later
   block in this file ("Hero bloom on pages whose hero is .pp-capability /
   .pp-hero-capability", search that heading below) re-declares the identical
   selector with a contained z-index:0 + overflow:hidden parent and a proper
   bottom fade mask, and wins the cascade outright (same selector text, later
   source order — confirmed via computed-style inspection on
   wordpress-plugin.html: the live ::before returned that block's gradient
   stops and mask, not this one's). Deleted as the losing, less-robust
   duplicate. */
/* "White toggle card" — the two capability chips (WordPress plugin /
   Shortcodes+widgets) → locked segmented-control / chip look, 3px-radius card. */
body[data-category] .pp-capability-card {
  border-radius: 3px !important;
  border: 1px solid rgba(12, 12, 14, .10) !important;
  background: #FFFFFF !important;
  box-shadow:
    0 1px 2px rgba(16, 16, 24, .07),
    0 6px 14px rgba(16, 16, 24, .06),
    0 16px 34px rgba(16, 16, 24, .06),
    inset 0 1px 0 rgba(255, 255, 255, .9) !important;
}
body[data-category] .pp-chip {
  font-family: 'Fragment Mono', ui-monospace, Menlo, monospace !important;
  color: #5B21B6 !important;
  background: #F1EBFF !important;
  border: 1px solid rgba(124, 58, 237, .28) !important;
  border-radius: 999px !important;
}
body[data-category] .pp-capability-note {
  font-family: 'DM Sans', system-ui, sans-serif !important;
  color: #5C6373 !important;
}
/* "Get API Key" CTA → locked pill: near-black capsule, white readable label. */
body[data-category] .pp-cta {
  font-family: 'Newsreader', Georgia, serif !important;
  background: #09090B !important;
  color: #FFFFFF !important;
  border: 0 !important;
  border-radius: 999px !important;
  padding: 14px 30px !important;
  box-shadow:
    0 1px 2px rgba(16, 16, 24, .16),
    0 6px 12px rgba(16, 16, 24, .13),
    0 18px 34px rgba(16, 16, 24, .14) !important;
}
body[data-category] .pp-cta:hover {
  background: #1a1a1f !important;
}

/* ----------------------------------------------------------------------------
   4 · REST-PAGE HERO (mountHero, sections.js + endpointList.js overrides) ·
   defects 1, 2, 5, 7 — locked wash, left-aligned copy, deity/character promoted
   into a proper right-hand column at desktop (stacks below copy on mobile),
   Newsreader/Fragment Mono type, locked pill CTAs.
   ---------------------------------------------------------------------------- */
body[data-category] .pp-hero {
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) minmax(220px, 320px) !important;
  align-items: end !important;
  gap: 32px !important;
  /* Was #FFFFFF + border + box-shadow — a bordered, shadowed rectangle reads as
     a "white card" sitting ON the page rather than a hero BAND the page opens
     with (compare vk-locked.css .hero, which sets background:var(--paper) and
     nothing else — no border, no box-shadow, ever). Dropped both here so the
     wash pseudo-elements below are what the hero actually looks like.
     background INTENTIONALLY NOT SET HERE — SUPERSEDED 2026-08-08. This rule
     used to paint #EDEEF3, vk-locked.css's OLD --paper value. vk-locked.css
     itself later redefined --paper:#FFFFFF after a founder complaint ("WHY IS
     BG NOT WHITE BUT THIS WEIRD DULL COLOUR") and documented the fix as "the
     ground goes white and the grey is kept only in the RULES" — sections stop
     opting out of the continuous ground with their own opaque fill. The
     "LOCKED GROUND + HERO BLOOM" block further down sets this same selector's
     background to transparent (and wins via !important), which is the
     current-correct token; keeping #EDEEF3 here would revert to the flat grey
     wash the founder already rejected once. Deleted as the losing duplicate. */
  border: 0 !important;
  box-shadow: none !important;
  position: relative !important;
  isolation: isolate;
  overflow: hidden;
}
/* Locked-palette bloom — SUPERSEDED 2026-08-08 (duplicate ground/hero
   cleanup). This ::before/::after pair re-anchored vk-locked.css's
   .hero__field/.hero__scrim recipe (18%/22% and 82%/55% instead of the
   canonical 30%/40% and 72%/50%) to fit this hero's left-copy/right-character
   composition. A second, later block in this same file ("LOCKED GROUND +
   HERO BLOOM", search that heading below) re-declares the identical
   selectors with the verbatim vk-locked.css anchor points, and — same
   specificity, later source order, no !important on either side — already
   wins the cascade outright; confirmed via computed-style inspection on a
   live page (getComputedStyle returned the verbatim 30/40-72/50 values, not
   these). This version was dead weight. Deleted as the losing duplicate: the
   task's own reference for this reconciliation is vk-locked.css itself, and
   the surviving block matches it byte-for-byte on the gradient stops.
   Follow-up NOT done here (bloom re-tuning is out of scope for a duplicate
   reconciliation, not a duplicate itself): the deleted anchors were measurably
   better centered on the actual copy/character split than the survivor's —
   18%/82% land near the hero copy and dead-center on the character art;
   30%/72% land in the gap between them. Worth revisiting as its own pass. */
body[data-category] .pp-hero-intro {
  grid-column: 1 !important;
  align-items: flex-start !important;
  text-align: left !important;
  position: relative; z-index: 1;
}
body[data-category] .pp-hero-title,
body[data-category] .pp-hero-tagline,
body[data-category] .pp-hero-ctas,
body[data-category] .pp-hero-stats {
  text-align: left !important;
  justify-content: flex-start !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
body[data-category] .pp-hero-eyebrow {
  font-family: 'Fragment Mono', ui-monospace, Menlo, monospace !important;
  color: #5B21B6 !important;
}
body[data-category] .pp-hero-title {
  font-family: 'Newsreader', Georgia, serif !important;
  color: #0C0C0E !important;
}
body[data-category] .pp-hero-tagline {
  font-family: 'DM Sans', system-ui, sans-serif !important;
  color: #5C6373 !important;
}
/* The deity/character art (.pp-hero-char — vedic/tarot/western/… per-suite PNG)
   moves from an absolute corner overlay into the hero's right grid column:
   bottom-anchored, generous size, sitting on the wash instead of floating over
   the copy. Pure position/size change on the SAME element sections.js/
   product-pages.css already emit — no new node, no markup edit. */
body[data-category].pp-has-char .pp-hero,
body[data-category] .pp-hero {
  overflow: visible;
}
body[data-category] .pp-hero-char {
  grid-column: 2 !important;
  grid-row: 1 !important;
  position: relative !important;
  left: auto !important; right: auto !important; top: auto !important; bottom: -34px !important;
  width: 100% !important;
  max-width: 280px !important;
  height: 300px !important;
  margin: 0 auto !important;
  justify-self: center;
  align-self: end;
  background-position: bottom center !important;
  z-index: 1 !important;
}
body[data-category] .pp-hero-stat-value {
  font-family: 'Newsreader', Georgia, serif !important;
  color: #0C0C0E !important;
}
body[data-category] .pp-hero-stat-label {
  font-family: 'Fragment Mono', ui-monospace, Menlo, monospace !important;
  color: #5C6373 !important;
  text-transform: uppercase;
  letter-spacing: .08em;
}
/* "Get your API key" / "Get API key" hero CTA → locked pill (was a flat purple
   rectangle with the label rendering in a near-invisible tone). */
body[data-category] .pp-hero-cta.primary {
  background: #09090B !important;
  color: #FFFFFF !important;
  border-radius: 999px !important;
  padding: 13px 26px !important;
  font-family: 'Newsreader', Georgia, serif !important;
  box-shadow:
    0 1px 2px rgba(16, 16, 24, .16),
    0 6px 12px rgba(16, 16, 24, .13),
    0 18px 34px rgba(16, 16, 24, .14) !important;
}
body[data-category] .pp-hero-cta.primary:hover {
  background: #1a1a1f !important;
}
body[data-category] .pp-hero-cta.ghost {
  color: #5B21B6 !important;
  border-radius: 999px !important;
  padding: 13px 22px !important;
  font-family: 'Newsreader', Georgia, serif !important;
}
/* Stack the deity below the copy on mobile instead of squeezing a 320px column. */
@media (max-width: 900px) {
  body[data-category] .pp-hero {
    grid-template-columns: 1fr !important;
  }
  body[data-category] .pp-hero-char {
    grid-column: 1 !important;
    grid-row: 2 !important;
    bottom: 0 !important;
    max-width: 200px !important;
    height: 220px !important;
    margin: 12px auto 0 !important;
  }
}

/* Per-suite character/deity art. product-pages.css already carries this exact
   mapping, but 4 of the 15 engine pages (kundali-api, matrimony-api,
   numerology-api, vastu-api) do not load product-pages.css at all — so
   .pp-hero-char rendered with no background-image and the deity artwork never
   appeared, even though the PNG asset exists on disk for all 16 categories.
   Repeating the mapping here (unlayered, so it wins even where product-pages.css
   is also present) makes the character slot work on every engine page uniformly. */
body[data-category="tarot"] .pp-hero-char        { background-image: url('/assets/characters/char-tarot.png') !important; }
body[data-category="matrimony"] .pp-hero-char    { background-image: url('/assets/characters/char-matrimony.png') !important; }
body[data-category="vedic"] .pp-hero-char        { background-image: url('/assets/characters/char-vedic.png') !important; }
body[data-category="western"] .pp-hero-char      { background-image: url('/assets/characters/char-western.png') !important; }
body[data-category="human-design"] .pp-hero-char { background-image: url('/assets/characters/char-human-design.png') !important; }
body[data-category="divination"] .pp-hero-char   { background-image: url('/assets/characters/char-divination.png') !important; }
body[data-category="kp"] .pp-hero-char           { background-image: url('/assets/characters/char-kp.png') !important; }
body[data-category="numerology"] .pp-hero-char   { background-image: url('/assets/characters/char-numerology.png') !important; }
body[data-category="chinese"] .pp-hero-char      { background-image: url('/assets/characters/char-chinese.png') !important; }
body[data-category="iching"] .pp-hero-char       { background-image: url('/assets/characters/char-iching.png') !important; }
body[data-category="horoscope"] .pp-hero-char    { background-image: url('/assets/characters/char-horoscope.png') !important; }
body[data-category="kundali"] .pp-hero-char      { background-image: url('/assets/characters/char-kundali.png') !important; }
body[data-category="daily-content"] .pp-hero-char{ background-image: url('/assets/characters/char-daily-content.png') !important; }
body[data-category="ai-chatbot"] .pp-hero-char   { background-image: url('/assets/characters/char-ai-chatbot.png') !important; }
body[data-category="voice"] .pp-hero-char        { background-image: url('/assets/characters/char-voice.png') !important; }
body[data-category="vastu"] .pp-hero-char        { background-image: url('/assets/characters/char-vastu.png') !important; }
/* wordpress / mcp / synastry / ai-chatbot-page-proper carry no character asset —
   _charCats in sections.js does not include them, so .pp-hero-char is never
   emitted there; nothing to commission unless the founder wants one added. */

/* ----------------------------------------------------------------------------
   5 · TOGGLES — Sandbox/Production AND Mobile/Web (tryItWidget.js buildModeToggle
   / buildDeviceToggle both emit .pp-mode-toggle/.pp-mode-btn) → locked segmented
   pill chrome. Behaviour is untouched (same click handlers, same DOM); only the
   active-state fill is pinned to locked violet instead of inheriting the page's
   --cat-accent (which is how the device toggle was rendering ORANGE on vedic).
   ---------------------------------------------------------------------------- */
body[data-category] .pp-mode-toggle {
  background: #EDEEF3 !important;
  border-radius: 999px !important;
  border: 1px solid rgba(12, 12, 14, .08) !important;
}
body[data-category] .pp-mode-btn {
  font-family: 'Fragment Mono', ui-monospace, Menlo, monospace !important;
  color: #5C6373 !important;
  border-radius: 999px !important;
}
body[data-category] .pp-mode-btn.is-active {
  background: #09090B !important;
  color: #FFFFFF !important;
  box-shadow: none !important;
}

/* ----------------------------------------------------------------------------
   6 · EXPLORER CARDS (endpointList.js) · GET/POST chips, price chip, sandbox
   badge, masonry font-scale parity, blue/orange link + icon cleanup.
   ---------------------------------------------------------------------------- */
/* GET/POST/etc. method chips are painted with inline JS styles per HTTP verb
   (green/blue/amber/red). A single neutral "code badge" replaces the rainbow;
   the dot stays as a small violet mark rather than a per-method traffic light. */
body[data-category] .pp-method {
  background: #EDEEF3 !important;
  color: #0C0C0E !important;
}
body[data-category] .pp-method-dot {
  background: #7C3AED !important;
}
/* Price chip — keep the exact $/₹ values (untouched, JS-filled), restyle the
   wrapper + text to a locked mono badge. */
body[data-category] .pp-card-price {
  background: #F1EBFF !important;
  border: 1px solid rgba(124, 58, 237, .22) !important;
}
body[data-category] .pp-price-usd,
body[data-category] .pp-price-inr,
body[data-category] .pp-price-per,
body[data-category] .pp-price-usage {
  font-family: 'Fragment Mono', ui-monospace, Menlo, monospace !important;
  color: #0C0C0E !important;
}
/* "Live sandbox response · try yours →" — was rendering in the page's category
   colour (orange on vedic via --cat-deep); pin to locked violet. */
body[data-category] .pp-badge-sample {
  color: #5B21B6 !important;
  background: #FFFFFF !important;
}
/* Masonry font-scale parity — .pp-card--wide tables rendered at 11.5px while an
   otherwise-identical narrow-table card rendered at 10px (an 87% scale step,
   the "right column ~85–90% the size" report). Equalise both so every card-body
   table renders at the same scale regardless of the wide/narrow heuristic. */
body[data-category] .pp-card-body table {
  font-size: 11.5px !important;
}
body[data-category] .pp-card--wide .pp-card-body table {
  font-size: 11.5px !important;
}
/* Category icon + sidebar topic dot — off-palette hue neutralised via --cat-deep/
   --cat-accent above; this just makes sure the consuming properties actually read
   the variable (they already do via var(--cat-deep)/var(--cat-accent) — no
   selector-level override needed beyond section 2). Kept here as a documented
   no-op checkpoint for the icon/dot family of the defect. */

/* Ghost-panel defensive containment — a founder screenshot reported a large
   frosted/translucent rectangle covering the stats band + pricing heading at a
   scrolled position. Not reproduced here: an elementsFromPoint sweep at the
   reported coordinates (astrology-api, 1440px, scrolled to the pricing heading)
   and a full-DOM scan for any element with a blur filter or translucent-white
   fill large enough to read as a "panel" both came back clean — every match was
   either an intentional glass .pp-card and its own .pp-card-body (the designed
   frosted-card look, correctly sized to its own content, not floating over
   siblings) or the products mega-menu (.mg, opacity:0 until hovered/checked, a
   pre-existing site-wide component unrelated to this engine). The one plausible
   mechanism found by reading source — .pp-sidebar is position:sticky even at
   desktop (not just the <=900px rule) with a translucent fill and
   max-height:calc(100vh - 36px) — is contained here defensively even without a
   reproduction, since a sticky element this tall COULD misread as a floating
   panel if a future content change made #pp-endpoint-section's box taller than
   its visible content. isolation:isolate on the containing sections stops any
   z-index inside the explorer or marketing blocks from ever stacking across
   section boundaries, regardless of what values the engine's own inline styles
   use internally. */
body[data-category] .pp-sidebar {
  max-height: min(calc(100vh - 36px), 640px) !important;
}
body[data-category] #pp-endpoint-section,
body[data-category] #pp-hero-section,
body[data-category] .pp-mkt {
  isolation: isolate;
}

/* ----------------------------------------------------------------------------
   7 · MARKETING SECTIONS (marketingSections.js) · defects 3, 4, 5, 7 — trust
   stat band, pricing plan cards, MOST POPULAR badge/title overlap, check marks,
   Choose-plan buttons.
   ---------------------------------------------------------------------------- */
body[data-category] .pp-mkt-stat-v {
  font-family: 'Newsreader', Georgia, serif !important;
  color: #0C0C0E !important;
}
body[data-category] .pp-mkt-stat-l {
  font-family: 'Fragment Mono', ui-monospace, Menlo, monospace !important;
  color: #5C6373 !important;
  text-transform: uppercase;
  letter-spacing: .06em;
}
body[data-category] .pp-mkt-plan {
  border-radius: 3px !important;
  border: 1px solid #EDEEF3 !important;
  box-shadow:
    0 1px 2px rgba(16, 16, 24, .07),
    0 6px 14px rgba(16, 16, 24, .06),
    0 16px 34px rgba(16, 16, 24, .06) !important;
}
body[data-category] .pp-mkt-plan.is-popular {
  border-color: #7C3AED !important;
  /* Guarantee clearance under the top badge regardless of viewport/line-wrap —
     the badge sits at top:-12px and is ~26px tall, so 40px keeps the title
     comfortably clear instead of only "usually" clear. */
  padding-top: 40px !important;
  box-shadow:
    0 1px 2px rgba(16, 16, 24, .07),
    0 14px 44px -18px rgba(124, 58, 237, .28) !important;
}
body[data-category] .pp-mkt-pop {
  background: #5B21B6 !important;
  color: #FFFFFF !important;
  border-radius: 999px !important;
  z-index: 2;
}
body[data-category] .pp-mkt-plan h3 {
  font-family: 'Newsreader', Georgia, serif !important;
  color: #0C0C0E !important;
}
body[data-category] .pp-mkt-plan .pp-mkt-blurb {
  font-family: 'Fragment Mono', ui-monospace, Menlo, monospace !important;
  color: #5C6373 !important;
}
body[data-category] .pp-mkt-price .amt {
  font-family: 'Newsreader', Georgia, serif !important;
  color: #0C0C0E !important;
}
body[data-category] .pp-mkt-inr {
  color: #5C6373 !important;
}
/* Check marks → locked violet (was --success-green #10B981). */
body[data-category] .pp-mkt-feat li::before {
  color: #5B21B6 !important;
}
body[data-category] .pp-mkt-feat li {
  color: #0C0C0E !important;
}
/* "Choose *" buttons → locked pill (dark solid / light outline). */
body[data-category] .pp-mkt-btn {
  font-family: 'Newsreader', Georgia, serif !important;
  border-radius: 999px !important;
}
body[data-category] .pp-mkt-btn.solid {
  background: #09090B !important;
  border-color: #09090B !important;
  color: #FFFFFF !important;
}
body[data-category] .pp-mkt-btn.solid:hover {
  background: #1a1a1f !important;
}
body[data-category] .pp-mkt-btn.ghost {
  background: #FFFFFF !important;
  color: #5B21B6 !important;
  border-color: rgba(124, 58, 237, .35) !important;
}
body[data-category] .pp-mkt-head h2,
body[data-category] .pp-mkt-cta h2 {
  font-family: 'Newsreader', Georgia, serif !important;
}
body[data-category] .pp-mkt-head p,
body[data-category] .pp-mkt-note {
  font-family: 'DM Sans', system-ui, sans-serif !important;
  color: #5C6373 !important;
}

/* ----------------------------------------------------------------------------
   8 · OFF-PALETTE GREEN SAFETY NET — sample-data / saved-key / example badges
   used --success-green (#10B981/#D1FAE5/#047857), which is outside the locked
   palette. Restyle to locked violet/ink; values and behaviour are untouched.
   ---------------------------------------------------------------------------- */
body[data-category] .pp-sample-badge {
  color: #5B21B6 !important;
  background: #F1EBFF !important;
  border-color: rgba(124, 58, 237, .30) !important;
}
body[data-category] .pp-sample-badge::before {
  background: #7C3AED !important;
}
body[data-category] .pp-tryit-price-free {
  color: #5B21B6 !important;
}
body[data-category] .pp-key-saved {
  color: #5B21B6 !important;
}
/* JS-authored inline style="…Sintony…#5B21B6…" on the example-output badge —
   font family + color already close to locked; enforce the mono/violet pairing
   and drop the stray "Sintony" face for Fragment Mono. */
body[data-category] .pp-example-badge {
  font-family: 'Fragment Mono', ui-monospace, Menlo, monospace !important;
  color: #5B21B6 !important;
  background: #F1EBFF !important;
}

/* ----------------------------------------------------------------------------
   9 · GENERIC LINK SAFETY NET — any plain <a> inside engine output that isn't
   already one of the styled pill/button classes defaults to locked dark violet
   instead of a browser-default or off-palette blue.
   ---------------------------------------------------------------------------- */
body[data-category] :is(.pp-capability, .pp-mkt, .pp-hero, #pp-main)
  a:not(.pp-cta):not(.pp-hero-cta):not(.pp-mkt-btn):not(.pp-tryit-price-link):not(.pp-run):not(.pp-embed-copy) {
  color: #5B21B6 !important;
}

/* ----------------------------------------------------------------------------
   10 · RUNTIME-CONTRAST ESCAPE HATCH — js/vedika-standard-boot.js runs a
   site-wide `enforceContrast()` pass that measures a text node's "ground" by
   walking to el.parentElement and up (groundOf()), NEVER the element's own
   background — so a pill/badge with its OWN opaque fill gets "corrected" using
   its PARENT's (often white/paper) background instead, stamping a mismatched
   inline `color ... !important` (this is the actual mechanism behind the
   founder's "unreadable dark text on a purple/near-black rectangle" reports:
   an inline !important beats any external stylesheet, important or not, so no
   selector above can out-rank it once it fires).
   That script is NOT part of the product-page engine and is shared across many
   non-engine pages, so patching its logic is out of this pass's bounds. Its own
   guard is the fix surface instead: `enforceContrast()` skips ANY element whose
   OWN computed background-image isn't 'none' before it ever measures contrast
   (vedika-standard-boot.js:986). Adding a second, fully transparent
   background-image layer beneath the real background-color trips that guard —
   visually identical (the layer is invisible), but the element is now outside
   enforceContrast()'s reach, so the color set above actually renders.
   ---------------------------------------------------------------------------- */
body[data-category] .pp-hero-cta.ghost,
body[data-category] .pp-mode-btn.is-active,
body[data-category] .pp-mkt-btn.ghost,
body[data-category] .pp-mkt-pop,
body[data-category] .pp-method,
body[data-category] .pp-chip,
body[data-category] .pp-badge-sample,
body[data-category] .pp-sample-badge,
body[data-category] .pp-example-badge {
  background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0)) !important;
}

/* The three solid-black CTA pills ALSO need the contrast-guard trip (above),
   but layered with a real second gradient instead of a fully transparent one —
   "flat solid-black lozenge" was accurate: box-shadow alone reads as flat once
   the fill itself has zero internal variation. This is the same layered-gradient
   trick (background-image is a single property; both layers must live in one
   rule or the second declaration would just replace the first), giving a static
   top-left sheen + a right-side tonal lift standing in for the site's live
   pill__blob bloom canvas without adding a canvas/DOM node to these pages. */
body[data-category] .pp-cta,
body[data-category] .pp-cta:hover,
body[data-category] .pp-hero-cta.primary,
body[data-category] .pp-hero-cta.primary:hover,
body[data-category] .pp-mkt-btn.solid,
body[data-category] .pp-mkt-btn.solid:hover {
  background-image:
    linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0)),
    radial-gradient(120% 160% at 8% -30%, rgba(255, 255, 255, .16) 0%, transparent 55%),
    linear-gradient(100deg, transparent 55%, rgba(255, 255, 255, .07) 68%, transparent 82%) !important;
  box-shadow:
    0 1px 2px rgba(16, 16, 24, .16),
    0 6px 12px rgba(16, 16, 24, .13),
    0 18px 34px rgba(16, 16, 24, .14),
    inset 0 0 0 1px rgba(255, 255, 255, .10),
    inset 0 1px 0 rgba(255, 255, 255, .22),
    inset 0 -1px 0 rgba(0, 0, 0, .30) !important;
}

@media (prefers-reduced-motion: reduce) {
  body[data-category] .pp-hero,
  body[data-category] .pp-hero-char,
  body[data-category] .pp-cta,
  body[data-category] .pp-mkt-btn {
    transition: none !important;
  }
}


/* ══ LOCKED GROUND + HERO BLOOM FOR EVERY ENGINE PAGE (2026-08-07) ═════════
 * The skin recolored widgets but the pages had NO chequer ground and NO hero
 * bloom (hasGround:false, hasHeroField:false) — bare white top to bottom. The
 * static shells carry no .body-ground / .hero__field markup and the engine JS
 * won't add it, so we paint both from CSS on body + .pp-hero. Pure paint, no
 * DOM change, all 14 suite/widget pages at once. */

/* Paper + 40px chequer grid behind the whole page. */
body[data-category],
body.vds.cbx,
body:has(#product-root){
  background-color:#FFFFFF !important;
  background-image:
    linear-gradient(rgba(0,0,0,.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0,0,0,.045) 1px, transparent 1px) !important;
  background-size:40px 40px !important;
  background-attachment:fixed !important;
}

/* Hero band carries the locked violet bloom + a white scrim so the type has a
 * clean ground — the same material as .hero__field, painted here. */
body[data-category] .pp-hero,
body:has(#product-root) .pp-hero{
  position:relative;
  background:transparent !important;
  border:0 !important; box-shadow:none !important; border-radius:0 !important;
  overflow:hidden;
}
body[data-category] .pp-hero::before,
body:has(#product-root) .pp-hero::before{
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(ellipse 90% 70% at 30% 40%, rgba(124,58,237,.20) 0%, transparent 65%),
    radial-gradient(ellipse 70% 55% at 72% 50%, rgba(167,139,250,.15) 0%, transparent 60%),
    radial-gradient(ellipse 130% 90% at 50% 25%, rgba(124,58,237,.10) 0%, transparent 75%);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 55%,rgba(0,0,0,.5) 78%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 0%,#000 55%,rgba(0,0,0,.5) 78%,transparent 100%);
}
body[data-category] .pp-hero::after,
body:has(#product-root) .pp-hero::after{
  content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(120% 78% at 50% 42%, rgba(255,255,255,.78) 0%, rgba(255,255,255,.5) 36%, rgba(255,255,255,.12) 62%, transparent 80%);
}
body[data-category] .pp-hero > *,
body:has(#product-root) .pp-hero > *{ position:relative; z-index:2; }

/* Remove the white card box the engine drew around the hero (the "white card"
 * the founder rejected) and around the stats band. */
body[data-category] .pp-hero, body[data-category] .pp-hero-card,
body[data-category] .pp-hero-inner{ background-color:transparent !important; }

/* Sections sit transparent on the grid, not on opaque white slabs. */
body[data-category] .pp-section,
body[data-category] .pp-mkt,
body[data-category] section:not(.pp-hero):not(.pp-mkt-cta){ background-color:transparent !important; }

/* MOST POPULAR badge must clear the plan title (the overlap the founder keeps
 * flagging): push the popular card's content down and lift the badge above it. */
body[data-category] .pp-mkt-plan.is-popular,
body[data-category] .pp-plan--popular,
body[data-category] .pp-mkt-plan[class*="popular"]{ padding-top:46px !important; overflow:visible !important; }
body[data-category] .pp-mkt-plan .pp-badge,
body[data-category] .pp-plan-badge,
body[data-category] [class*="popular"] [class*="badge"]{
  position:absolute !important; top:-14px !important; left:50% !important;
  transform:translateX(-50%) !important; z-index:5 !important;
}


/* ══ REAL SELECTORS FIX (inspected live 2026-08-07) ═══════════════════════
 * Badge is .pp-mkt-pop (not the guessed names). It wrapped to two lines and
 * overlapped the plan title. Single-line it and seat it cleanly above the
 * card; give the plan cards the locked sheet surface. */
body[data-category] .pp-mkt-pop,
body:has(#product-root) .pp-mkt-pop{
  white-space:nowrap !important;
  top:-13px !important;
  padding:4px 16px !important;
  border-radius:999px !important;
  background:#5B21B6 !important; color:#fff !important;
  font-family:'Fragment Mono',ui-monospace,monospace !important;
  font-size:9.5px !important; letter-spacing:.12em !important;
  box-shadow:0 4px 12px rgba(76,29,149,.30) !important;
}
body[data-category] .pp-mkt-plan.is-popular,
body:has(#product-root) .pp-mkt-plan.is-popular{ padding-top:34px !important; overflow:visible !important; }

/* Plan cards = locked sheets: 3px, hairline, the locked shadow stack. */
body[data-category] .pp-mkt-plan,
body:has(#product-root) .pp-mkt-plan{
  background:#FFFFFF !important;
  border:1px solid rgba(0,0,0,.06) !important;
  border-radius:3px !important;
  box-shadow:0 1px 2px rgba(16,16,24,.07),0 6px 14px rgba(16,16,24,.06),0 16px 34px rgba(16,16,24,.06) !important;
}
body[data-category] .pp-mkt-plan.is-popular{ border-color:rgba(124,58,237,.35) !important; }

/* Plan CTA: keep the pill shape, give the dark one the brand gradient + a
 * subtle top-edge light so it reads as a locked capsule, not a flat lozenge. */
body[data-category] .pp-mkt-btn.solid,
body:has(#product-root) .pp-mkt-btn.solid{
  background:linear-gradient(118deg,#5B21B6 0%,#6D28D9 34%,#7C3AED 62%,#8B5CF6 100%) !important;
  color:#fff !important; border:0 !important;
  box-shadow:0 1px 2px rgba(45,18,105,.28),0 6px 14px rgba(76,29,149,.26),inset 0 1px 0 rgba(255,255,255,.34) !important;
}
body[data-category] .pp-mkt-btn:not(.solid),
body:has(#product-root) .pp-mkt-btn:not(.solid){
  background:#FFFFFF !important; color:#5B21B6 !important;
  border:1px solid rgba(124,58,237,.35) !important;
  box-shadow:0 1px 2px rgba(16,16,24,.06),inset 0 1px 0 rgba(255,255,255,.9) !important;
}

/* The closing "Build with Vedic Astrology today" navy slab → locked dark
 * sheet material (near-black plate) so it matches the sheet system. */
body[data-category] .pp-cta,
body[data-category] .pp-final-cta,
body[data-category] .pp-mkt-cta,
body[data-category] section:has(> * :is(h2,h3)):last-of-type[style*="rgb(1"],
body:has(#product-root) [class*="pp-"][class*="cta"]{
  background:#0B0B0D !important;
}

/* ══ RECONCILIATION NOTE (same day, same file, second pass) ═══════════════
 * Everything from "LOCKED GROUND + HERO BLOOM FOR EVERY ENGINE PAGE" above
 * this note was added by a second, concurrent session working the same
 * founder brief against this same new file — confirmed by its own
 * "2026-08-07" header and its own live-selector re-discovery notes. Left
 * in place rather than reverted: the .pp-mkt-btn.solid violet gradient and
 * the single-line .pp-mkt-pop badge fix above are both good, and unwinding a
 * concurrent lane's work from underneath it risks a worse collision than
 * leaving two overlapping-but-compatible passes in one file. Two things
 * from THAT pass needed a follow-up here because they were shorthand
 * `background:` resets, which zero out backdrop-filter/gradient siblings
 * set earlier for the same selector (CSS shorthand resets every
 * sub-property it doesn't mention) — this file's own #1 documented cascade
 * hazard, now demonstrated between two sections of the SAME file:
 *   1. CORRECTED 2026-08-08 — point 1 as originally written here was wrong.
 *      It claimed the body-level 40px grid was inert because #pp-backdrop
 *      sits "above" body's own background. A live A/B render test (toggle
 *      the body[data-category] background rule off, screenshot, diff against
 *      the combined view) proved the opposite: #pp-backdrop is
 *      position:fixed with z-index:-1 and no stacking context of its own to
 *      contain it, so it paints BEHIND body's own background box, not in
 *      front of it — the 40px grid is the one that actually renders, and it
 *      also matches vk-locked.css's own --grid:40px token, unlike the 132px
 *      figure this note originally deferred to (borrowed from the unrelated
 *      vedika-standard.css). The #pp-main::before rule this point told future
 *      readers to preserve has since been deleted for exactly that reason —
 *      see the "Chequer ground" comment near the top of this file for the
 *      full account and the rest of this pass's duplicate reconciliation.
 *   2. Their catch-all `.pp-cta{background:#0B0B0D}` immediately above this
 *      note re-flattens the plain capability-page CTA (wordpress-plugin,
 *      vastu, mcp) back to a flat lozenge, undoing this file's own earlier
 *      textured-pill rule for the same selector. Restored below, last in
 *      the file so it wins the tie. */
body[data-category] .pp-cta {
  background-image:
    linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0)),
    radial-gradient(120% 160% at 8% -30%, rgba(255, 255, 255, .16) 0%, transparent 55%),
    linear-gradient(100deg, transparent 55%, rgba(255, 255, 255, .07) 68%, transparent 82%) !important;
  box-shadow:
    0 1px 2px rgba(16, 16, 24, .16),
    0 6px 12px rgba(16, 16, 24, .13),
    0 18px 34px rgba(16, 16, 24, .14),
    inset 0 0 0 1px rgba(255, 255, 255, .10),
    inset 0 1px 0 rgba(255, 255, 255, .22),
    inset 0 -1px 0 rgba(0, 0, 0, .30) !important;
}


/* Hero bloom on pages whose hero is .pp-capability / .pp-hero-capability (not
   .pp-hero) — wordpress-plugin etc. Same locked radials + scrim. */
body[data-category] .pp-capability,
body[data-category] .pp-hero-capability,
body:has(#product-root) [class*="pp-"][class*="capability"]{ position:relative; overflow:hidden; background:transparent !important; }
body[data-category] .pp-capability::before,
body[data-category] .pp-hero-capability::before,
body:has(#product-root) [class*="pp-"][class*="capability"]::before{
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(ellipse 90% 70% at 30% 40%, rgba(124,58,237,.18) 0%, transparent 65%),
    radial-gradient(ellipse 70% 55% at 72% 50%, rgba(167,139,250,.13) 0%, transparent 60%);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 55%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 0%,#000 55%,transparent 100%);
}
body[data-category] .pp-capability > *,
body:has(#product-root) [class*="pp-"][class*="capability"] > *{ position:relative; z-index:1; }


/* Closing CTA (.pp-mkt-cta): its heading is styled near-white, so it always
   expected a dark slab that never landed — ghost text on white. Give it the
   locked dark slab. */
body[data-category] .pp-mkt-cta,
body:has(#product-root) .pp-mkt-cta{
  background:#0B0B0D !important; border-radius:3px !important;
  margin:24px auto !important; max-width:1060px !important;
  padding:56px 40px !important; position:relative; overflow:hidden;
}
body[data-category] .pp-mkt-cta .pp-mkt-inner,
body:has(#product-root) .pp-mkt-cta .pp-mkt-inner{ position:relative; z-index:2; }
body[data-category] .pp-mkt-cta h2,
body:has(#product-root) .pp-mkt-cta h2{ color:#fff !important; }
body[data-category] .pp-mkt-cta p,
body:has(#product-root) .pp-mkt-cta p{ color:rgba(255,255,255,.82) !important; }


/* Footer wash on engine pages: no boot -> no live canvas -> the OLD 4-color
   fallback (violet/cyan/ROSE/amber) painted the founder's "pink footer".
   Locked lavender-only still wash instead. */
.vk-footer .vk-footer__wash:not(:has(canvas)){
  background:
    radial-gradient(ellipse 80% 50% at 20% 30%, rgba(124,58,237,.12), transparent 65%),
    radial-gradient(ellipse 60% 40% at 80% 60%, rgba(167,139,250,.10), transparent 60%),
    radial-gradient(ellipse 100% 70% at 50% 80%, rgba(178,196,240,.08), transparent 70%),
    linear-gradient(180deg, rgba(252,251,254,.92) 0%, rgba(242,239,249,.88) 100%) !important;
}
