/* LocalLaunch brand — single source of truth for the sunset design system.
 *
 * Consumed by:
 *   - crm/        via templates/_brand.html ll_head()  (/brand/brand.css)
 *   - apex_app/   via base.html + base_dashboard.html  (/brand/brand.css)
 *   - apex_site/  reference aesthetic — its inline token block should match
 *     these values; reconcile on the marketing page's next edit.
 *
 * Tokens carry the canonical values extracted from apex_site/index.html.
 * Components here are additive (ll-* / data-* namespaced) so existing
 * template CSS keeps working; motion is fail-open — elements are only
 * hidden when motion.js has stamped `html.ll-anim`, so no-JS renders
 * everything visible, and prefers-reduced-motion short-circuits it all.
 */

:root {
  /* Ink + text */
  --ink: #3a1b0e;
  --ink-soft: rgba(58, 27, 14, 0.78);
  --muted: rgba(72, 32, 16, 0.86);
  --soft-muted: rgba(72, 32, 16, 0.6);

  /* Sunset accents */
  --accent: #d6481a;
  --accent-hot: #ef6a28;
  --accent-soft: #fbd79a;
  --accent-deep: #8a2a0c;
  --ivory: #fff6e8;

  /* Footer dusk ramp + gold */
  --footer-1: #b8451a;
  --footer-2: #7a2410;
  --footer-3: #3f1308;
  --gold-1: #fbd07a;
  --gold-3: #d65a1a;

  /* Surfaces */
  --card-bg: rgba(255, 248, 236, 0.96);
  --card-border: rgba(214, 104, 42, 0.22);
  --card-shadow: 0 16px 30px rgba(96, 32, 12, 0.14);
  --border-soft: rgba(138, 42, 12, 0.18);

  /* Semantic */
  --positive: #1f7a3a;
  --positive-bg: rgba(31, 122, 58, 0.1);
  --positive-border: rgba(31, 122, 58, 0.3);
  --warning-bg: rgba(232, 110, 40, 0.14);
  --warning-border: rgba(214, 104, 42, 0.5);

  /* Type — Hanken Grotesk is the brand sans (marketing site); Inter stays
     in the stack as fallback for surfaces that haven't migrated. */
  --serif: "Fraunces", "Georgia", serif;
  --sans: "Hanken Grotesk", "Inter", "Segoe UI", Arial, sans-serif;
  --mono: "JetBrains Mono", monospace;
}

/* ── Sunset seam (fixed top stripe) ─────────────────────────────────── */
.ll-seam {
  position: fixed;
  inset: 0 0 auto 0;
  height: 7px;
  background: linear-gradient(90deg, #d6481a 0%, #ef6a28 50%, #f7a04a 100%);
  z-index: 50;
}

/* Scroll progress fill — optional, sits inside .ll-seam */
.ll-scroll-progress {
  position: fixed;
  top: 7px;
  left: 0;
  height: 3px;
  width: 0;
  background: linear-gradient(90deg, var(--gold-1), var(--accent-hot));
  z-index: 50;
  pointer-events: none;
}

/* ── Grain overlay ──────────────────────────────────────────────────────
   The marketing site's warmth filter. Applies automatically to the CRM
   (body.ll-shell) and by opt-in class elsewhere (body.ll-grain). */
body.ll-shell::after,
body.ll-grain::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 60;
  opacity: 0.05;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* ── Scroll reveals — fail-open ─────────────────────────────────────────
   Hidden ONLY under html.ll-anim (stamped by motion.js when the visitor
   does not prefer reduced motion). No JS → everything visible. */
html.ll-anim [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}
html.ll-anim [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html.ll-anim [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .ll-scroll-progress { display: none; }
}

/* ── Rise-on-insert — for client-rendered content (Alpine x-if panels)
   where IntersectionObserver would race the render. Pure CSS: animates
   whenever the element enters the DOM. Same fail-open gate. */
html.ll-anim .ll-rise {
  animation: llRise 0.55s cubic-bezier(0.22, 1, 0.36, 1) both;
}
html.ll-anim .ll-rise:nth-child(2) { animation-delay: 60ms; }
html.ll-anim .ll-rise:nth-child(3) { animation-delay: 120ms; }
html.ll-anim .ll-rise:nth-child(4) { animation-delay: 180ms; }
@keyframes llRise {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  html.ll-anim .ll-rise { animation: none; }
}

/* ── Gold shimmer (customer tier) — shared from the CRM ────────────────── */
.ll-gold-shimmer {
  background-image: linear-gradient(110deg, #f59e0b 0%, #fbbf24 18%,
      #fde68a 38%, #fffbeb 50%, #fde68a 62%, #fbbf24 82%, #f59e0b 100%);
  background-size: 250% 100%;
  animation: llGoldShimmer 3.5s linear infinite;
}
@keyframes llGoldShimmer {
  from { background-position: 125% 0; }
  to { background-position: -125% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ll-gold-shimmer { animation: none; }
}

/* ── Working pulse dot (task in flight) ────────────────────────────────── */
.ll-pulse-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--accent-hot);
  animation: llPulseDot 1.6s ease-in-out infinite;
}
@keyframes llPulseDot {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239, 106, 40, 0.5); }
  50% { box-shadow: 0 0 0 6px rgba(239, 106, 40, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .ll-pulse-dot { animation: none; }
}
