/* SpectraWorks - care-signal layer
   Loaded AFTER global.css. Overrides are deliberate.

   Microspec numbers per references/microspec-rationale.md:
     180ms link draw-in, cubic-bezier(0.22, 1, 0.36, 1) button curve,
     900ms section reveals with 0/160/320ms stagger, 1200ms ruler first-reveal,
     hero meta cascade 200/320/440/560ms, translateY 6-14px, mark scale 1.08,
     arrow shift 3px, button colour cross-fade 320ms.
*/

:root {
  --focus: var(--sp-450);   /* branded focus ring - spectrum indigo */
  --ease-out-quart: cubic-bezier(0.22, 1, 0.36, 1);
  --motion-link: 180ms;
  --motion-nav: 220ms;
  --motion-control: 320ms;
  --motion-reveal: 900ms;
  --motion-signature: 1200ms;
  /* --bg now lives only in global.css (#FBF8F1) -- a single source of
     truth survives any stylesheet-order shuffle from view-transitions. */
}
body { background: var(--bg); overflow-x: clip; }
main { overflow-x: clip; }
.section-head > div { min-width: 0; }

/* -------- Focus rings (branded, never browser default) -------- */
*:focus { outline: none; }
*:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}
.cta-form input:focus-visible,
.cta-form select:focus-visible,
.cta-form textarea:focus-visible {
  outline: none;
  border-bottom-color: var(--focus);
}

/* -------- Link underline draw-in (180ms ease-out) -------- */
/* Applies to nav links, list-item links, sidebar links, footer-list links.
   Buttons and brand-image links are excluded. Footer underline targets the
   <a> inside each <li> so it tracks the link text width, not the column. */
.nav-link,
.blog-list-item,
.footer ul li a,
.contact-mail,
.feed-side .tag {
  position: relative;
}
.nav-link::after,
.blog-list-item::after,
.footer ul li a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  height: 1px;
  width: 0;
  background: currentColor;
  transition: width var(--motion-link) ease-out;
}
.nav-link:hover::after,
.blog-list-item:hover::after,
.footer ul li a:hover::after {
  width: 100%;
}
/* Nav-link underline: full visible-spectrum gradient (same stops as the
   spectrum-ruler hero device), revealed left-to-right via clip-path
   (animating width would stretch the gradient instead of revealing it).
   Active state holds the full reveal with no transition so it does not
   animate on initial paint. Specificity boosted via .nav ancestor so this
   wins over global.css regardless of stylesheet load order (Astro
   view-transitions swaps). */
.nav .nav-link::after {
  left: 0;
  right: auto;
  bottom: -2px;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg,
    var(--sp-400) 0%,
    var(--sp-450) 18%,
    var(--sp-500) 35%,
    var(--sp-550) 52%,
    var(--sp-600) 70%,
    var(--sp-650) 85%,
    var(--sp-700) 100%);
  clip-path: inset(0 100% 0 0);
  transition: clip-path var(--motion-nav) var(--ease-out-quart);
}
.nav .nav-link:hover::after { clip-path: inset(0 0 0 0); }
.nav .nav-link.active::after {
  clip-path: inset(0 0 0 0);
  transition: none;
}

/* Footer-link underline: same spectral gradient as the nav, scoped to the
   <a> so it tracks the link text width, not the column. Slower beat than
   the nav (320ms vs 220ms) to read as a quieter zone. */
.footer ul li a::after {
  left: 0;
  right: auto;
  bottom: -2px;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg,
    var(--sp-400) 0%,
    var(--sp-450) 18%,
    var(--sp-500) 35%,
    var(--sp-550) 52%,
    var(--sp-600) 70%,
    var(--sp-650) 85%,
    var(--sp-700) 100%);
  clip-path: inset(0 100% 0 0);
  transition: clip-path var(--motion-control) var(--ease-out-quart);
}
.footer ul li a:hover::after { clip-path: inset(0 0 0 0); }

/* -------- Buttons: slow colour cross-fade + arrow shift in sync -------- */
/* Colour fade uses ease-in-out so the change spreads evenly across the
   duration instead of front-loading. ease-out-quart kept for the arrow
   (position transitions still benefit from the snap on enter). */
.btn {
  transition:
    background var(--motion-control) ease-in-out,
    color var(--motion-control) ease-in-out,
    border-color var(--motion-control) ease-in-out,
    box-shadow var(--motion-control) ease-in-out;
}
.btn .arrow {
  display: inline-block;
  transition: transform var(--motion-control) var(--ease-out-quart);
}
.btn:hover .arrow { transform: translateX(3px); }

/* -------- RefCal buyer surface: shared website interaction language -------- */
/* Ancestor specificity keeps these effects stable if static stylesheet order
   changes. Demo layout stays in demo.css; interaction timing and focus live here. */
