/* ============================================================
   Delight — two moments below the hero.

   The hero is out of scope and untouched, and so is the header
   pill: no selector here matches inside .mast or header.

   Neither moment is invented. Both are already promised by the
   page and never delivered:

   1. The section is called Lightning Round and behaves like a
      bulleted list. The bolt strikes, and the round fires.
   2. Every "Email me" on this page is a mailto:, which does
      nothing at all for a visitor with no mail client wired up —
      on the page whose entire ask is "email me". The click now
      leaves the address on their clipboard and says so.
   ============================================================ */

/* ---------------------------------------------------------------
   The bolt strikes

   A real strike is a double flash, not a fade, so every step is a
   hard cut. It runs once, when the block is reached, and it is
   what sets the round off — the rows follow it in motion.css.
   --------------------------------------------------------------- */

.loaded main .lightning .tag .emoji.invert {
  display: inline-block;
  transform-origin: 50% 60%;
}

/* Fires on .struck, not .shown. The section observer adds .shown the
   instant the block's top edge touches the bottom of the screen, so at
   any real scrolling speed the flash was finished before the reader's
   eye arrived — the strike was measurably running and still went
   unnoticed. index.html adds .struck from its own observer once the
   block is 38% up the viewport. */
.loaded main .lightning.struck .tag .emoji.invert {
  animation: boltStrike 1.1s both;
}

/* Two hard leader flashes, then the main flash glows down. A 16px
   greyscale glyph going briefly to colour is too small a signal on its
   own, so the strike also lights the pill it sits in — the resting
   shadow is restored exactly at 100%. */
@keyframes boltStrike {
  0% {
    filter: saturate(0) invert(1);
    transform: scale(1);
    animation-timing-function: steps(1, end);
  }
  12% {
    filter: none;
    transform: scale(1.55) rotate(-7deg);
    animation-timing-function: steps(1, end);
  }
  26% {
    filter: saturate(0) invert(1);
    transform: scale(1);
    animation-timing-function: steps(1, end);
  }
  40% {
    filter: none;
    transform: scale(1.9) rotate(5deg);
    animation-timing-function: steps(1, end);
  }
  /* Hold the main flash before letting it go. The ease-out is
     front-loaded enough that decaying straight from 40% made the payoff
     dimmer than the leader flash within ~30ms. */
  52% {
    filter: none;
    transform: scale(1.9) rotate(5deg);
    animation-timing-function: cubic-bezier(.16, 1, .3, 1);
  }
  100% {
    filter: saturate(0) invert(1);
    transform: scale(1) rotate(0deg);
  }
}

.loaded main .lightning.struck .tag {
  animation: strikeGlow 1.1s both;
}

@keyframes strikeGlow {
  0% {
    box-shadow: #00000012 0 0 0 1px, inset #ffffff1f 1px 1px, inset #ffffff57 0 1px 6px;
    animation-timing-function: steps(1, end);
  }
  12% {
    box-shadow: var(--accent) 0 0 0 1px, var(--accent-soft) 0 0 16px 1px, inset #ffffff1f 1px 1px, inset #ffffff57 0 1px 6px;
    animation-timing-function: steps(1, end);
  }
  26% {
    box-shadow: #00000012 0 0 0 1px, inset #ffffff1f 1px 1px, inset #ffffff57 0 1px 6px;
    animation-timing-function: steps(1, end);
  }
  40% {
    box-shadow: var(--accent) 0 0 0 1px, var(--accent-soft) 0 0 22px 3px, inset #ffffff1f 1px 1px, inset #ffffff57 0 1px 6px;
    animation-timing-function: steps(1, end);
  }
  52% {
    box-shadow: var(--accent) 0 0 0 1px, var(--accent-soft) 0 0 22px 3px, inset #ffffff1f 1px 1px, inset #ffffff57 0 1px 6px;
    animation-timing-function: cubic-bezier(.16, 1, .3, 1);
  }
  100% {
    box-shadow: #00000012 0 0 0 1px, inset #ffffff1f 1px 1px, inset #ffffff57 0 1px 6px;
  }
}

/* ---------------------------------------------------------------
   The address is already on your clipboard

   Confirmation is the page's own .tag material — the glass pill
   already used for "Lightning Round" and "On Screen" — pinned to
   the link that was actually clicked, rather than a toast from
   somewhere else. It carries the address itself, so if the mail
   client never opened, the answer is right there to read.

   The anchor is position:relative from the base sheet, and
   scripts.js only ever replaces .rgbsplit innerHTML, so a
   pseudo-element on the anchor survives that rewrite untouched.
   --------------------------------------------------------------- */

main p:has(a[href^="mailto:"]),
footer li:has(a[href^="mailto:"]) {
  position: relative;
}

/* Anchored to the block, not to the link: "Email me, or find me on
   Instagram or LinkedIn." wraps on a phone, and a pill hung under the
   link itself landed on the second line of its own sentence. */
main p:has(a[href^="mailto:"])::after,
footer li:has(a[href^="mailto:"])::after {
  backdrop-filter: saturate(142%) blur(20px);
  background: color-mix(in srgb, #fff, transparent 25%);
  border-radius: .43em;
  box-shadow:
    #00000012 0 0 0 1px,
    inset #ffffff1f 1px 1px,
    inset #ffffff57 0 1px 6px;
  color: var(--color-fill);
  content: attr(data-copied) " copied";
  font-size: var(--size-s);
  font-weight: 500;
  left: 0;
  opacity: 0;
  padding: .2em .6em;
  pointer-events: none;
  position: absolute;
  top: calc(100% + .55em);
  transform: translateY(-.35em);
  transition:
    opacity .2s ease,
    transform .2s var(--m-rise-ease, cubic-bezier(.16, 1, .3, 1)),
    visibility 0s .2s;
  visibility: hidden;
  white-space: nowrap;
  z-index: 120;
}
/* :has() carries the specificity of its argument, so the hidden rule
   above outranks a plain .copied — the selector has to be repeated. */
main p:has(a[href^="mailto:"]).copied::after,
footer li:has(a[href^="mailto:"]).copied::after {
  opacity: 1;
  transform: none;
  transition-delay: 0s;
  visibility: visible;
}

/* A 21-character address does not fit beside a link on a 390px
   screen, and a phone almost certainly did open a mail client. */
@media screen and (width < 768px) {
  main p:has(a[href^="mailto:"])::after,
  footer li:has(a[href^="mailto:"])::after {
    content: "Copied";
  }
}

@media (prefers-reduced-motion: reduce) {
  .loaded main .lightning.struck .tag .emoji.invert,
  .loaded main .lightning.struck .tag {
    animation: none !important;
  }
}
