/* Lucia marketing site · entry animations
   Rule: only html.js gates initial-hide. No JS = fully visible.
   prefers-reduced-motion = instant end-state. */


/* ============================================================================
   .rv  ·  Scroll-reveal fade-up
   ============================================================================
   Wrap items in a .rv container. Each .rv-item gets staggered 70ms.
   JS (site.js) adds .rv-in to trigger.
   Without JS, everything stays visible (no html.js = no hiding). */

/* Only hide when JS is confirmed running */
html.js .rv .rv-item {
  opacity: 0;
  transform: translateY(12px);
}

/* Revealed state · html.js prefix so this outranks the initial-hide rule (specificity bug fixed 2026-09-23) */
html.js .rv.rv-in .rv-item {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 400ms var(--ease), transform 400ms var(--ease);
}

/* Stagger: each child delays 70ms more.
   Cover up to 12 items; beyond that, the 12th delay holds. */
.rv.rv-in .rv-item:nth-child(1)  { transition-delay: 0ms; }
.rv.rv-in .rv-item:nth-child(2)  { transition-delay: 70ms; }
.rv.rv-in .rv-item:nth-child(3)  { transition-delay: 140ms; }
.rv.rv-in .rv-item:nth-child(4)  { transition-delay: 210ms; }
.rv.rv-in .rv-item:nth-child(5)  { transition-delay: 280ms; }
.rv.rv-in .rv-item:nth-child(6)  { transition-delay: 350ms; }
.rv.rv-in .rv-item:nth-child(7)  { transition-delay: 420ms; }
.rv.rv-in .rv-item:nth-child(8)  { transition-delay: 490ms; }
.rv.rv-in .rv-item:nth-child(9)  { transition-delay: 560ms; }
.rv.rv-in .rv-item:nth-child(10) { transition-delay: 630ms; }
.rv.rv-in .rv-item:nth-child(11) { transition-delay: 700ms; }
.rv.rv-in .rv-item:nth-child(n+12) { transition-delay: 770ms; }

/* Container itself can also reveal (for single-element reveals) */
html.js .rv-self {
  opacity: 0;
  transform: translateY(12px);
}
html.js .rv-self.rv-in {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 400ms var(--ease), transform 400ms var(--ease);
}


/* ============================================================================
   .draw  ·  Line-drawing scaleX animation (for rules and pseudo-element lines)
   ============================================================================
   Apply to the element whose ::after draws the line, or directly on a
   pseudo-element.
   JS adds .draw-in to trigger.
   transform-origin: 0 50% draws left-to-right. */

html.js .draw {
  transform: scaleX(0);
  transform-origin: 0 50%;
}
html.js .draw.draw-in {
  transform: scaleX(1);
  transition: transform 450ms var(--ease);
}

/* For .rail::after — the hairline draws in when .rail has .draw-in */
html.js .rail.draw::after {
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.rail.draw.draw-in::after {
  transform: scaleX(1);
  transition: transform 450ms var(--ease);
}

/* For .rule-total — the accounting double-line draws in */
html.js .rule-total.draw {
  position: relative;
}
html.js .rule-total.draw::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 3px;
  border-bottom: 3px double var(--ink);
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.dark .rule-total.draw::after { border-color: var(--paper); }
.rule-total.draw.draw-in::after {
  transform: scaleX(1);
  transition: transform 450ms 100ms var(--ease);
}


/* ============================================================================
   prefers-reduced-motion  ·  Skip to end state
   ============================================================================ */

@media (prefers-reduced-motion: reduce) {
  html.js .rv .rv-item,
  html.js .rv-self,
  html.js .draw,
  html.js .rail.draw::after,
  html.js .rule-total.draw::after {
    opacity: 1;
    transform: none;
    transition: none;
  }
}


/* ============================================================================
   Safety net  ·  nothing stays hidden for more than 2.5s, whatever happens
   ============================================================================
   Full-page screenshots, print, IntersectionObserver never firing: after 2.5s the
   animation forces the end state. A normal reveal (.rv-in / .draw-in) still runs
   its transition before that. */
@keyframes lucia-rv-safety { to { opacity: 1; transform: none; } }
html.js .rv .rv-item,
html.js .rv-self,
html.js .draw,
html.js .rail.draw::after,
html.js .rule-total.draw::after {
  animation: lucia-rv-safety 1ms linear 2.5s forwards;
}
@media print {
  html.js .rv .rv-item,
  html.js .rv-self,
  html.js .draw,
  html.js .rail.draw::after,
  html.js .rule-total.draw::after {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
  }
}
