/* MysteryReveal — pixel-blurred scrambled text that decrypts on hover/tap.
   All styles scoped under .mystery-reveal-target so they don't bleed into
   the hero name (.encrypted-char) or the featured-excerpt scramble
   (.archive-featured__excerpt .encrypted-text-char, which uses a
   different visual treatment). */


/* ---------- Encrypted character spans ----------
   Tiny font + 2.38x scale gives a chunky pixel-art feel, and a CSS blur
   filter softens the edges. Revealed state transitions back to the host
   font with zero blur. */

.mystery-reveal-target .encrypted-text-char {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.42em;
  transform: scale(2.38);
  transform-origin: center bottom;
  filter: blur(var(--mystery-blur, 2.2px));
  color: var(--color-text-muted);
  opacity: 0.45;
  transition:
    filter 320ms cubic-bezier(0.16, 1, 0.3, 1),
    font-size 320ms cubic-bezier(0.16, 1, 0.3, 1),
    transform 320ms cubic-bezier(0.16, 1, 0.3, 1),
    font-family 250ms ease,
    color 280ms ease,
    opacity 280ms ease;
  will-change: filter, transform, opacity;
}

.mystery-reveal-target .encrypted-text-char.revealed {
  font-family: inherit;
  font-size: 1em;
  transform: scale(1);
  filter: blur(0);
  color: inherit;
  opacity: 1;
}

@keyframes mystery-scramble-pulse {
  0%, 100% { text-shadow: 0 0 3px rgba(139, 0, 0, 0); }
  50%      { text-shadow: 0 0 6px rgba(139, 0, 0, 0.3); }
}
.mystery-reveal-target .encrypted-text-char:not(.revealed) {
  animation: mystery-scramble-pulse 1.6s ease-in-out infinite;
}


/* ---------- Accent border on the mystery container ----------
   Opt-in via --accented modifier. Container picks up a faint dark-red
   left bar that brightens on hover, then fades to transparent once the
   text is revealed so the row looks "normal" again. */

.mystery-reveal-target--accented {
  border-left: 2px solid rgba(139, 0, 0, 0.3);
  padding-left: calc(0.5rem + 4px);
  transition: border-left-color 300ms ease;
}
.mystery-reveal-target--accented:hover {
  border-left-color: rgba(179, 0, 0, 0.6);
}
.mystery-reveal-target--accented.is-revealed {
  border-left-color: transparent;
  transition: border-left-color 800ms ease 500ms;
}


/* ---------- Sibling blur (tags / dates) ----------
   When the container is a .mystery-reveal-target, its child tag pills
   blur out and the date/meta dims, all returning to normal on reveal.
   Disabled per-instance via data-mystery-no-blur-tags / -meta. */

.mystery-reveal-target:not([data-mystery-no-blur-tags]) .tag-pill {
  filter: blur(3px);
  opacity: 0.35;
  transition: filter 400ms ease 200ms, opacity 400ms ease 200ms;
}
/* Trigger unblur the moment the reveal starts (mystery-revealing),
   not when it completes — tags should clear in step with the decrypt,
   not after it. is-revealed keeps the cleared state once done. */
.mystery-reveal-target.mystery-revealing:not([data-mystery-no-blur-tags]) .tag-pill,
.mystery-reveal-target.is-revealed:not([data-mystery-no-blur-tags]) .tag-pill {
  filter: blur(0);
  opacity: 1;
}

.mystery-reveal-target:not([data-mystery-no-blur-meta]) .archive-row__date,
.mystery-reveal-target:not([data-mystery-no-blur-meta]) .thought__meta {
  opacity: 0.4;
  transition: opacity 300ms ease;
}
.mystery-reveal-target.mystery-revealing:not([data-mystery-no-blur-meta]) .archive-row__date,
.mystery-reveal-target.mystery-revealing:not([data-mystery-no-blur-meta]) .thought__meta,
.mystery-reveal-target.is-revealed:not([data-mystery-no-blur-meta]) .archive-row__date,
.mystery-reveal-target.is-revealed:not([data-mystery-no-blur-meta]) .thought__meta {
  opacity: 1;
}


