/* Animations */
/* Base: start hidden */
.reveal,
.reveal-left,
.reveal-right,
.reveal-top,
.reveal-bottom,
.reveal-fade,
.zoomin { opacity: 0; }

/* Motion preferences */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal-left,
  .reveal-right,
  .reveal-top,
  .reveal-bottom,
  .reveal-fade,
  .zoomin {
    animation: none !important;
    opacity: 1 !important;
    translate: 0 0 !important;
    scale: 1 !important;
  }
}

/* Scroll-driven animations */
@supports (animation-timeline: view()) {
  /* One setup for all reveal classes */
  .reveal,
  .reveal-left,
  .reveal-right,
  .reveal-top,
  .reveal-bottom,
  .reveal-fade,
  .zoomin {
    animation-timeline: view();
    /* Use cover so items visible at load still animate */
    animation-range: cover 0% cover 40%;
    animation-fill-mode: both;
    animation-duration: 2s; /* required; scroll controls the real pace */
    will-change: opacity, transform;
  }

  .reveal-fade   { animation-name: kf-fade; }
  .reveal-left   { animation-name: kf-left; }
  .reveal-right  { animation-name: kf-right; }
  .reveal-top    { animation-name: kf-top; }
  .reveal-bottom { animation-name: kf-bottom; }
  .zoomin        { animation-name: kf-zoomin; }

  /* Keyframes use the translate sub-property to avoid clobbering other transforms */
  @keyframes kf-fade   { from { opacity: 0;           } to { opacity: 1;           } }
  @keyframes kf-left   { from { opacity: 0; translate: -222px 0; } to { opacity: 1; translate: 0 0; } }
  @keyframes kf-right  { from { opacity: 0; translate:  222px 0; } to { opacity: 1; translate: 0 0; } }
  @keyframes kf-top    { from { opacity: 0; translate: 0 -222px; } to { opacity: 1; translate: 0 0; } }
  @keyframes kf-bottom { from { opacity: 0; translate: 0  222px; } to { opacity: 1; translate: 0 0; } }
  @keyframes kf-zoomin { from { opacity: 0; scale: 0.7; } to { opacity: 1; scale: 1; } }

  /* Ensure a real starting pose even if the element begins in view */
  @starting-style {
    .reveal        { opacity: 0; }
    .reveal-left   { opacity: 0; translate: -222px 0; }
    .reveal-right  { opacity: 0; translate:  222px 0; }
    .reveal-top    { opacity: 0; translate: 0 -222px; }
    .reveal-bottom { opacity: 0; translate: 0  222px; }
    .reveal-fade   { opacity: 0; }
    .zoomin        { opacity: 0; scale: 0.7; }
  }
}

/* Fallback when scroll animations aren't supported: just show content */
@supports not (animation-timeline: view()) {
  .reveal,
  .reveal-left,
  .reveal-right,
  .reveal-top,
  .reveal-bottom,
  .reveal-fade,
  .zoomin { opacity: 1; }
}
/* One-time animation for elements visible at page load */
.reveal-now {
  animation-timeline: auto !important; /* switch from scroll to time-based */
  animation-duration: 0.6s;
  animation-fill-mode: both;
  animation-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94); /* smooth ease-out */
  will-change: opacity, transform;
}

.reveal-left.reveal-now   { animation-name: kf-left; }
.reveal-right.reveal-now  { animation-name: kf-right; }
.reveal-top.reveal-now    { animation-name: kf-top; }
.reveal-bottom.reveal-now { animation-name: kf-bottom; }
.zoomin.reveal-now        { animation-name: kf-zoomin; }
.reveal-fade.reveal-now,
.reveal.reveal-now        { animation-name: kf-fade; }

@media (prefers-reduced-motion: reduce) {
  .reveal-now { animation: none !important; opacity: 1 !important; translate: 0 0 !important; scale: 1 !important; }
}

/* TYPE IN EFFECT */
.typein {
  white-space: pre-wrap;   /* wrap long lines, respect line breaks */
  overflow: visible;       /* don't clip multi-line text */
}

.typein.is-typing::after {
  content: "";
  display: inline-block;
  width: 1px;
  height: 1em;
  vertical-align: -0.15em;
  border-right: 2px solid currentColor;
  animation: caret-blink 0.7s steps(1) infinite;
  margin-left: 2px;
}

@keyframes caret-blink { 
  50% { border-color: transparent; } 
}
