/*
 * Text animation (see cicada-type.js). Every hidden starting state needs
 * both .type-motion (set by theme.js when motion is allowed) and a class
 * the script adds, so text never stays hidden without the script.
 */

/* The hero headline would flash before the deferred script splits it, so
   it is held back from first paint; the failsafe shows it after 2.5 s if
   the script never arrives. */
.type-motion .cc-hero h1:not(.tw-ready) {
  opacity: 0;
  animation: ty-failsafe 0s 2.5s forwards;
}
@keyframes ty-failsafe { to { opacity: 1; } }

/* ---- Headings: words rise out of a mask ---------------------------- */
.tw {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  /* room for descenders and the italic overhang, given back by margins */
  padding: 0 0.08em 0.14em 0;
  margin: 0 -0.08em -0.14em 0;
}
.tw-i { display: inline-block; }
.type-motion .tw-ready .tw-i {
  transform: translateY(110%) rotate(4deg);
  opacity: 0;
  filter: blur(6px);
  transform-origin: 0 100%;
}
.type-motion .tw-ready.is-in .tw-i {
  animation: tw-rise 1.05s cubic-bezier(0.16, 0.84, 0.24, 1) both;
  animation-delay: calc(var(--i) * 70ms + 80ms);
}
.type-motion .cc-hero .tw-ready.is-in .tw-i {
  animation-duration: 1.3s;
  animation-delay: calc(var(--i) * 110ms + 250ms);
}
@keyframes tw-rise {
  0% { transform: translateY(110%) rotate(4deg); opacity: 0; filter: blur(6px); }
  60% { opacity: 1; filter: blur(0); }
  100% { transform: none; opacity: 1; filter: none; }
}

/* ---- The italic half carries a travelling glint -------------------- */
:root {
  --ty-ink: #6a3fa6;
  --ty-glint: #c99bff;
  --ty-gold: #b8955a;
}
:root[data-theme="dark"] {
  --ty-ink: #c8b2f0;
  --ty-glint: #f3e8ff;
  --ty-gold: #f1dcaa;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ty-ink: #c8b2f0;
    --ty-glint: #f3e8ff;
    --ty-gold: #f1dcaa;
  }
}
.type-motion :is(h1, h2) em .tw-i {
  background: linear-gradient(100deg,
    var(--ty-ink) 0%, var(--ty-ink) 38%, var(--ty-glint) 46%,
    var(--ty-gold) 50%, var(--ty-glint) 54%, var(--ty-ink) 62%, var(--ty-ink) 100%);
  background-size: 300% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* Two animations on one element: the rise, then the glint loop. The glint
   starts after the word has landed and passes word to word. These selectors
   must out-rank the plain rise rules above (one more element: em). */
.type-motion .tw-ready.is-in em .tw-i {
  animation:
    tw-rise 1.05s cubic-bezier(0.16, 0.84, 0.24, 1) both,
    ty-glint 7s ease-in-out infinite;
  animation-delay:
    calc(var(--i) * 70ms + 80ms),
    calc(var(--i) * 160ms + 1.4s);
}
.type-motion .cc-hero .tw-ready.is-in em .tw-i {
  animation-duration: 1.3s, 7s;
  animation-delay:
    calc(var(--i) * 110ms + 250ms),
    calc(var(--i) * 160ms + 1.8s);
}
@keyframes ty-glint {
  0% { background-position: 100% 0; }
  28%, 100% { background-position: 0% 0; }
}

/* ---- Eyebrows: split-flap letters ---------------------------------- */
.fw { white-space: nowrap; }
.fl { display: inline-block; }
.type-motion .fl-ready .fl {
  opacity: 0;
  transform: perspective(300px) rotateX(-95deg);
  transform-origin: 50% 40%;
}
.type-motion .fl-ready.is-in .fl {
  animation: fl-flip 0.55s cubic-bezier(0.3, 1.4, 0.5, 1) both;
  animation-delay: calc(var(--i) * 22ms);
}
@keyframes fl-flip {
  0% { opacity: 0; transform: perspective(300px) rotateX(-95deg); }
  45% { opacity: 1; }
  100% { opacity: 1; transform: none; }
}
/* the eyebrow dot pings once as its line lands */
.type-motion .fl-ready.is-in i {
  animation: ty-ping 1.6s ease-out 0.4s both;
}
@keyframes ty-ping {
  0% { box-shadow: 0 0 0 0 #8b63c966; }
  70% { box-shadow: 0 0 0 10px #8b63c900; }
  100% { box-shadow: 0 0 0 4px #8b63c91c; }
}

/* ---- Copy and card titles settle in -------------------------------- */
.type-motion .ty-fade {
  opacity: 0;
  transform: translateY(14px);
  filter: blur(5px);
}
.type-motion .ty-fade.is-in {
  animation: ty-settle 1s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  animation-delay: 0.35s;
}
.type-motion h3.ty-fade.is-in { animation-delay: 0.1s; }
.type-motion .cc-hero .ty-fade.is-in { animation-delay: 1.1s; }
@keyframes ty-settle {
  0% { opacity: 0; transform: translateY(14px); filter: blur(5px); letter-spacing: 0.03em; }
  100% { opacity: 1; transform: none; filter: none; }
}

/* ---- Buttons: a sheen crosses now and then, and on hover ----------- */
.type-motion .button { position: relative; overflow: hidden; isolation: isolate; }
.type-motion .button::after {
  content: "";
  position: absolute;
  inset: -20% auto -20% -60%;
  width: 45%;
  background: linear-gradient(100deg, #ffffff00, #ffffff40 45%, #f3e3ffaa 50%, #ffffff40 55%, #ffffff00);
  transform: skewX(-18deg) translateX(0);
  pointer-events: none;
  animation: ty-sheen 6.5s ease-in-out 2.4s infinite;
}
.type-motion .button:hover::after { animation: ty-sheen-now 0.9s ease-out; }
@keyframes ty-sheen {
  0% { transform: skewX(-18deg) translateX(0); }
  16%, 100% { transform: skewX(-18deg) translateX(420%); }
}
@keyframes ty-sheen-now {
  from { transform: skewX(-18deg) translateX(0); }
  to { transform: skewX(-18deg) translateX(420%); }
}

/* The details band is deep violet in both themes: glint in pale tones. */
.cc-details { --ty-ink: #d6c3f5; --ty-glint: #ffffff; --ty-gold: #f1dcaa; }
