/* ════════════════════════════════════════════════════════════════════════
   bujusjujus site theme — display type, holo-foil background, light mode.

   Loaded by every marketing page right AFTER /tailwind.css (static pages in
   public/ and the SITE_THEME_HEAD templates in server.js). Each page also
   carries three small pieces of markup:
     1. an inline <head> script that sets html[data-theme] before first paint
        (saved choice in localStorage `bj-theme`, else the device setting);
     2. the <div class="holo-bg"> layer straight after <body>;
     3. a [data-theme-toggle] button in its nav (wired by /js/site-theme.js).

   Plain CSS on purpose: public/tailwind.css is PREBUILT and committed, so it
   can't grow dark:/light: variants without a rebuild + cache-buster ritual.
   Light mode instead re-points the colour utilities that build contains, all
   scoped to html[data-theme="light"], so dark mode — the original design —
   is untouched by anything in the light sections.

   Versioning: express.static serves this file `immutable` for 7 days and
   Cloudflare caches it, so a change under the same URL reaches nobody. Server
   chromes and the priced static pages get a content-hash ?v= automatically
   (SITE_THEME_CSS_SRC + the rewrite in renderPriceTemplated, server.js). The
   raw sendFile pages — terms, privacy, api-terms, delete-account, api —
   carry a hand-typed ?v=: bump it there whenever this file or
   /js/site-theme.js changes.
   ════════════════════════════════════════════════════════════════════════ */

:root { color-scheme: dark; }
html[data-theme="light"] { color-scheme: light; }

/* ── Display type ────────────────────────────────────────────────────────
   Headings use Bricolage Grotesque; body text stays Inter, which reads better
   small. Bricolage tops out at 800, so font-black renders at 800. */
h1, h2, h3, .font-display {
  font-family: 'Bricolage Grotesque', 'Inter', system-ui, sans-serif;
  font-optical-sizing: auto;
}
/* Even line lengths instead of a lone last word — Bricolage sets narrower
   than Inter, so breaks tuned for Inter left orphans. */
h1, h2 { text-wrap: balance; }

/* ── Holo-foil background ────────────────────────────────────────────────
   One fixed layer behind the whole page. z-index:-1 on a fixed child of a
   non-positioned <body> paints above the canvas (where body's navy lands)
   and below every section, so no section needs a z-index change. Soft edges
   come from the gradients themselves — no filter:blur on 70vmax layers,
   which is what makes phones stutter. Only transform animates. */
.holo-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
.holo-blob {
  position: absolute;
  width: 70vmax;
  height: 70vmax;
  border-radius: 50%;
  will-change: transform;
}
.holo-blob.b1 {
  top: -28vmax; left: -22vmax;
  background: radial-gradient(circle, rgba(0, 212, 163, 0.17) 0%, rgba(0, 212, 163, 0) 62%);
  animation: holo-drift-a 48s ease-in-out infinite alternate;
}
.holo-blob.b2 {
  top: 8vh; right: -32vmax;
  background: radial-gradient(circle, rgba(139, 92, 246, 0.2) 0%, rgba(139, 92, 246, 0) 62%);
  animation: holo-drift-b 62s ease-in-out infinite alternate;
}
.holo-blob.b3 {
  bottom: -38vmax; left: 0;
  background: radial-gradient(circle, rgba(255, 203, 5, 0.1) 0%, rgba(255, 203, 5, 0) 60%);
  animation: holo-drift-c 56s ease-in-out infinite alternate;
}
.holo-blob.b4 {
  width: 55vmax; height: 55vmax;
  bottom: -22vmax; right: -12vmax;
  background: radial-gradient(circle, rgba(236, 72, 153, 0.11) 0%, rgba(236, 72, 153, 0) 60%);
  animation: holo-drift-a 70s ease-in-out infinite alternate-reverse;
}
/* Foil sheen: a faint hue sweep turning very slowly, like light moving across
   a holo card. Start and end stops match, so there's no seam. */