.demo-shell :is(a, button, input, select, textarea):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--radius-small);
}
.demo-shell :is(a:not(.brand), button) {
  transition:
    background-color var(--motion-control) ease-in-out,
    color var(--motion-control) ease-in-out,
    border-color var(--motion-control) ease-in-out;
}
.demo-shell a:not(.brand) {
  position: relative;
}
.demo-shell a:not(.brand)::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 0;
  height: 1px;
  background: currentColor;
  transition: width var(--motion-link) ease-out;
}
.demo-shell a:not(.brand):hover::after {
  width: 100%;
}
.demo-shell :is(.demo-tab-btn, .demo-mode-btn) {
  position: relative;
}
.demo-shell :is(.demo-tab-btn, .demo-mode-btn)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: linear-gradient(90deg,
    var(--sp-400) 0%,
    var(--sp-450) 18%,
    var(--sp-500) 35%,
    var(--sp-550) 52%,
    var(--sp-600) 70%,
    var(--sp-650) 85%,
    var(--sp-700) 100%);
  clip-path: inset(0 100% 0 0);
  transition: clip-path var(--motion-nav) var(--ease-out-quart);
}
.demo-shell :is(.demo-tab-btn, .demo-mode-btn):is(:hover, .is-active)::after {
  clip-path: inset(0 0 0 0);
}
.demo-shell :is(.demo-tab-btn, .demo-mode-btn).is-active::after {
  transition: none;
}
.demo-shell :is(.fd-source, .demo-cmp-stage, .demo-cmp-range, .demo-avail-satellite, .demo-walk-card):hover {
  border-color: var(--ink-700);
}

/* -------- Logo: spectral wave sweep on hover (V4) -------- */
/* The mark is a <span> with the PNG used as an alpha mask, so we can paint
   the silhouette with a CSS gradient. Default fill is ink-700 slate. On hover
   a narrow rainbow band travels left-to-right across the mark and exits; on
   unhover the band tracks back the way it came. Mark also scales 1.08. */
.brand { transition: none; }
.brand:hover { transform: none; }
.brand-mark {
  display: block;
  width: 56px;
  height: 56px;
  -webkit-mask: var(--brand-mark-mask, url(/assets/mark-mask.png)) center / contain no-repeat;
          mask: var(--brand-mark-mask, url(/assets/mark-mask.png)) center / contain no-repeat;
  background:
    linear-gradient(90deg,
      var(--ink-700) 0%,
      var(--ink-700) 30%,
      var(--sp-400) 38%,
      var(--sp-450) 42%,
      var(--sp-500) 46%,
      var(--sp-550) 50%,
      var(--sp-600) 54%,
      var(--sp-650) 58%,
      var(--sp-700) 62%,
      var(--ink-700) 70%,
      var(--ink-700) 100%);
  background-size: 300% 100%;
  background-position: 100% 0%;
  transform-origin: center;
  transition:
    transform var(--motion-link) var(--ease-out-quart),
    background-position var(--motion-signature) var(--ease-out-quart);
}
.brand:hover .brand-mark {
  transform: scale(1.08);
  background-position: 0% 0%;
}
.brand-text {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--ink-900);
  text-transform: uppercase;
}
.footer .brand-text { color: var(--ink-900); }
.cta-lockup .brand-text { color: var(--bg); }
.brand-lockup {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
}

/* -------- Dark CTA: original dark ink (NOT navy) -------- */
/* User preference: keep the deep near-black CTA from global.css.
   Navy was tried and reverted. Override here only to be explicit. */
.cta { background: var(--ink-900); }
.cta-form input:focus,
.cta-form textarea:focus { border-bottom-color: var(--sp-600); }
.cta-form .btn:focus-visible { outline-offset: 4px; }

.cta-lockup {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 28px;
}
.cta-lockup .mark {
  height: 44px;
  width: auto;
  display: block;
  transition: transform var(--motion-link) var(--ease-out-quart);
}
.cta-lockup .wordmark {
  height: 18px;
  width: auto;
  display: block;
}
.cta-lockup:hover .mark { transform: scale(1.05); }

/* -------- Spectrum ruler: first-reveal sweep (single pass) -------- */
/* Uses clip-path instead of background-size: hardware-accelerated, renders
   smoothly at any height, and the transition must be on the pre-state so
   the browser sees it before the property change (otherwise some browsers
   skip the animation and the line shoots across in one frame). */
.spectrum-ruler.sweep {
  clip-path: inset(0 100% 0 0);
  transition: clip-path var(--motion-signature) var(--ease-out-quart);
}
.spectrum-ruler.sweep.played {
  clip-path: inset(0 0 0 0);
}
/* Hero ruler gets an extra beat before sweeping so it reads as a moment. */
.hero .spectrum-ruler.sweep {
  transition-delay: 300ms;
}

/* -------- Hero meta cascade (terminal-print) -------- */
.hero-meta .meta-row {
  opacity: 0;
  transform: translateY(4px);
}
.hero-meta.cascaded .meta-row {
  opacity: 1;
  transform: none;
  transition: opacity 260ms ease-out, transform 260ms ease-out;
}
.hero-meta.cascaded .meta-row:nth-child(1) { transition-delay: 200ms; }
.hero-meta.cascaded .meta-row:nth-child(2) { transition-delay: 320ms; }
.hero-meta.cascaded .meta-row:nth-child(3) { transition-delay: 440ms; }
.hero-meta.cascaded .meta-row:nth-child(4) { transition-delay: 560ms; }

/* -------- Section reveals (opacity + 14px translateY, configurable stagger) -------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity var(--motion-reveal) var(--ease-out-quart),
    transform var(--motion-reveal) var(--ease-out-quart);
  transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal].revealed {
  opacity: 1;
  transform: none;
}

/* -------- Reduced motion: degrade to instant -------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0ms !important;
    animation-duration: 0ms !important;
    animation-iteration-count: 1 !important;
  }
  .hero-meta .meta-row,
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
  .spectrum-ruler.sweep { clip-path: inset(0 0 0 0) !important; }
  .btn:hover .arrow { transform: none; }
  .brand:hover { transform: none; }
  /* Don't flash the spectral band: keep the mark fully slate. */
  .brand:hover .brand-mark { background-position: 100% 0% !important; }
}
