/* ==========================================================================
   Blowfish mascot — shared, sitewide (86d3rtyv3)
   Loaded on every page next to styles.css, because the footer placement is on
   every page. Everything here is namespaced .blowfish / .bf-* so it cannot
   reach into the Testimonials or Upcoming Trips scenes.

   WHAT IS *NOT* HERE, AND WHY
   The two existing peek placements keep their own wrappers, positioning and
   keyframes (.ts-anim/[data-peek] + peekBob/peekBubble in testimonials.css,
   .ut-peek*/cts-anim + ctsPeek/ctsPeekBub in upcoming-trips.css). Those two
   forks had already drifted apart — a 5px vs 6px bob, a 64px vs 60px bubble
   rise — so folding them into one shared keyframe would have visibly changed
   at least one live page for no gain. The duplication that actually mattered
   was the SVG artwork, and that is now gone: one partial, one copy of the fish.
   The keyframes below are this file's own, for the three NEW placements only.
   ========================================================================== */

/* ---------- the artwork itself ---------- */
/* The partial emits a bare <svg class="blowfish …"> with no wrapper element,
   so existing page rules like `.ut-peek svg { width:100% }` keep matching
   exactly as they did before the swap. */
.blowfish {
  display: block;
  width: 100%;
  height: auto;
}
.blowfish--animated { overflow: visible; }

/* ---------- keyframes (new placements only) ---------- */
@keyframes bfBob { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-5px) } }
@keyframes bfBubble { 0% { transform: translateY(0) scale(.5); opacity: 0 } 20% { opacity: .9 } 100% { transform: translateY(-58px) scale(1.05); opacity: 0 } }
@keyframes bfFinFlap { 0%, 100% { transform: rotate(-8deg) } 50% { transform: rotate(10deg) } }
@keyframes bfSparkTwinkle { 0%, 100% { transform: scale(.7); opacity: .5 } 50% { transform: scale(1.15); opacity: 1 } }

/* ---------- shared mount ---------- */
/* Every placement is decorative: absolutely positioned, never in flow, never
   hit-testable. aria-hidden is set on the SVG by the partial itself. */
.bf-mount {
  position: absolute;
  pointer-events: none;
  user-select: none;
}
.bf-bob { animation: bfBob 4.6s ease-in-out infinite }

/* The little hopeful bubble that rises off him. Same treatment both existing
   placements use, rebuilt here rather than borrowed from either page's sheet. */
.bf-bubble {
  position: absolute;
  left: 74%;
  top: -4px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, rgba(255,255,255,.96), rgba(255,255,255,.2) 60%, rgba(255,255,255,0) 74%);
  animation: bfBubble 4s ease-in infinite;
}

/* ==========================================================================
   PLACEMENT — sitewide footer
   Bottom-right, half-sunk below the footer's own bottom edge so he reads as
   peeking up over the very end of the page.

   Two things keep him off the footer's content, at every width:
     1. .site-footer clips him (overflow:hidden), so he can never spill onto
        the page below or widen the document.
     2. .footer-bottom gets a right-hand lane reserved for him, which pushes
        the "Where Adventures Begin…" tagline clear. The reserve (≥120px) is
        wider than his full footprint (≤134px from the footer's padding edge,
        of which 48px is the footer's own padding), so the two cannot meet.
   Below 861px — the width where the footer collapses toward one column and
   the gutter disappears — he is simply not rendered as a visible element.
   That also means he can contribute nothing to mobile layout or overflow.
   ========================================================================== */
.site-footer { overflow: hidden; }

/* `bottom` tracks `width` on purpose. He is 0.722x as tall as he is wide, and
   the crop has to stay just below his mouth (73.8% down) at every size — a
   fixed offset against a fluid width slices his face off at the narrow end. */
.bf-footer {
  display: none;
  right: clamp(10px, 2vw, 34px);
  bottom: clamp(-16px, -1.3vw, -13px);
  width: clamp(80px, 8vw, 100px);
  z-index: 0;
}

@media (min-width: 861px) {
  .bf-footer { display: block; }
  .footer-bottom { padding-right: clamp(120px, 11vw, 150px); }
}

