/*
 * Mascot CSS
 * Responsive, collision-safe mascot placement utilities.
 * CSS-only. No JavaScript required.
 *
 * Recommended markup:
 *
 * <section class="mascot-box mascot-right dock-bottom overflow-top-20 mascot-lg">
 *   <div class="mascot-content">...</div>
 *   <div class="mascot-slot">
 *     <img class="mascot" src="mascot.webp" alt="">
 *   </div>
 * </section>
 */

:root {
  --mascot-breakpoint: 48rem;
}

/* =========================================================
   BASE LAYOUT
   ========================================================= */

.mascot-box {
  --mascot-gap: clamp(1rem, 2.5vw, 2rem);
  --mascot-padding-x: clamp(1rem, 3vw, 2rem);
  --mascot-padding-y: clamp(1rem, 3vw, 2rem);

  --mascot-zone: clamp(12rem, 32vw, 24rem);
  --mascot-size: clamp(10rem, 28vw, 22rem);
  --mascot-max-height: 100%;
  --mascot-slot-min-height: clamp(14rem, 34vw, 24rem);

  --mascot-x: 0%;
  --mascot-y: 0%;
  --mascot-scale: 1;

  --mascot-safe-top: 0px;
  --mascot-safe-bottom: 0px;

  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--mascot-zone));
  grid-template-areas: "content mascot";
  gap: var(--mascot-gap);
  align-items: stretch;
  min-width: 0;
  padding: var(--mascot-padding-y) var(--mascot-padding-x);

  /* Visible overflow is intentional. Safe-space utilities reserve room. */
  overflow: visible;

  margin-block-start: var(--mascot-safe-top);
  margin-block-end: var(--mascot-safe-bottom);

  transition:
    grid-template-columns 280ms ease,
    gap 280ms ease,
    padding 280ms ease,
    margin 280ms ease;
}

.mascot-content {
  grid-area: content;
  position: relative;
  z-index: 2;
  min-width: 0;
  align-self: center;
}

.mascot-slot {
  grid-area: mascot;
  position: relative;
  z-index: 1;
  min-width: 0;
  min-height: var(--mascot-slot-min-height);
  display: grid;
  align-items: end;
  justify-items: end;
  pointer-events: none;
  overflow: visible;
}

.mascot {
  display: block;
  width: min(100%, var(--mascot-size));
  max-width: 100%;
  max-height: var(--mascot-max-height);
  height: auto;
  object-fit: contain;
  object-position: center bottom;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;

  transform:
    translate(var(--mascot-x), var(--mascot-y))
    scale(var(--mascot-scale));

  transition:
    width 280ms ease,
    max-height 280ms ease,
    transform 280ms ease;
}

/* =========================================================
   HORIZONTAL PLACEMENT
   Desktop/tablet. Mobile centers by default.
   ========================================================= */

.mascot-right {
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--mascot-zone));
  grid-template-areas: "content mascot";
}

.mascot-right > .mascot-slot {
  justify-items: end;
}

.mascot-left {
  grid-template-columns: minmax(0, var(--mascot-zone)) minmax(0, 1fr);
  grid-template-areas: "mascot content";
}

.mascot-left > .mascot-slot {
  justify-items: start;
}

.mascot-center {
  grid-template-columns: 1fr;
  grid-template-areas:
    "content"
    "mascot";
}

.mascot-center > .mascot-slot {
  justify-items: center;
}

/* =========================================================
   VERTICAL DOCKING
   ========================================================= */

.dock-bottom > .mascot-slot,
.mascot-dock-bottom > .mascot-slot {
  align-items: end;
}

.dock-bottom > .mascot-slot > .mascot,
.mascot-dock-bottom > .mascot-slot > .mascot {
  object-position: center bottom;
  transform-origin: center bottom;
}

.dock-top > .mascot-slot,
.mascot-dock-top > .mascot-slot {
  align-items: start;
}

.dock-top > .mascot-slot > .mascot,
.mascot-dock-top > .mascot-slot > .mascot {
  object-position: center top;
  transform-origin: center top;
}

.dock-center > .mascot-slot,
.mascot-dock-center > .mascot-slot {
  align-items: center;
}

.dock-center > .mascot-slot > .mascot,
.mascot-dock-center > .mascot-slot > .mascot {
  object-position: center center;
  transform-origin: center center;
}

/* =========================================================
   SIZE UTILITIES
   ========================================================= */