.holo-sheen {
  position: absolute;
  top: 50%; left: 50%;
  width: 160vmax; height: 160vmax;
  transform: translate(-50%, -50%);
  background: conic-gradient(from 0deg,
    rgba(0, 212, 163, 0) 0deg, rgba(0, 212, 163, 0.05) 60deg,
    rgba(139, 92, 246, 0.05) 140deg, rgba(236, 72, 153, 0.04) 210deg,
    rgba(255, 203, 5, 0.04) 280deg, rgba(0, 212, 163, 0) 360deg);
  animation: holo-spin 140s linear infinite;
  will-change: transform;
}
/* Dot grid, fading out toward the edges. Fixed, so content scrolls over it. */
.holo-grid {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.075) 1px, transparent 1.5px);
  background-size: 28px 28px;
  -webkit-mask-image: radial-gradient(ellipse 85% 75% at 50% 35%, #000 25%, transparent 100%);
  mask-image: radial-gradient(ellipse 85% 75% at 50% 35%, #000 25%, transparent 100%);
}
/* Film grain: static SVG noise, so it costs one paint and nothing after. */
.holo-grain {
  position: absolute;
  inset: 0;
  opacity: 0.06;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
@keyframes holo-drift-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(12vw, 10vh, 0) scale(1.15); }
}
@keyframes holo-drift-b {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to   { transform: translate3d(-14vw, 18vh, 0) scale(0.95); }
}
@keyframes holo-drift-c {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(10vw, -14vh, 0) scale(1.2); }
}
@keyframes holo-spin {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

/* Foil edge on cards: an iridescent 1px ring drawn by a masked ::before,
   faint at rest, full and moving on hover. The card itself stays opaque, so
   its text contrast doesn't change. */
.holo-edge { position: relative; }
.holo-edge::before {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 1px;
  border-radius: inherit;
  background: linear-gradient(120deg, #00D4A3, #8B5CF6, #EC4899, #FFCB05, #00D4A3);
  background-size: 300% 300%;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0.28;
  transition: opacity 0.35s;
  pointer-events: none;
}
.holo-edge:hover::before {
  opacity: 1;
  animation: holo-pan 4s linear infinite;
}
@keyframes holo-pan {
  0%   { background-position: 0% 50%; }
  100% { background-position: 300% 50%; }
}

/* ── Light/dark toggle button (both themes) ──────────────────────────────
   Sun shows in dark (click → light), moon in light. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 9999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.04);
  color: #d1d5db;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.theme-toggle:hover { color: #00D4A3; border-color: rgba(0, 212, 163, 0.4); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .i-moon { display: none; }
/* Inner pages' nav (logo · toggle · Start for free, marked by the subpage-nav
   CTA) had no room to spare on phones: the toggle left the logo 17px short at
   390px wide and 47px short at 360. Tighten it at 400px, and below 380px show
   the wordmark without the eyes — the legal pages' nav already does that. */
@media (max-width: 400px) {
  nav:has([data-track-placement="subpage-nav"]) .theme-toggle { width: 32px; height: 32px; }
  nav:has([data-track-placement="subpage-nav"]) :has(> .theme-toggle) { gap: 0.625rem; }
  nav:has([data-track-placement="subpage-nav"]) a > img[src*="logo.png"] { height: 30px !important; }
}
@media (max-width: 380px) {
  nav:has([data-track-placement="subpage-nav"]) a > img[src*="logo.png"] { display: none; }
}
html[data-theme="light"] .theme-toggle { border-color: rgba(11, 21, 38, 0.14); background: rgba(255, 255, 255, 0.7); color: #334155; }
html[data-theme="light"] .theme-toggle:hover { color: #007257; border-color: rgba(0, 127, 99, 0.4); }
html[data-theme="light"] .theme-toggle .i-sun { display: none; }
html[data-theme="light"] .theme-toggle .i-moon { display: block; }

/* ════════════════════════════════════════════════════════════════════════
   LIGHT MODE — Tailwind colour utilities.
   Covers every colour utility in the prebuilt tailwind.css (59 as of
   2026-10-20). Adding a NEW colour utility to a marketing page means adding
   its light counterpart here, or it stays dark-mode coloured in light mode.
   Accent TEXT darkens to #007257: 5.5:1 on the page, and still 4.5:1 at the
   strongest point of the pastel holo glows. #00D4A3 is 1.9:1 on white.
   Accent FILLS (buttons, pills, tints, borders) keep the bright brand teal.
   ════════════════════════════════════════════════════════════════════════ */

/* Surfaces */
html[data-theme="light"] .bg-navy { background-color: #F4F6FB; }
html[data-theme="light"] .bg-navy\/85 { background-color: rgba(255, 255, 255, 0.82); }
html[data-theme="light"] .bg-navy\/95 { background-color: rgba(255, 255, 255, 0.95); }
html[data-theme="light"] .bg-navy-card { background-color: #FFFFFF; }
html[data-theme="light"] .bg-navy-card\/80 { background-color: rgba(255, 255, 255, 0.85); }
html[data-theme="light"] .bg-navy-light { background-color: #F8FAFC; }
html[data-theme="light"] .bg-navy-light\/40 { background-color: rgba(241, 245, 249, 0.7); }
html[data-theme="light"] .bg-navy-border { background-color: #E2E8F0; }
html[data-theme="light"] .bg-white\/\[0\.04\] { background-color: rgba(11, 21, 38, 0.04); }
html[data-theme="light"] .bg-white\/\[0\.06\] { background-color: rgba(11, 21, 38, 0.05); }
html[data-theme="light"] .hover\:bg-white\/\[0\.1\]:hover { background-color: rgba(11, 21, 38, 0.08); }
html[data-theme="light"] .hover\:bg-white\/\[0\.02\]:hover { background-color: rgba(11, 21, 38, 0.03); }
html[data-theme="light"] .bg-gray-300 { background-color: #334155; }
/* Soft lift on cards that don't already carry a shadow utility. :where()
   keeps it at zero specificity so .step-card:hover and friends still win. */
:where(html[data-theme="light"] .bg-navy-card:not([class*="shadow-"])) {
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 30px -18px rgba(15, 23, 42, 0.18);
}

/* Borders */
html[data-theme="light"] .border-navy-border,
html[data-theme="light"] .border-border { border-color: #E2E8F0; }
html[data-theme="light"] .border-navy-border\/50 { border-color: rgba(226, 232, 240, 0.7); }
html[data-theme="light"] .border-navy-border\/60 { border-color: rgba(226, 232, 240, 0.8); }
html[data-theme="light"] .border-white\/\[0\.06\] { border-color: rgba(11, 21, 38, 0.08); }
html[data-theme="light"] .border-white\/\[0\.12\] { border-color: rgba(11, 21, 38, 0.14); }
html[data-theme="light"] .divide-white\/\[0\.04\] > :not([hidden]) ~ :not([hidden]) { border-color: rgba(11, 21, 38, 0.06); }

/* Text */
html[data-theme="light"] .text-gray-100,
html[data-theme="light"] .text-white { color: #0B1526; }
html[data-theme="light"] .text-gray-200 { color: #1E293B; }
html[data-theme="light"] .text-gray-300 { color: #334155; }
html[data-theme="light"] .text-gray-400 { color: #4B5563; }
html[data-theme="light"] .text-gray-500,
html[data-theme="light"] .text-gray-600 { color: #566275; }
html[data-theme="light"] .text-accent,
html[data-theme="light"] .hover\:text-accent:hover { color: #007257; }
html[data-theme="light"] .text-gold { color: #92400E; }

/* Shadows built for a dark page read as smudges on a light one. */
html[data-theme="light"] .shadow-black\/30 { --tw-shadow-color: rgba(15, 23, 42, 0.1); }
html[data-theme="light"] .retailer-card:hover,
html[data-theme="light"] .step-card:hover { box-shadow: 0 16px 40px -16px rgba(15, 23, 42, 0.22); }

/* ════════════════════════════════════════════════════════════════════════
   LIGHT MODE — page-level patterns.
   Rules that pages define in their own <style> blocks with hard-coded dark
   colours (article prose, comparison tables, callouts, blog + drops
   templates in server.js). The html[data-theme] prefix out-specifies those
   page rules regardless of order.
   ════════════════════════════════════════════════════════════════════════ */

/* Hero tint on the legal pages */
html[data-theme="light"] .bg-mesh { background-image: none; }

/* Article prose (retailer, guide, product, vs pages; set pages) */
html[data-theme="light"] .prose-bujus h2,
html[data-theme="light"] .prose-bujus h3,
html[data-theme="light"] .prose-bujus strong { color: #0B1526; }
html[data-theme="light"] .prose-bujus p,
html[data-theme="light"] .prose-bujus ul,
html[data-theme="light"] .prose-bujus li { color: #334155; }
html[data-theme="light"] .prose-bujus a { color: #007257; }
html[data-theme="light"] .prose-bujus a:hover { color: #005A45; }
html[data-theme="light"] .prose-bujus .cta-card a.cta-btn,
html[data-theme="light"] .prose-bujus .cta-card a.cta-btn:hover { color: #0A1628; }

/* Comparison tables */
html[data-theme="light"] .matrix th,
html[data-theme="light"] .matrix td { border-color: #E2E8F0; color: #334155; }
html[data-theme="light"] .matrix th { background: #F1F5F9; color: #0B1526; }
html[data-theme="light"] .matrix td.yes,
html[data-theme="light"] .matrix td.y,
html[data-theme="light"] .matrix td.price { color: #007257; }
html[data-theme="light"] .matrix td.no { color: #B91C1C; }
html[data-theme="light"] .matrix td.n { color: #566275; }

/* Callouts and boxed asides */
html[data-theme="light"] .callout { background: #EEFBF6; color: #334155; }
html[data-theme="light"] .callout strong { color: #007257; }
html[data-theme="light"] .warning { background: #FFF8E6; color: #334155; }
html[data-theme="light"] .warning strong { color: #92400E; }
html[data-theme="light"] .cta-card h3 { color: #0B1526; }
html[data-theme="light"] .cta-card p { color: #334155; }
html[data-theme="light"] .cta-card .cta-sub { color: #566275; }
html[data-theme="light"] .scenario,
html[data-theme="light"] .story,
html[data-theme="light"] .promise,
html[data-theme="light"] .checklist { background: #FFFFFF; border-color: #E2E8F0; }
html[data-theme="light"] .scenario .label,
html[data-theme="light"] .story .label { color: #566275; }
html[data-theme="light"] .scenario p,
html[data-theme="light"] .story p,
html[data-theme="light"] .promise p { color: #334155; }
html[data-theme="light"] .promise h3 { color: #007257; }
html[data-theme="light"] .step-num,
html[data-theme="light"] .pill { color: #007257; }
html[data-theme="light"] .platform-card { background: rgba(255, 255, 255, 0.85); border-color: rgba(11, 21, 38, 0.1); }

/* API docs (api.html). Code blocks stay dark in both themes — a terminal
   panel reads fine on a light page; inline code gets a light chip. */
html[data-theme="light"] .doc h2 { color: #0B1526; }
html[data-theme="light"] .doc h3,
html[data-theme="light"] .doc a { color: #007257; }
html[data-theme="light"] .doc p,
html[data-theme="light"] .doc li,
html[data-theme="light"] .doc td { color: #4B5563; }
html[data-theme="light"] .doc strong,
html[data-theme="light"] .doc th { color: #1E293B; }
html[data-theme="light"] .doc th,
html[data-theme="light"] .doc td { border-color: #E2E8F0; }
html[data-theme="light"] :not(pre) > code { background: #F1F5F9; border-color: #E2E8F0; color: #0B1526; }

/* Blog, guides index, support (blogPageChrome in server.js) */
html[data-theme="light"] .post-card { background: #FFFFFF; border-color: #E2E8F0; }
html[data-theme="light"] .post-meta { color: #566275; }
html[data-theme="light"] .post-meta .post-date { color: #475569; }
html[data-theme="light"] .post-meta .post-tag { color: #007257; }
html[data-theme="light"] .post-title { color: #0B1526; }
html[data-theme="light"] .post-desc { color: #4B5563; }
html[data-theme="light"] .post-body { color: #1E293B; }
html[data-theme="light"] .post-body h1,
html[data-theme="light"] .post-body h2,
html[data-theme="light"] .post-body h3,
html[data-theme="light"] .post-body strong,
html[data-theme="light"] .post-body th { color: #0B1526; }
html[data-theme="light"] .post-body h2,
html[data-theme="light"] .post-body hr,
html[data-theme="light"] .post-body th,
html[data-theme="light"] .post-body td { border-color: #E2E8F0; }
html[data-theme="light"] .post-body th { background: #F1F5F9; }
html[data-theme="light"] .post-body a { color: #007257; }
html[data-theme="light"] .post-body a:hover { color: #005A45; }
html[data-theme="light"] .post-body :not(pre) > code { background: #F1F5F9; color: #9A3412; }
html[data-theme="light"] .post-body blockquote { color: #475569; }
html[data-theme="light"] .post-body em { color: #334155; }

/* Recent drops (/drops in server.js) */
html[data-theme="light"] .drop-row { background: #FFFFFF; border-color: #E2E8F0; }
html[data-theme="light"] .drop-meta { color: #566275; }
html[data-theme="light"] .drop-retailer { color: #007257; }
html[data-theme="light"] .drop-ago { color: #475569; }
html[data-theme="light"] .drop-title,
html[data-theme="light"] .drop-title-link { color: #0B1526; }
html[data-theme="light"] .drop-title-link:hover { color: #007257; border-bottom-color: #007257; }

/* Inline style="" colours. Inline styles beat any selector, so these need
   !important. Each matches the exact spelling used in the pages. */
html[data-theme="light"] [style*="color:#b6c2d4"],
html[data-theme="light"] [style*="color: #b6c2d4"] { color: #334155 !important; }
html[data-theme="light"] [style*="color:#8391a7"],
html[data-theme="light"] [style*="color: #6b7a90"],
html[data-theme="light"] [style*="color:#8b96a8"],
html[data-theme="light"] [style*="color:#6b7689"] { color: #566275 !important; }
html[data-theme="light"] [style^="color: #fff"],
html[data-theme="light"] [style*=";color:#fff"] { color: #0B1526 !important; }
html[data-theme="light"] [style*="color:#00D4A3"],
html[data-theme="light"] [style*="color: #00D4A3"] { color: #007257 !important; }
html[data-theme="light"] [style*="color:#ffcb05"] { color: #92400E !important; border-color: #D97706 !important; }
html[data-theme="light"] [style*="background:#1C2D4A"] { background: #E2E8F0 !important; }
html[data-theme="light"] [style*="background:#0f1729"] { background: #F1F5F9 !important; color: #1E293B !important; }
html[data-theme="light"] [style*="border-left:2px solid #2a3a55"] { border-left-color: #CBD5E1 !important; }
html[data-theme="light"] [style*="rgba(255,255,255,0.06)"] { border-color: rgba(11, 21, 38, 0.08) !important; }
html[data-theme="light"] [style*="rgba(255,255,255,0.12)"] { border-color: rgba(11, 21, 38, 0.14) !important; }

/* ── Holo foil, light edition ────────────────────────────────────────────
   Same layers, pastel and a little stronger so the foil still reads on
   white. Grain is inverted to dark specks. */
html[data-theme="light"] .holo-blob.b1 { background: radial-gradient(circle, rgba(0, 212, 163, 0.18) 0%, rgba(0, 212, 163, 0) 62%); }
html[data-theme="light"] .holo-blob.b2 { background: radial-gradient(circle, rgba(139, 92, 246, 0.16) 0%, rgba(139, 92, 246, 0) 62%); }
html[data-theme="light"] .holo-blob.b3 { background: radial-gradient(circle, rgba(255, 203, 5, 0.2) 0%, rgba(255, 203, 5, 0) 60%); }
html[data-theme="light"] .holo-blob.b4 { background: radial-gradient(circle, rgba(236, 72, 153, 0.12) 0%, rgba(236, 72, 153, 0) 60%); }
html[data-theme="light"] .holo-sheen {
  background: conic-gradient(from 0deg,
    rgba(0, 212, 163, 0) 0deg, rgba(0, 212, 163, 0.08) 60deg,
    rgba(139, 92, 246, 0.08) 140deg, rgba(236, 72, 153, 0.06) 210deg,
    rgba(255, 203, 5, 0.08) 280deg, rgba(0, 212, 163, 0) 360deg);
}
html[data-theme="light"] .holo-grid { background-image: radial-gradient(rgba(11, 21, 38, 0.09) 1px, transparent 1.5px); }
html[data-theme="light"] .holo-grain { filter: invert(1); opacity: 0.035; }
html[data-theme="light"] .holo-edge::before { opacity: 0.45; }

/* ── Reduced motion: everything here holds still ───────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .holo-blob, .holo-sheen, .holo-edge::before { animation: none !important; }
}
