/* Shared motion for all CivicPulse pages. Kept light on purpose: content rises in once, and nothing loops.
   Everything here is switched off for visitors whose device asks for reduced motion. */

/* Smooth cross-fade when moving between pages (supported browsers; others just navigate normally). */
@view-transition { navigation: auto; }

html{scroll-behavior:smooth;}

@keyframes cp-rise{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:none;}}
@keyframes cp-fade{from{opacity:0;}to{opacity:1;}}
/* Who decides? while the topic is being picked: a soft sweep along the bar */
@keyframes cp-sweep{from{transform:translateX(-100%);}to{transform:translateX(350%);}}

/* Gentle color changes on anything interactive */
a, button, input, select, textarea,
.tab, .chip, .search-result-item, .home-link, .nav-cta{
  transition:background-color .18s ease, color .18s ease, border-color .18s ease, box-shadow .15s ease, transform .1s ease;
}

/* Content entering the page */
.anim-rise{animation:cp-rise .35s cubic-bezier(.2,.7,.3,1) both;}
/* Switching tabs only cross-fades, so nothing slides or jumps. */
.panel.active{animation:cp-fade .22s ease-out both;}
.search-results.show{animation:cp-fade .15s ease-out;}
.gloss:hover::after, .gloss:focus::after, .gloss.show::after{animation:cp-fade .15s ease-out;}

/* Page headers rise in, one line after another */
.hero-text > *, .page-head > *{animation:cp-rise .5s cubic-bezier(.2,.7,.3,1) both;}
.hero-text > :nth-child(2), .page-head > :nth-child(2){animation-delay:.06s;}
.hero-text > :nth-child(3), .page-head > :nth-child(3){animation-delay:.12s;}
.hero-text > :nth-child(4){animation-delay:.18s;}
.hero-text > :nth-child(5){animation-delay:.24s;}
/* While the home page intro plays, the page's own entrance waits, then runs as the intro hands off. */
html.intro-on .hero-text > *{animation-play-state:paused;}

/* ---- Motion layer (motion.js: GSAP + Lenis). These rules only apply once motion.js is running (html.gsap-on). */
/* Headings wait, hidden, until their letters rise in (theme.js shows them after 2.5 s if motion.js never starts). */
html.split-wait [data-split="chars"]{visibility:hidden;}
html.gsap-on .hero-text > [data-split], html.gsap-on .page-head > [data-split]{animation:none;}
[data-split="chars"]{perspective:600px;}
/* GSAP runs the scroll reveal, so the CSS fallback transition stays out of its way. */
html.gsap-on .reveal{transition:none;}
/* Lenis owns smooth scrolling; the browser's own smoothing would double it. */
html.lenis, html.lenis body{height:auto;}
html.lenis{scroll-behavior:auto !important;}
.lenis:not(.lenis-autoToggle).lenis-stopped{overflow:clip;}
.lenis [data-lenis-prevent]{overscroll-behavior:contain;}

/* SpotlightCard: a faint green glow follows the pointer across a card. Drawn behind the card's content. */
.spot{position:relative;isolation:isolate;}
.spot::after{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;opacity:0;
  background:radial-gradient(380px circle at var(--mx, 50%) var(--my, 50%), color-mix(in srgb, var(--accent-bright) 13%, transparent), transparent 65%);
  transition:opacity .35s ease;}
.spot:hover::after{opacity:1;}
.spot{transition:border-color .25s ease, box-shadow .25s ease;}
.spot:hover{border-color:color-mix(in srgb, var(--accent) 35%, var(--line));}

/* App tabs: one green marker slides to the open tab. */
.tabs.has-ind{position:relative;}
.tab-ind{position:absolute;left:0;top:0;width:0;height:0;z-index:0;border-radius:var(--radius-sm);background:var(--accent);
  pointer-events:none;box-shadow:0 6px 18px color-mix(in srgb, var(--accent) 28%, transparent);}
.tabs.has-ind .tab{position:relative;z-index:1;background:transparent;}
.tabs.has-ind .tab.active{background:transparent;border-color:transparent;}

@media (prefers-reduced-motion: reduce){
  @view-transition { navigation: none; }
  html{scroll-behavior:auto;}
  *, *::before, *::after{animation:none !important;transition:none !important;}
}