.mascot-xs { --mascot-size: clamp(6rem, 14vw, 10rem); --mascot-zone: clamp(8rem, 18vw, 12rem); }
.mascot-sm { --mascot-size: clamp(8rem, 19vw, 14rem); --mascot-zone: clamp(10rem, 23vw, 16rem); }
.mascot-md { --mascot-size: clamp(10rem, 25vw, 18rem); --mascot-zone: clamp(12rem, 29vw, 20rem); }
.mascot-lg { --mascot-size: clamp(12rem, 31vw, 23rem); --mascot-zone: clamp(14rem, 35vw, 25rem); }
.mascot-xl { --mascot-size: clamp(14rem, 38vw, 30rem); --mascot-zone: clamp(16rem, 42vw, 32rem); }

/* Optical scaling. Useful when a transparent asset has a tighter crop or
   should occupy more of its reserved slot without changing the slot width. */
.mascot-scale-105 { --mascot-scale: 1.05; }
.mascot-scale-110 { --mascot-scale: 1.1; }
.mascot-scale-115 { --mascot-scale: 1.15; }

/* Fill the reserved slot height. Useful for full-body grounded mascots. */
.mascot-fill > .mascot-slot > .mascot {
  width: auto;
  height: 100%;
  max-width: 100%;
  max-height: none;
}

/* =========================================================
   OVERFLOW / PEEK

   Important behavior:
   - dock-bottom + overflow-top-X keeps feet docked and scales upward.
   - dock-top + overflow-bottom-X keeps head/top docked and scales downward.
   - other combinations translate the mascot in the requested direction.

   One vertical overflow utility at a time is recommended.
   ========================================================= */

/* Values are chosen so X% of the FINAL mascot height is outside.
   scale = 1 / (1 - X).
   5%  => 1.0526316
   10% => 1.1111111
   15% => 1.1764706
   20% => 1.25
   25% => 1.3333333
   30% => 1.4285714
*/

.overflow-top-5,
.mascot-overflow-top-5 {
  --mascot-overflow-top: 5%;
  --mascot-overflow-scale: 1.0526316;
  --mascot-safe-top: clamp(.4rem, 1vw, .8rem);
}

.overflow-top-10,
.mascot-overflow-top-10 {
  --mascot-overflow-top: 10%;
  --mascot-overflow-scale: 1.1111111;
  --mascot-safe-top: clamp(.8rem, 2vw, 1.6rem);
}

.overflow-top-15,
.mascot-overflow-top-15 {
  --mascot-overflow-top: 15%;
  --mascot-overflow-scale: 1.1764706;
  --mascot-safe-top: clamp(1.1rem, 3vw, 2.3rem);
}

.overflow-top-20,
.mascot-overflow-top-20 {
  --mascot-overflow-top: 20%;
  --mascot-overflow-scale: 1.25;
  --mascot-safe-top: clamp(1.5rem, 4vw, 3rem);
}

.overflow-top-25,
.mascot-overflow-top-25 {
  --mascot-overflow-top: 25%;
  --mascot-overflow-scale: 1.3333333;
  --mascot-safe-top: clamp(1.9rem, 5vw, 3.8rem);
}

.overflow-top-30,
.mascot-overflow-top-30 {
  --mascot-overflow-top: 30%;
  --mascot-overflow-scale: 1.4285714;
  --mascot-safe-top: clamp(2.2rem, 6vw, 4.5rem);
}

.overflow-bottom-5,
.mascot-overflow-bottom-5 {
  --mascot-overflow-bottom: 5%;
  --mascot-overflow-scale: 1.0526316;
  --mascot-safe-bottom: clamp(.4rem, 1vw, .8rem);
}

.overflow-bottom-10,
.mascot-overflow-bottom-10 {
  --mascot-overflow-bottom: 10%;
  --mascot-overflow-scale: 1.1111111;
  --mascot-safe-bottom: clamp(.8rem, 2vw, 1.6rem);
}

.overflow-bottom-15,
.mascot-overflow-bottom-15 {
  --mascot-overflow-bottom: 15%;
  --mascot-overflow-scale: 1.1764706;
  --mascot-safe-bottom: clamp(1.1rem, 3vw, 2.3rem);
}

.overflow-bottom-20,
.mascot-overflow-bottom-20 {
  --mascot-overflow-bottom: 20%;
  --mascot-overflow-scale: 1.25;
  --mascot-safe-bottom: clamp(1.5rem, 4vw, 3rem);
}

.overflow-bottom-25,
.mascot-overflow-bottom-25 {
  --mascot-overflow-bottom: 25%;
  --mascot-overflow-scale: 1.3333333;
  --mascot-safe-bottom: clamp(1.9rem, 5vw, 3.8rem);
}

.overflow-bottom-30,
.mascot-overflow-bottom-30 {
  --mascot-overflow-bottom: 30%;
  --mascot-overflow-scale: 1.4285714;
  --mascot-safe-bottom: clamp(2.2rem, 6vw, 4.5rem);
}