/* ==========================================================================
   PLACEMENT — The Crew, board corner
   Sits in the empty right-hand gutter of .cs-board (the cards cap at 812px
   inside a board up to ~1140px) and is clipped by the board's existing
   overflow:hidden along its BOTTOM edge only.

   Bottom-edge clipping, not corner clipping, is deliberate: cropping the right
   edge as well would slice through one eye and read as a mistake rather than a
   peek. Clipped this way he keeps a whole face and loses only his lower body.
   z-index sits under .cs-cards (5) and above the doodles (1), so if a very
   wide viewport ever brings a card near him, the card wins.
   Hidden at ≤920px, matching the board's existing rule for .cs-doodle.
   ========================================================================== */
/* Same fluid-crop rule as the footer: this pose is 0.923x as tall as it is
   wide and the eyes sit 47.5% down, so `bottom` scales with `width` to keep a
   steady ~62% of him showing (whole face, no chin) from 920px up. */
#csroot .bf-crew {
  right: clamp(-14px, -1vw, -4px);
  bottom: clamp(-58px, -4.6vw, -42px);
  width: clamp(120px, 13vw, 164px);
  z-index: 2;
}

@media (max-width: 920px) {
  #csroot .bf-crew { display: none; }
}

/* ==========================================================================
   PLACEMENT + PAGE — 404
   The mascot is the whole illustration on this page, so it is the one place he
   is in flow rather than pinned to a corner. Kept small and off-centre-left of
   the card so the page still reads as text-first.
   Page furniture lives here rather than in its own stylesheet: it is ~20 lines,
   and 404.php has no registry entry to hang a per-template sheet on (the
   registry is keyed by page template slug, which a 404 has none of).
   ========================================================================== */
.ct-404 {
  max-width: 620px;
  margin: 0 auto;
  padding: clamp(48px, 9vw, 110px) clamp(18px, 5vw, 32px) clamp(60px, 10vw, 120px);
  text-align: center;
}
.ct-404-fish {
  position: relative;
  width: clamp(150px, 26vw, 210px);
  margin: 0 auto clamp(10px, 2vw, 18px);
}
.ct-404-eyebrow {
  font: 800 12px/1 'Nunito Sans', sans-serif;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--wood);
  margin-bottom: 12px;
}
.ct-404-title {
  font: 700 clamp(38px, 7vw, 62px)/.95 'Caveat', cursive;
  color: var(--teal);
  margin: 0;
  transform: rotate(-1deg);
}
.ct-404-body {
  font: 400 clamp(15px, 2vw, 16.5px)/1.65 'Nunito Sans', sans-serif;
  color: var(--ink);
  margin: 16px auto 0;
  max-width: 420px;
  text-wrap: pretty;
}
.ct-404-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
  align-items: center;
  margin-top: clamp(22px, 3.5vw, 32px);
}
.ct-404-link {
  font: 700 13.5px/1 'Nunito Sans', sans-serif;
  color: var(--teal);
  text-decoration: none;
  border-bottom: 2px solid rgba(11, 110, 102, .35);
  padding-bottom: 3px;
}
.ct-404-link:hover { border-bottom-color: var(--teal); }

/* ==========================================================================
   Reduced motion — one block, all three new placements.
   The two existing placements already kill their own motion (testimonials.css
   [data-ts-root] .ts-anim, upcoming-trips.css .cts-anim), and The Crew's sheet
   already carries #csroot *{animation:none}. This covers everything this file
   introduces, including the footer and 404, which no existing rule reaches.
   blowfish-mascot.js repeats the guard in JS so neither one is load-bearing
   on its own.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .bf-bob,
  .bf-bubble,
  .bf-mount .bf-anim,
  .blowfish .bf-anim { animation: none !important; }
  .blowfish [data-puff-core],
  .blowfish [data-puff-spikes],
  .blowfish [data-puff-lids],
  .blowfish [data-puff-sparkle],
  .blowfish [data-puff-mouth],
  .blowfish [data-puff-pupil],
  .blowfish [data-puff-green],
  .blowfish [data-puff-blush] { transition: none !important; }
}
