/* Hide animated text until its animation starts, so you never see the
   final copy flash before it reveals.

   The .ta-js guard is set by a tiny inline script in <head>. If the
   JavaScript fails to load, the guard is absent and the text simply
   stays visible instead of being hidden forever. */
.ta-js [data-anim]:not(.ta-ready),
.ta-js .anim-line-reveal:not(.ta-ready),
.ta-js .anim-scramble:not(.ta-ready),
.ta-js .anim-img-reveal:not(.ta-ready),
.ta-js .anim-reveal:not(.ta-ready),
.ta-js .anim-odometer:not(.ta-ready) {
  visibility: hidden;
}

[data-anim].ta-ready,
.anim-line-reveal.ta-ready,
.anim-scramble.ta-ready,
.anim-img-reveal.ta-ready,
.anim-reveal.ta-ready,
.anim-odometer.ta-ready {
  visibility: visible;
}

/* The wipe animates clip-path on this element and counter-scales the image
   inside it, so the box must clip and the image must fill it. */
.anim-img-reveal {
  overflow: hidden;
}

.anim-img-reveal img {
  display: block;
  max-width: 100%;
  will-change: transform;
}

/* Scramble-on-hover characters. Each box is width-locked in JS, so centring
   keeps a narrow "." sitting where its letter was instead of hugging the left. */
.ta-char {
  text-align: center;
}

/* SplitText line boxes. */
.ta-line {
  will-change: transform;
}

/* SplitText wraps each line in a mask element (class = line class + "-mask")
   with inline `overflow: clip`, sized to a tight line box. That crops glyphs
   that extend past the box: descenders (g, y), a comma, a period, and tall
   ascenders/accents. `overflow-clip-margin` pushes the visible clip edge
   outward so those fit, with zero effect on layout or line spacing (unlike
   padding/margins). It only applies while `overflow: clip` is set, so a
   browser without support simply keeps today's behaviour. The travelling line
   starts at opacity 0, so the wider clip region never flashes mid-animation. */
.ta-line-mask {
  overflow-clip-margin: 0.3em;
}

/* Scrambling cycles through glyphs of differing widths; tabular figures
   stop digits from jittering. A monospace font stops it entirely. */
[data-anim='scramble'],
.anim-scramble {
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------ *
 * Odometer / slot-machine number roll
 * ------------------------------------------------------------------ */
.anim-odometer {
  /* Equal-width figures keep the wheels from shifting as digits change. */
  font-variant-numeric: tabular-nums;
}

/* One digit column: a 1em-tall window that clips the rolling strip. */
.anim-odometer .ta-odo-digit {
  display: inline-block;
  height: 1em;
  overflow: hidden;
  vertical-align: bottom;
}

.anim-odometer .ta-odo-strip {
  display: block;
  will-change: transform;
}

/* Each cell must be exactly 1em tall: the wheel lands by translating a
   whole number of em, so the step and the cell height have to match. */
.anim-odometer .ta-odo-cell {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: 1em;
  line-height: 1;
}

/* Separators and symbols (comma, %, currency, +) sit on the baseline. */
.anim-odometer .ta-odo-static {
  display: inline-block;
  vertical-align: bottom;
  line-height: 1;
  white-space: pre;
}

/* ------------------------------------------------------------------ *
 * Target cursor
 * ------------------------------------------------------------------ */
.target-cursor-wrapper {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 9999;
  mix-blend-mode: difference;
  transform: translate(-50%, -50%);
}

.target-cursor-dot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 4px;
  height: 4px;
  background: #fff;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  will-change: transform;
}

.target-cursor-corner {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 12px;
  height: 12px;
  border: 3px solid #fff;
  will-change: transform;
}

.corner-tl {
  transform: translate(-150%, -150%);
  border-right: none;
  border-bottom: none;
}

.corner-tr {
  transform: translate(50%, -150%);
  border-left: none;
  border-bottom: none;
}

.corner-br {
  transform: translate(50%, 50%);
  border-left: none;
  border-top: none;
}

.corner-bl {
  transform: translate(-150%, 50%);
  border-right: none;
  border-top: none;
}

/* ------------------------------------------------------------------ *
 * Page transitions - native cross-document View Transitions.
 *
 * Every same-origin navigation animates in instead of the default hard
 * reload. This must be present on both the outgoing and incoming page,
 * which it is: this stylesheet loads site-wide on the front end (and is
 * skipped inside the Breakdance builder by the plugin's enqueue guard).
 *
 * Browsers without cross-document View Transitions (e.g. Firefox as of
 * early 2026) ignore @view-transition and the ::view-transition-*
 * pseudo-elements entirely and simply load the page normally.
 * ------------------------------------------------------------------ */
@view-transition {
  navigation: auto;
}

/* Slide-up only when the visitor has not asked for reduced motion. Under
   'reduce' the browser's default (a subtle crossfade) is left in place. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes ta-page-in {
    from { opacity: 0; transform: translateY(40px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  @keyframes ta-page-out {
    from { opacity: 1; }
    to   { opacity: 0; }
  }
  /* Only the incoming page slides up; the outgoing one just fades, so
     there is no competing double movement. */
  ::view-transition-old(root) {
    animation: 220ms ease both ta-page-out;
  }
  ::view-transition-new(root) {
    animation: 520ms cubic-bezier(0.16, 1, 0.3, 1) both ta-page-in;
  }
}