/* Correct semantics for the most common grounded combinations. */
:is(.dock-bottom, .mascot-dock-bottom):is(
  .overflow-top-5, .overflow-top-10, .overflow-top-15,
  .overflow-top-20, .overflow-top-25, .overflow-top-30,
  .mascot-overflow-top-5, .mascot-overflow-top-10, .mascot-overflow-top-15,
  .mascot-overflow-top-20, .mascot-overflow-top-25, .mascot-overflow-top-30
) > .mascot-slot > .mascot {
  --mascot-scale: var(--mascot-overflow-scale);
  --mascot-y: 0%;
  transform-origin: center bottom;
}

:is(.dock-top, .mascot-dock-top):is(
  .overflow-bottom-5, .overflow-bottom-10, .overflow-bottom-15,
  .overflow-bottom-20, .overflow-bottom-25, .overflow-bottom-30,
  .mascot-overflow-bottom-5, .mascot-overflow-bottom-10, .mascot-overflow-bottom-15,
  .mascot-overflow-bottom-20, .mascot-overflow-bottom-25, .mascot-overflow-bottom-30
) > .mascot-slot > .mascot {
  --mascot-scale: var(--mascot-overflow-scale);
  --mascot-y: 0%;
  transform-origin: center top;
}

/* Less common combinations: move instead of scaling from the opposite dock. */
:is(.dock-top, .mascot-dock-top, .dock-center, .mascot-dock-center):is(
  .overflow-top-5, .overflow-top-10, .overflow-top-15,
  .overflow-top-20, .overflow-top-25, .overflow-top-30,
  .mascot-overflow-top-5, .mascot-overflow-top-10, .mascot-overflow-top-15,
  .mascot-overflow-top-20, .mascot-overflow-top-25, .mascot-overflow-top-30
) > .mascot-slot > .mascot {
  --mascot-y: calc(-1 * var(--mascot-overflow-top));
}

:is(.dock-bottom, .mascot-dock-bottom, .dock-center, .mascot-dock-center):is(
  .overflow-bottom-5, .overflow-bottom-10, .overflow-bottom-15,
  .overflow-bottom-20, .overflow-bottom-25, .overflow-bottom-30,
  .mascot-overflow-bottom-5, .mascot-overflow-bottom-10, .mascot-overflow-bottom-15,
  .mascot-overflow-bottom-20, .mascot-overflow-bottom-25, .mascot-overflow-bottom-30
) > .mascot-slot > .mascot {
  --mascot-y: var(--mascot-overflow-bottom);
}

/* =========================================================
   NUDGE UTILITIES
   Small artistic corrections without breaking layout.
   ========================================================= */

.mascot-nudge-left-5  > .mascot-slot > .mascot { --mascot-x: -5%; }
.mascot-nudge-left-10 > .mascot-slot > .mascot { --mascot-x: -10%; }
.mascot-nudge-left-15 > .mascot-slot > .mascot { --mascot-x: -15%; }
.mascot-nudge-left-20 > .mascot-slot > .mascot { --mascot-x: -20%; }

.mascot-nudge-right-5  > .mascot-slot > .mascot { --mascot-x: 5%; }
.mascot-nudge-right-10 > .mascot-slot > .mascot { --mascot-x: 10%; }
.mascot-nudge-right-15 > .mascot-slot > .mascot { --mascot-x: 15%; }
.mascot-nudge-right-20 > .mascot-slot > .mascot { --mascot-x: 20%; }

.mascot-nudge-up-5  > .mascot-slot > .mascot { --mascot-y: -5%; }
.mascot-nudge-up-10 > .mascot-slot > .mascot { --mascot-y: -10%; }
.mascot-nudge-down-5  > .mascot-slot > .mascot { --mascot-y: 5%; }
.mascot-nudge-down-10 > .mascot-slot > .mascot { --mascot-y: 10%; }

/* Let a visually cropped mascot meet the container edge instead of stopping
   at the component's inner padding. The desktop-only form keeps the default
   stacked mobile breathing room intact. */
.mascot-bleed-bottom > .mascot-slot {
  margin-block-end: calc(-1 * var(--mascot-padding-y));
}

@media (min-width: 48.001rem) {
  .mascot-desktop-bleed-bottom > .mascot-slot {
    margin-block-end: calc(-1 * var(--mascot-padding-y));
  }
}

/* =========================================================
   CONTENT / INTERACTION UTILITIES
   ========================================================= */

.mascot-clickable > .mascot-slot,
.mascot-clickable > .mascot-slot > .mascot {
  pointer-events: auto;
}

/* Optional linked mascot. Keep the anchor as the direct .mascot child so all
   existing size, dock, nudge and overflow utilities continue to work. */