/* ---------- Thoughts: red-tint the existing left border ----------
   .thought already paints its own border-left, so we tint it red while
   encrypted instead of stacking a second --accented border on top. The
   normal hover :hover { border-left-color: var(--color-red) } in
   thoughts.css already does this — here we make it persist until reveal. */

.thought.mystery-reveal-target {
  border-left-color: rgba(139, 0, 0, 0.55);
  transition: border-left-color 300ms ease;
}
.thought.mystery-reveal-target.is-revealed {
  border-left-color: var(--color-border);
  transition: border-left-color 800ms ease 500ms;
}


/* ---------- Hint label ----------
   Small mono "hover me" floating near the encrypted element. Positioned
   absolutely inside the el (which MysteryReveal sets to position:relative
   if needed). Fades out once the container is revealed. */

.mystery-hint {
  font-family: var(--font-mono);
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  text-transform: lowercase;
  color: var(--color-red-bright);
  opacity: 0.6;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity 250ms ease;
}

.mystery-hint--right {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}
.mystery-hint--above {
  position: absolute;
  left: 0;
  bottom: calc(100% + 4px);
}
.mystery-hint--below {
  position: absolute;
  left: 0;
  top: calc(100% + 4px);
}

/* Hint fades the instant reveal kicks off — once the visitor has
   interacted, the "hover me" prompt has served its purpose. */
.mystery-reveal-target.mystery-revealing .mystery-hint,
.mystery-reveal-target.is-revealed .mystery-hint {
  opacity: 0;
}


/* ---------- Archive-row: mute hover choreography while encrypted ----------
   .archive-row's default :hover paints a red-tinted background, slides
   in the left bar, shifts padding-left, and reveals the arrow. On
   touch the hover lingers a beat after tap, so all four flash in
   under the decrypt and read as a "colored box" pulse. While the row
   is the active mystery (and not yet revealed), suppress that whole
   choreography — only the title decrypt + sibling unblur should move.
   .is-revealed restores normal hover affordance for subsequent passes. */

.archive-row.mystery-reveal-target:not(.is-revealed) {
  /* Suppress the mobile browser's blue tap-highlight overlay during the
     reveal — it's the OS-level affordance for "you tapped a link" and
     paints a translucent box over the row mid-decrypt, fighting the
     animation. Restored after .is-revealed so subsequent navigation
     taps get normal feedback. */
  -webkit-tap-highlight-color: transparent;
}
.archive-row.mystery-reveal-target:not(.is-revealed):hover {
  background: transparent;
  border-color: transparent;
  padding-left: 1rem;
}
.archive-row.mystery-reveal-target:not(.is-revealed):hover .archive-row__bar {
  opacity: 0;
  transform: scaleY(0.4);
}
.archive-row.mystery-reveal-target:not(.is-revealed):hover .archive-row__arrow {
  opacity: 0;
  transform: translateX(-5px);
}


/* ---------- Responsive: archive-row hint placement ----------
   On mobile the archive grid collapses to date-on-top, title | tags —
   the title cell shrinks to share its row with the tag column, so a
   right-anchored hint lands behind the tag pills. Reposition it below
   the title where there's free vertical space, and shrink it a touch
   so it doesn't feel shouty next to the smaller mobile type. */

@media (max-width: 600px) {
  .archive-row .mystery-hint--right {
    right: auto;
    left: 0;
    top: calc(100% + 2px);
    transform: none;
    font-size: 0.45rem;
  }
  /* Match the mobile-default padding-left so the mute-hover override
     doesn't accidentally nudge the row 0.1rem on tap. */
  .archive-row.mystery-reveal-target:not(.is-revealed):hover {
    padding-left: 0.9rem;
  }
}


/* ---------- Reduced motion ----------
   Honor the user setting: no glow pulse, no character cycling. JS also
   passes charDelay:0 to reveal everything in one synchronous tick so
   there's no staggered animation either. */

@media (prefers-reduced-motion: reduce) {
  .mystery-reveal-target .encrypted-text-char:not(.revealed) {
    animation: none;
  }
  .mystery-reveal-target .encrypted-text-char {
    transition: none;
  }
}