.mascot-link {
  position: relative;
  color: inherit;
  text-decoration: none;
  pointer-events: auto;
}

.mascot-link > .mascot-link-image {
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain;
}

.mascot-link:focus-visible {
  outline: 3px solid color-mix(in srgb, currentColor 70%, transparent);
  outline-offset: .35rem;
  border-radius: .75rem;
}

/* Generic delayed disclosure for a linked mascot. Text and destination stay
   in the markup, while --mascot-reveal-delay controls the hover delay. */
.mascot-link-reveal {
  position: absolute;
  z-index: 5;
  inset-inline-start: 50%;
  inset-block-start: 12%;
  min-width: max-content;
  padding: .65rem .8rem;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: .8rem;
  color: #fff;
  background: rgba(8, 20, 36, .92);
  box-shadow: 0 .8rem 2rem rgba(0, 0, 0, .25);
  font: 700 .78rem/1.2 system-ui, sans-serif;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  translate: -50% .5rem;
  transition:
    opacity 180ms ease,
    visibility 180ms ease,
    translate 180ms ease;
  transition-delay: 0ms;
}

.mascot-link:is(:hover, :focus-visible) > .mascot-link-reveal {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  translate: -50% 0;
  transition-delay: var(--mascot-reveal-delay, 2s);
}

.mascot-no-transition,
.mascot-no-transition > .mascot-slot > .mascot {
  transition: none !important;
}

.mascot-behind > .mascot-slot { z-index: 0; }
.mascot-behind > .mascot-content { z-index: 1; }

.mascot-front > .mascot-slot { z-index: 3; }
.mascot-front > .mascot-content { z-index: 2; }

/* Optional clipping when overflow is not wanted. */
.mascot-clip {
  overflow: clip;
  --mascot-safe-top: 0px;
  --mascot-safe-bottom: 0px;
}

/* =========================================================
   MOBILE
   Default philosophy:
   - content first
   - mascot second
   - mascot centered
   This prevents left/right desktop choices from looking awkward on phones.
   ========================================================= */

@media (max-width: 48rem) {
  .mascot-box {
    --mascot-zone: 100%;
    --mascot-size: min(68vw, 18rem);
    --mascot-slot-min-height: clamp(10rem, 52vw, 17rem);

    grid-template-columns: 1fr;
    grid-template-areas:
      "content"
      "mascot";
  }

  .mascot-box > .mascot-slot {
    justify-items: center;
  }

  .mascot-box > .mascot-slot > .mascot {
    object-position: center bottom;
  }

  /* Explicit mobile placement overrides. */
  .mascot-mobile-top {
    grid-template-areas:
      "mascot"
      "content";
  }

  .mascot-mobile-bottom {
    grid-template-areas:
      "content"
      "mascot";
  }

  .mascot-mobile-left > .mascot-slot { justify-items: start; }
  .mascot-mobile-center > .mascot-slot { justify-items: center; }
  .mascot-mobile-right > .mascot-slot { justify-items: end; }

  .mascot-mobile-hide > .mascot-slot {
    display: none;
  }

  /* Preserve desktop side-by-side layout only when explicitly requested. */
  .mascot-mobile-side.mascot-left {
    grid-template-columns: minmax(7rem, 36%) minmax(0, 1fr);
    grid-template-areas: "mascot content";
  }

  .mascot-mobile-side.mascot-right {
    grid-template-columns: minmax(0, 1fr) minmax(7rem, 36%);
    grid-template-areas: "content mascot";
  }

  .mascot-mobile-side > .mascot-slot {
    min-height: 100%;
  }
}

/* Very small phones: constrain size and overflow reserve. */
@media (max-width: 30rem) {
  .mascot-box {
    --mascot-size: min(72vw, 15rem);
    --mascot-slot-min-height: clamp(9rem, 58vw, 14rem);
  }

  .overflow-top-20,
  .mascot-overflow-top-20,
  .overflow-top-25,
  .mascot-overflow-top-25,
  .overflow-top-30,
  .mascot-overflow-top-30 {
    --mascot-safe-top: clamp(1rem, 5vw, 1.6rem);
  }

  .overflow-bottom-20,
  .mascot-overflow-bottom-20,
  .overflow-bottom-25,
  .mascot-overflow-bottom-25,
  .overflow-bottom-30,
  .mascot-overflow-bottom-30 {
    --mascot-safe-bottom: clamp(1rem, 5vw, 1.6rem);
  }
}

/* Respect reduced motion preference. */
@media (prefers-reduced-motion: reduce) {
  .mascot-box,
  .mascot,
  .mascot-content,
  .mascot-slot {
    transition: none !important;
  }
}
