/*
 * Polaris Point Folio — Homepage styles (v1.1.0)
 *
 * Layered for easy editing. Design tokens live in :root.
 * Merriweather is the default font; enqueued via functions.php.
 *
 * IMAGE ASSETS: all files live in assets/img/. The PHP template references
 * them with get_stylesheet_directory_uri(). Filenames with spaces or special
 * characters (#, &) are URL-encoded inline below where needed.
 */

:root {
  /* This page is designed for a light color scheme. Declaring it here stops
     browsers' "force dark mode" (e.g. Brave, Chrome auto-dark) from inverting
     or recoloring the text and panels against the intended palette. */
  color-scheme: light;

  /* ---- Brand palette ---------------------------------------------------- */
  --navy:        #1f2d4a;
  --navy-deep:   #16233c;
  --forest:      #2f5d4f;
  --forest-deep: #1f3f35;
  --white:       #ffffff;
  --warm-gray:   #8a857c;   /* desktop fabric body fallback color */
  --page-bg:     #c9c6cf;
  --ink:         #20303f;
  --paper:       #f4f2ec;

  /* ---- Layout dimensions ------------------------------------------------ */
  --panel-w:      340px;    /* FIXED panel width — header & body grids share it */
  --header-h:     118px;    /* shorter header */
  --header-h-compact: 88px;
  --logo-overhang: 84px;
  --maxw:         1500px;

  /* ---- Spacing scale ---------------------------------------------------- */
  --sp-1: 6px;  --sp-2: 12px; --sp-3: 20px;
  --sp-4: 32px; --sp-5: 48px; --sp-6: 72px;

  /* ---- Motion ----------------------------------------------------------- */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur:  760ms;

  /* ---- Disc shadow (applied to <img> via filter for image-based discs) -- */
  --disc-shadow: drop-shadow(0 6px 8px rgba(30, 35, 45, 0.18))
                 drop-shadow(0 1px 2px rgba(30, 35, 45, 0.10));
  --disc-shadow-hover: drop-shadow(0 14px 16px rgba(20, 25, 35, 0.26))
                       drop-shadow(0 4px 6px rgba(20, 25, 35, 0.14));
}

/* Fonts: Merriweather is enqueued via functions.php */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
  font-family: 'Merriweather', Georgia, 'Times New Roman', serif;
  color: var(--ink);
  background-color: var(--page-bg);
  -webkit-font-smoothing: antialiased;
  /* Page is a single-screen landing; fill the viewport, no forced scroll. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ===========================================================================
   STICKY HEADER — fixed-width left column so panel + body column never drift.
   =========================================================================== */
.pp-header {
  position: sticky;
  top: 0;
  z-index: 100;
  display: grid;
  grid-template-columns: var(--panel-w) 1fr;
  transition: box-shadow 400ms var(--ease);
}
.pp-header.is-compact {
  box-shadow: 0 8px 28px rgba(20, 30, 50, 0.18);
}

/* ---- LEFT: navy night-sky panel ----------------------------------------- */
.pp-panel {
  position: relative;
  overflow: visible;
  background-color: var(--navy);
  /* Background IMAGE comes from inline style in the template (so it can
     reference get_stylesheet_directory_uri()). We layer effects on top. */
  background-size: cover;
  background-position: center;
  min-height: var(--header-h);
  height: var(--header-h);
  transition: height 400ms var(--ease);
}
.pp-header.is-compact .pp-panel { height: var(--header-h-compact); }

/* Star field overlay — adds gentle drifting stars on top of the bg image */
.pp-stars {
  position: absolute; inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.pp-stars::before,
.pp-stars::after {
  content: "";
  position: absolute; inset: -20%;
  background-image:
    radial-gradient(1.4px 1.4px at 20% 30%, rgba(255,255,255,.9), transparent),
    radial-gradient(1px 1px at 65% 18%, rgba(255,255,255,.7), transparent),
    radial-gradient(1.2px 1.2px at 80% 55%, rgba(255,255,255,.6), transparent),
    radial-gradient(1px 1px at 38% 70%, rgba(255,255,255,.5), transparent),
    radial-gradient(1.6px 1.6px at 50% 42%, rgba(255,255,255,.85), transparent),
    radial-gradient(0.9px 0.9px at 12% 60%, rgba(255,255,255,.5), transparent),
    radial-gradient(1px 1px at 88% 30%, rgba(255,255,255,.6), transparent),
    radial-gradient(1.1px 1.1px at 72% 78%, rgba(255,255,255,.5), transparent),
    radial-gradient(0.8px 0.8px at 28% 12%, rgba(255,255,255,.45), transparent);
  background-repeat: no-repeat;
  animation: ppStarDrift 26s linear infinite alternate;
}
.pp-stars::after {
  opacity: .5;
  transform: scale(1.3) translateY(8%);
  animation-duration: 38s;
}
@keyframes ppStarDrift {
  from { transform: translateY(0); }
  to   { transform: translateY(-10px); }
}

/* ---- The animated North Star (more detailed) --------------------------- */
.pp-northstar {
  position: absolute;
  top: 22px;
  right: 26%;
  width: 40px; height: 40px;
  pointer-events: none;
  transform-origin: center;
  animation: ppTwinkle 9s ease-in-out infinite;
}
.pp-northstar svg { width: 100%; height: 100%; display: block; overflow: visible; }
@keyframes ppTwinkle {
  /* Most of the 9s cycle is the gentle pulse most viewers see */
  0%   { opacity: .8;  transform: scale(0.98); filter: drop-shadow(0 0 2px rgba(255,255,255,.4)); }
  25%  { opacity: 1;   transform: scale(1.03); filter: drop-shadow(0 0 6px rgba(200,220,255,.7)); }
  50%  { opacity: .8;  transform: scale(0.98); filter: drop-shadow(0 0 2px rgba(255,255,255,.4)); }
  /* Rare wink near the end — collapses to a point, then bursts back */
  78%  { opacity: 1;   transform: scale(1);    filter: drop-shadow(0 0 4px rgba(200,220,255,.6)); }
  82%  { opacity: .25; transform: scale(0.18); filter: drop-shadow(0 0 1px rgba(255,255,255,.2)); }
  86%  { opacity: 1;   transform: scale(1.18); filter: drop-shadow(0 0 14px rgba(220,235,255,1)); }
  92%  { opacity: 1;   transform: scale(1.02); filter: drop-shadow(0 0 6px rgba(200,220,255,.7)); }
  100% { opacity: .8;  transform: scale(0.98); filter: drop-shadow(0 0 2px rgba(255,255,255,.4)); }
}

/* ---- Polaris Point logo (overhangs the panel) -------------------------- */
/* The logo is two layered images:
     .logo-wordmark  — book + "Polaris Point FOLIO" text (the static base)
     .logo-star      — the compass-star illustration, positioned ON TOP of
                       the book, rotates on hover.
   Each has a desktop and mobile variant, swapped at the 820px breakpoint. */
.pp-logo {
  position: absolute;
  left: 50%;
  bottom: calc(-1.3 * var(--logo-overhang));
  transform: translateX(-50%);
  width: 210px;
  z-index: 3;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: width 400ms var(--ease), bottom 400ms var(--ease);
}
.pp-header.is-compact .pp-logo {
  width: 150px;
  bottom: calc(-0.62 * var(--logo-overhang));
}
/* The logo images are wrapped in an <a> (home link). Keep that wrapper fully
   layout-neutral so the existing logo sizing/animation is unaffected. */
.pp-logo .pp-logo-link {
  display: block;
  line-height: 0;
  text-decoration: none;
  color: inherit;
}
/* Wordmark sits in normal flow and defines the logo's height */
.pp-logo .logo-wordmark {
  width: 100%;
  height: auto;
  display: block;
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.28));
  position: relative;
  z-index: 1;
}
/* Star is the SAME canvas as the wordmark (just parts removed), so it
   overlays 1:1 at full size — no positioning math needed. */
.pp-logo .logo-star {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: auto;
  display: block;
  z-index: 2;
  transform-origin: center center;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,.25));
}
/* Hide mobile variants on desktop; mobile media query flips this */
.pp-logo .logo-star-mobile,
.pp-logo .logo-wordmark-mobile { display: none; }
/* logo-mobile-scroll is the single combined image used only when the user
   has scrolled on mobile. Hidden by default, revealed by mobile rules below. */
.pp-logo .logo-mobile-scroll {
  display: none;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.28));
}

/* Multi-phase compass swing: right with overshoot, hold heading, swing back
   left past center, settle home. Triggered by hover OR the .is-swinging
   class (added by JS on mobile tap). Animation always ends at 0°, so it
   doesn't matter if the user mouses away mid-swing. */
@keyframes ppCompassSwing {
  0%   { transform: rotate(0deg); }
  18%  { transform: rotate(22deg); }    /* swing right past target */
  32%  { transform: rotate(15deg); }    /* brief settle at heading */
  62%  { transform: rotate(-22deg); }   /* swing back FURTHER left */
  82%  { transform: rotate(6deg); }     /* swing back through center */
  100% { transform: rotate(0deg); }     /* home */
}

@media (hover: hover) {
  .pp-logo:hover .logo-star {
    animation: ppCompassSwing 2000ms cubic-bezier(.32,.7,.42,1) forwards;
  }
}
.pp-logo:focus-within .logo-star {
  animation: ppCompassSwing 2000ms cubic-bezier(.32,.7,.42,1) forwards;
}
.pp-logo.is-swinging .logo-star {
  animation: ppCompassSwing 2000ms cubic-bezier(.32,.7,.42,1) forwards;
}

@media (prefers-reduced-motion: reduce) {
  .pp-logo:hover .logo-star,
  .pp-logo:focus-within .logo-star,
  .pp-logo.is-swinging .logo-star { animation: none; }
}

/* ---- RIGHT: white paper strip with the four brand names ---------------- */
.pp-topbar {
  position: relative;
  background-color: var(--paper);
  /* desktop "right side" paper-texture image goes here via inline style.
     Anchor left + stretch full width so there's no gap next to the panel. */
  background-size: 100% 100%;
  background-position: left center;
  background-repeat: no-repeat;
  display: flex;
  align-items: center;
  min-height: var(--header-h);
  height: var(--header-h);
  padding: 0 var(--sp-5);
  transition: height 400ms var(--ease);
}
.pp-header.is-compact .pp-topbar { height: var(--header-h-compact); }

.pp-nav {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  width: 100%;
  gap: var(--sp-3);
  align-items: end;
  height: 100%;
  padding-bottom: 30px;
}

/* Brand name in the top strip — IMAGE based */
.pp-brandname {
  text-align: center;
  user-select: none;
}
.pp-brandname img {
  max-width: 100%;
  max-height: 64px;
  height: auto;
  width: auto;
  display: inline-block;
  transition: max-height 400ms var(--ease);
}
.pp-header.is-compact .pp-brandname img { max-height: 44px; }

/* ===========================================================================
   BODY — desktop warm-gray fabric (via image), mobile uses a different image.
   =========================================================================== */
.pp-body {
  background: transparent; /* the .pp-lower wrapper carries the body texture */
  flex: 1 0 auto; /* fill remaining height so the footer rests at the fold */
}

/* Wrapper that holds body + footer and carries ONE continuous background,
   so there's no seam/tint between them. The texture is a small tile that
   repeats seamlessly across the area at its native crisp resolution. */
.pp-lower {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  background-color: var(--warm-gray);
  background-repeat: repeat;     /* tile the small texture */
  background-size: auto;         /* show the image at its native size */
  background-position: top left;
}

.pp-discs {
  display: grid;
  grid-template-columns: var(--panel-w) 1fr; /* SAME as header */
}
.pp-discs-spacer { /* holds tagline below logo */ }

.pp-disc-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-3);
  padding: 0 var(--sp-5);
  margin-top: -32px; /* discs pulled up, overlapping the header */
  align-items: start;
  position: relative;
  z-index: 1; /* default: below the sticky header (tucks under on scroll) */
}
/* DESKTOP ONLY: discs sit ABOVE the header where they overlap at rest. */
@media (min-width: 821px) {
  .pp-disc-row { z-index: 200; }
}

/* ---- Each sub-brand item (now a container, not the link) --------------- */
.pp-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--sp-1) var(--sp-1) var(--sp-2);
  min-width: 0; /* allow grid item to shrink so discs never overflow */
}

/* The disc link wraps the brand name + disc (this is the navigation link) */
.pp-disc-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-decoration: none;
  border-radius: 16px;
  cursor: pointer;
  outline: none;
  width: 100%;
}

/* The disc wrapper. On desktop the disc IS the image (white disc baked in). */
.pp-disc {
  position: relative;
  width: 100%;
  max-width: 190px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 320ms var(--ease);
}
/* Shadow applies ONLY to the base disc image, not the overlay FX elements.
   (If the shadow was on the container, every overlay would throw its own
   shadow of its full canvas — including its transparent areas — producing
   phantom oval shadows.) */
.pp-disc .disc-desktop,
.pp-disc .disc-mobile {
  filter: var(--disc-shadow);
  transition: filter 320ms var(--ease);
}
/* Subtle gradient overlay suggesting the white oval has dimension.
   Sits IN FRONT of the disc image with mix-blend-mode so it interacts
   with the artwork without obscuring the disc art.
   NOTE: both radial gradients now fade to fully transparent WELL within
   the element's box (highlight done by 55%, shadow by 45%) so the element's
   own elliptical edge never reads as a hard "seam" line across the disc. */
.pp-disc::after {
  content: "";
  position: absolute;
  left: 10%;
  right: 10%;
  bottom: 7%;
  height: 34%;
  pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 35%,
                    rgba(255,255,255,0.45) 0%,
                    rgba(255,255,255,0.10) 35%,
                    rgba(255,255,255,0)    55%),
    radial-gradient(ellipse at 50% 90%,
                    rgba(20,25,40,0.14)    0%,
                    rgba(0,0,0,0)          45%);
  mix-blend-mode: soft-light;
  border-radius: 50%;
  z-index: 3;     /* sit above gears so the sheen reads on top, but it's
                     fully transparent at its edges so it adds no seam */
}
.pp-disc .disc-desktop,
.pp-disc .disc-mobile {
  width: 100%;
  height: auto;
  display: block;
  position: relative;
  z-index: 1;
}
/* Overlay FX must stay absolutely positioned over the base disc image,
   not flow in flex layout alongside it. All disc PNGs (base + every gear/
   overlay) share IDENTICAL canvas dimensions, so a plain width:100% overlay
   at top:0/left:0 lines up 1:1 with the base disc automatically. */
.pp-disc .pp-fx {
  position: absolute !important;
  top: 0;
  left: 0;
  width: 100%;
  height: auto;
}
/* Hide the mobile disc image on desktop (only one shows at a time) */
.pp-disc .disc-mobile { display: none; }

/* Category label below the disc */
.pp-label {
  position: relative;
  margin-top: var(--sp-2);
  font-family: 'Merriweather', Georgia, serif;
  color: #f1efe9;
  opacity: .92;
  transition: opacity 280ms var(--ease);
  /* Reserve room so the row doesn't jump when the description appears */
  min-height: 2.8em;
  width: 100%;
  max-width: 26ch;
  margin-left: auto;
  margin-right: auto;
  /* Center the trigger (short word + icon) under the disc */
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* The trigger button (short word + info icon). The WORD is centered under
   the disc; the info icon is positioned to its right so it does NOT shift
   the word off-center. */
.pp-label-trigger {
  position: relative;
  display: inline-block;        /* shrink-wrap the word; centered by parent */
  background: none;
  border: none;
  padding: 2px 4px;
  margin: 0 auto;
  cursor: pointer;
  color: inherit;
  font-family: inherit;
  border-radius: 8px;
  outline: none;
  transition: opacity 260ms var(--ease);
}
.pp-label-trigger .label-short {
  font-weight: 700;
  font-size: clamp(12px, 1vw, 15px);
  letter-spacing: 2px;
  text-transform: uppercase;
}
.pp-info-icon {
  position: absolute;
  left: 100%;                   /* hang off the right edge of the word */
  top: 50%;
  transform: translateY(-50%);
  margin-left: 3px;
  font-size: 0.95em;
  line-height: 1;
  opacity: .65;
  transition: opacity 200ms var(--ease);
}
.pp-label-trigger:hover .pp-info-icon,
.pp-label-trigger:focus-visible .pp-info-icon { opacity: 1; }
.pp-label-trigger:focus-visible {
  box-shadow: 0 0 0 2px rgba(255,255,255,.9);
}

/* Long description — a white box (both desktop & mobile), shown on hover
   (desktop) or when .is-open (tap/click). Positioned below the trigger. */
.pp-label .label-long {
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: max-content;
  max-width: min(260px, 80vw);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(12px, 0.95vw, 14px);
  letter-spacing: .2px;
  text-transform: none;
  line-height: 1.4;
  color: var(--ink);
  background: rgba(255,255,255,0.96);
  border-radius: 8px;
  padding: 10px 12px;
  box-shadow: 0 6px 18px rgba(20,25,35,0.22);
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms var(--ease), transform 260ms var(--ease);
  z-index: 6;
}

/* Tap/click-open state (works on any device, driven by JS) */
.pp-label.is-open .label-long {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  transition-delay: 0ms;
}
.pp-label.is-open .pp-label-trigger { opacity: 0; }

/* ---- Hover: MOUSE-ONLY. Disc lifts FIRST, text/box appears slightly after.
   Both happen on hovering ANY part of the item (disc OR label). ----------- */
@media (hover: hover) {
  /* Disc lift — fires immediately on hovering the whole item.
     Lift goes on the container; shadow goes only on the base disc images
     (so overlay FX don't cast extra phantom shadows). */
  .pp-item:hover .pp-disc {
    transform: translateY(-8px) scale(1.015);
    transition-delay: 0ms;
  }
  .pp-item:hover .pp-disc .disc-desktop,
  .pp-item:hover .pp-disc .disc-mobile {
    filter: var(--disc-shadow-hover);
  }
  .pp-disc-link:focus-visible .pp-disc {
    transform: translateY(-8px) scale(1.015);
  }
  .pp-disc-link:focus-visible .pp-disc .disc-desktop,
  .pp-disc-link:focus-visible .pp-disc .disc-mobile {
    filter: var(--disc-shadow-hover);
  }
  /* Description box — appears slightly AFTER the disc lifts */
  .pp-item:hover .pp-label .label-long {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
    transition-delay: 160ms;
  }
  /* Hide the trigger word while the box is shown */
  .pp-item:hover .pp-label-trigger {
    opacity: 0;
    transition-delay: 160ms;
  }
}

/* Keyboard focus ring on the disc link (all devices) */
.pp-disc-link:focus-visible {
  box-shadow: 0 0 0 3px rgba(255,255,255,.85), 0 0 0 6px var(--forest);
  border-radius: 16px;
}

/* ===========================================================================
   TAGLINE  — wordmark is baked into the logo PNG, so only tagline is HTML.
   =========================================================================== */
.pp-identity {
  text-align: center;
  margin-top: calc(var(--logo-overhang) + 50px);
  padding: 0 var(--sp-4) var(--sp-4);
  color: var(--white);
}
.pp-tagline {
  margin: 0;
  font-family: 'Merriweather', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: clamp(15px, 1.4vw, 19px);
  line-height: 1.45;
  color: rgba(255,255,255,.95);
}

/* ===========================================================================
   OPENING ANIMATION
   =========================================================================== */
.pp-anim { opacity: 0; }
.anim-panel { transition: opacity 900ms var(--ease); }
.anim-logo  { transform: translateX(-50%) scale(.86); transition: opacity 400ms var(--ease), transform 400ms var(--ease), filter 400ms var(--ease); }
.anim-disc    { transform: translateY(40px); transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease); }
.anim-name    { transform: translateY(-8px); transition: opacity 520ms var(--ease), transform 520ms var(--ease); }
.anim-label   { transform: translateY(6px); transition: opacity 520ms var(--ease), transform 520ms var(--ease); }
.anim-identity{ transform: translateY(14px); transition: opacity 800ms var(--ease), transform 800ms var(--ease); }

.is-in.anim-panel   { opacity: 1; }
.is-in.anim-logo    { opacity: 1; transform: translateX(-50%) scale(1); }
.is-in.anim-disc    { opacity: 1; transform: translateY(0); }
.is-in.anim-name    { opacity: 1; transform: translateY(0); }
.is-in.anim-label   { opacity: 1; transform: translateY(0); }
.is-in.anim-identity{ opacity: 1; transform: translateY(0); }

.col-1 .anim-disc { transition-delay: 250ms; }
.col-2 .anim-disc { transition-delay: 400ms; }
.col-3 .anim-disc { transition-delay: 550ms; }
.col-4 .anim-disc { transition-delay: 700ms; }
.col-1 .anim-name { transition-delay: 560ms; }
.col-2 .anim-name { transition-delay: 710ms; }
.col-3 .anim-name { transition-delay: 860ms; }
.col-4 .anim-name { transition-delay: 1010ms; }
.col-1 .anim-label { transition-delay: 680ms; }
.col-2 .anim-label { transition-delay: 830ms; }
.col-3 .anim-label { transition-delay: 980ms; }
.col-4 .anim-label { transition-delay: 1130ms; }
.anim-logo     { transition-delay: 0ms; }
.anim-identity { transition-delay: 900ms; }

@media (prefers-reduced-motion: reduce) {
  .pp-anim, .pp-anim.is-in { opacity: 1 !important; transform: none !important; transition: none !important; }
  .anim-logo, .anim-logo.is-in { transform: translateX(-50%) !important; }
  .pp-northstar, .pp-stars::before, .pp-stars::after { animation: none !important; }
}

/* ===========================================================================
   MOBILE  (<= 820px): full-width navy header, light body, 2x2 discs.
   - Navy panel spans the FULL width (not a left column).
   - The white desktop top strip is hidden.
   - Logo swaps to the mobile version (blue text on light bg context).
   - Body uses the LIGHT mobile background image.
   - Discs swap to the dark "purple disc" mobile artwork.
   =========================================================================== */
@media (max-width: 820px) {

  /* The header is now a SINGLE column (no left/right split) */
  .pp-header { grid-template-columns: 1fr; }

  /* Hide the white top strip — brand names move down onto the cards */
  .pp-topbar { display: none; }

  /* Navy panel: full width, shorter */
  .pp-panel {
    height: 140px;
    min-height: 140px;
    background-position: center;
  }
  /* Mobile background image is set inline in template; override here */
  .pp-northstar {
    right: 34%;
    top: 24px;
    width: 44px; height: 44px;
  }

  /* Logo: swap to mobile star + wordmark variants, larger, centered */
  .pp-logo {
    width: 230px;
    bottom: -120px;
  }
  .pp-header.is-compact .pp-logo { width: 190px; bottom: -98px; }
  .pp-logo .logo-star-desktop,
  .pp-logo .logo-wordmark-desktop { display: none; }
  .pp-logo .logo-star-mobile,
  .pp-logo .logo-wordmark-mobile  { display: block; }

  /* When scrolled (header is-compact), swap the two stacked mobile images
     for a single combined scroll image. */
  .pp-header.is-compact .pp-logo .logo-star-mobile,
  .pp-header.is-compact .pp-logo .logo-wordmark-mobile { display: none; }
  .pp-header.is-compact .pp-logo .logo-mobile-scroll   { display: block; }

  /* Body background swaps to the LIGHT mobile image (set inline on .pp-lower) */
  .pp-lower {
    background-color: #f1eee9;
  }

  /* Layout collapses to single column; spacer holds tagline ABOVE the cards */
  .pp-discs { grid-template-columns: 1fr; }
  .pp-discs-spacer { display: block; }

  .pp-identity {
    margin-top: calc(var(--logo-overhang) + 64px); /* clearance + one line drop */
    padding: 0 var(--sp-4) var(--sp-3);
  }
  /* Tagline ink color flips to dark for the light mobile background */
  .pp-tagline { color: var(--ink); }

  /* 2x2 grid of cards */
  .pp-disc-row {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--sp-4) var(--sp-3);
    margin-top: var(--sp-4);
    padding: 0 var(--sp-3) var(--sp-4);
  }

  /* Brand name images live with each card on mobile, ABOVE the disc */
  .pp-item .pp-brandname {
    display: block;
    position: relative;
    z-index: 2;
    margin-bottom: -8px;
  }
  .pp-item .pp-brandname img {
    max-height: 56px;
  }

  /* Swap to the mobile (dark) disc image */
  .pp-disc .disc-desktop { display: none; }
  .pp-disc .disc-mobile  { display: block; }
  .pp-disc {
    width: clamp(150px, 42vw, 220px);
  }
  /* Slightly stronger shadow for the darker mobile discs on the light bg.
     Applied only to the base disc image to avoid phantom overlay shadows. */
  .pp-disc .disc-mobile {
    filter: drop-shadow(0 14px 16px rgba(30, 35, 45, 0.30))
            drop-shadow(0 3px 4px rgba(30, 35, 45, 0.18));
  }

  /* Label ink flips to dark for the light mobile background.
     The description box (base styles) appears on tap (.is-open). */
  .pp-label {
    color: var(--ink);
    opacity: 1;
    min-height: 2.4em;
  }
  .pp-label-trigger .label-short { font-weight: 700; }
}

/* On desktop only, hide the per-card brand image (it lives in the top strip) */
@media (min-width: 821px) {
  .pp-item .pp-brandname { display: none; }
  /* Move the label (and info icon) up a touch closer to the disc */
  .pp-label { margin-top: 4px; }
}

/* Single column on very narrow screens — keeps things readable */
@media (max-width: 460px) {
  .pp-disc-row { grid-template-columns: 1fr; }
}

/* ===========================================================================
   FOOTER — matches the body background; white text (desktop), blue (mobile).
   flex-shrink:0 keeps it from collapsing; it rests at the fold.
   =========================================================================== */
.pp-footer {
  flex: 0 0 auto;
  background: transparent; /* sits on the .pp-lower wrapper background */
  text-align: center;
  padding: var(--sp-3) var(--sp-4);
}
.pp-footer-text {
  margin: 0;
  font-family: 'Merriweather', Georgia, serif;
  font-size: 13px;
  line-height: 1.6;
  color: #ffffff;             /* white on desktop */
}
.pp-footer-text a {
  color: #ffffff;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.pp-footer-text a:hover { opacity: .85; }
.pp-footer-sep { margin: 0 8px; opacity: .6; }

@media (max-width: 820px) {
  .pp-footer-text,
  .pp-footer-text a {
    color: #2c4a63;            /* blue on mobile */
  }
}

/* ===========================================================================
   SEARCH — icon button in the LOWER-right of the white strip (in-header).
   Lives at header level (not inside topbar) so it survives on mobile.
   =========================================================================== */
.pp-header { position: sticky; } /* (already sticky) — also the anchor */

.pp-search-btn {
  position: absolute;
  bottom: 0;                     /* flush to bottom of header */
  right: 0;                      /* flush to right of header */
  width: 44px; height: 58px;     /* a bit larger than the art for an easier target */
  display: flex; align-items: center; justify-content: center;
  background: transparent !important;
  background-color: transparent !important;
  border: none !important;
  box-shadow: none;
  padding: 0;                    /* no internal padding around the image */
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  z-index: 300;                  /* ABOVE the disc-row (z-index:200) so the
                                    discs' transparent canvas can't steal clicks
                                    over the telescope */
}
/* Prevent the parent theme (GeneratePress) from shading the button on hover */
.pp-search-btn:hover,
.pp-search-btn:active,
.pp-search-btn:focus {
  background: transparent !important;
  background-color: transparent !important;
  box-shadow: none;
  opacity: 1;
  transform: none;
}
.pp-search-icon {
  width: 100%; height: 100%; object-fit: contain; display: block;
  /* Sharpen the downscaled image. Browsers default to a smoothing pass that
     can soften detailed PNGs at small sizes; these hints request crisper
     resampling across the major engines. */
  image-rendering: -webkit-optimize-contrast;
  image-rendering: crisp-edges;
}
/* show desktop icon by default, hide the mobile (white) variant */
.pp-search-icon-mobile { display: none; }
/* No hover effect on the search icon — keep it static (no scale/shade). */
.pp-search-btn:focus-visible {
  outline: none;
  border-radius: 8px;
  box-shadow: 0 0 0 3px rgba(47, 93, 79, 0.5);
}

/* ---- Modal ------------------------------------------------------------- */
.pp-search-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 18vh;
}
.pp-search-modal[hidden] { display: none; }

.pp-search-overlay {
  position: absolute; inset: 0;
  background: rgba(20, 28, 44, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  animation: ppFade 240ms var(--ease);
}
.pp-search-panel {
  position: relative;
  width: min(560px, 92vw);
  background: var(--paper);
  border-radius: 14px;
  padding: 28px 24px 24px;
  box-shadow: 0 24px 60px rgba(10, 15, 30, 0.4);
  animation: ppRise 280ms var(--ease);
}
@keyframes ppFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes ppRise {
  from { opacity: 0; transform: translateY(-14px); }
  to   { opacity: 1; transform: translateY(0); }
}

.pp-search-close {
  position: absolute;
  top: 8px; right: 12px;
  background: none; border: none;
  font-size: 28px; line-height: 1;
  color: var(--ink);
  opacity: .55;
  cursor: pointer;
  transition: opacity 200ms var(--ease);
}
.pp-search-close:hover { opacity: 1; }

.pp-search-label {
  display: block;
  font-family: 'Merriweather', Georgia, serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--ink);
  margin-bottom: 10px;
}
.pp-search-row { display: flex; gap: 8px; }
.pp-search-input {
  flex: 1 1 auto;
  font-family: 'Merriweather', Georgia, serif;
  font-size: 16px;
  padding: 12px 14px;
  border: 1.5px solid #cfcabf;
  border-radius: 8px;
  background: #fff;
  color: var(--ink);
  outline: none;
  transition: border-color 200ms var(--ease), box-shadow 200ms var(--ease);
}
.pp-search-input:focus {
  border-color: var(--forest);
  box-shadow: 0 0 0 3px rgba(47, 93, 79, 0.15);
}
.pp-search-submit {
  flex: 0 0 auto;
  font-family: 'Merriweather', Georgia, serif;
  font-size: 15px;
  font-weight: 700;
  padding: 12px 20px;
  background: var(--forest);
  color: #fff;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background 200ms var(--ease);
}
.pp-search-submit:hover { background: var(--forest-deep); }

/* Mobile: telescope sits in the LOWER-RIGHT of the navy panel.
   White icon variant on navy. */
@media (max-width: 820px) {
  .pp-search-btn {
    top: auto;
    bottom: 0;                   /* flush to bottom of navy header */
    right: 0;                    /* flush to right edge */
    width: 38px; height: 54px;   /* matches telescope image aspect */
    padding: 0;
  }
  /* swap to the white icon variant on the navy panel */
  .pp-search-icon-desktop { display: none; }
  .pp-search-icon-mobile  { display: block; }
  .pp-search-modal { padding-top: 12vh; }
}

/* ===========================================================================
   SHOOTING STAR CURSOR (desktop / fine pointer only).
   A four-pointed star with a soft trailing tail, drawn as inline SVG so it
   needs no asset file. Touch devices don't show cursors, so this naturally
   only affects mouse users. Hotspot is at the star's center (16, 16 of 32).
   =========================================================================== */
@media (hover: hover) and (pointer: fine) {
  body.polaris-folio-page,
  .polaris-folio-page * {
    cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'><defs><linearGradient id='t' x1='100%25' y1='100%25' x2='0%25' y2='0%25'><stop offset='0%25' stop-color='%23ffffff' stop-opacity='0'/><stop offset='65%25' stop-color='%23ffffff' stop-opacity='0.55'/><stop offset='100%25' stop-color='%23ffffff' stop-opacity='0.95'/></linearGradient></defs><path d='M30 30 Q24 22 22 19 Q20 17 17 16' fill='none' stroke='url(%23t)' stroke-width='1.8' stroke-linecap='round'/><path d='M16 4 L18 14 L28 16 L18 18 L16 28 L14 18 L4 16 L14 14 Z' fill='%23ffffff' stroke='%232c4a63' stroke-width='0.5'/></svg>") 16 16, auto;
  }
  /* Pointer-style cursor for clickable items — golden curved-tail comet */
  .polaris-folio-page a,
  .polaris-folio-page button,
  .polaris-folio-page .pp-disc-link,
  .polaris-folio-page .pp-label-trigger {
    cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 36 36'><defs><linearGradient id='t2' x1='100%25' y1='100%25' x2='0%25' y2='0%25'><stop offset='0%25' stop-color='%23ffd86e' stop-opacity='0'/><stop offset='60%25' stop-color='%23ffd86e' stop-opacity='0.6'/><stop offset='100%25' stop-color='%23ffd86e' stop-opacity='0.95'/></linearGradient></defs><path d='M34 34 Q27 25 24 22 Q22 20 19 19' fill='none' stroke='url(%23t2)' stroke-width='2.2' stroke-linecap='round'/><path d='M18 2 L21 15 L34 18 L21 21 L18 34 L15 21 L2 18 L15 15 Z' fill='%23fff4c4' stroke='%23b88a1a' stroke-width='0.6'/></svg>") 18 18, pointer;
  }
}

/* ===========================================================================
   SHOOTING STAR ON LOAD — fires once when the page opens. Arcs diagonally
   across the navy panel from upper-left to lower-right, then disappears.
   No loop. Pure CSS.
   =========================================================================== */
.pp-shootingstar {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  overflow: hidden;
  z-index: 2;
}
/* One combined comet: a long thin gradient bar with a bright head at its
   right end. The whole thing translates diagonally across the panel. */
.pp-shootingstar-head {
  position: absolute;
  /* Start off-stage upper-left; end off-stage lower-right.
     Percentages here ARE relative to the parent (.pp-shootingstar),
     which fills the navy panel — so this travels the full width. */
  top: -12%;
  left: -20%;
  width: 90px;
  height: 2px;
  opacity: 0;
  /* The visible comet: a tapered tail behind a bright head */
  background: linear-gradient(to right,
                              rgba(255,255,255,0)    0%,
                              rgba(255,255,255,0.25) 50%,
                              rgba(255,255,255,0.85) 88%,
                              rgba(255,255,255,1)    100%);
  border-radius: 2px;
  /* Angle of travel (~28deg downward) baked into rotation */
  transform: rotate(28deg);
  transform-origin: center center;
  box-shadow: 0 0 6px 1px rgba(255,255,255,0.5),
              0 0 14px 2px rgba(200,220,255,0.25);
  animation: ppShootStar 1.6s cubic-bezier(.25,.7,.6,1) 600ms 1 forwards;
}
/* Hide the now-unused separate tail element */
.pp-shootingstar-tail { display: none; }

@keyframes ppShootStar {
  0%   { opacity: 0;   top: -12%;  left: -20%; }
  10%  { opacity: 0.9; }
  85%  { opacity: 0.9; }
  100% { opacity: 0;   top: 95%;   left: 110%; }
}

/* ---------------------------------------------------------------------------
   GLOBAL FX KEYFRAMES
   These are defined at top level (not inside a media query) so BOTH the
   desktop hover block and the mobile auto-run block can use them. Keyframes
   declared inside an @media are scoped to that query and unavailable outside
   it — hence these canonical global copies.
   --------------------------------------------------------------------------- */
@keyframes ppLeaf1 {
  0%   { opacity: 1; transform: translate(0, 0)         rotate(0deg)   scale(1); }
  12%  { opacity: 1; transform: translate(-3%, -1%)     rotate(-6deg)  scale(1.7); }
  40%  { opacity: 1; transform: translate(-10%, -2%)    rotate(-18deg) scale(1.8); }
  70%  { opacity: 1; transform: translate(-19%, 4%)     rotate(-38deg) scale(1.9); }
  88%  { opacity: 0.85; transform: translate(-23%, 15%) rotate(-58deg) scale(1.95); }
  100% { opacity: 0; transform: translate(-26%, 23%)    rotate(-75deg) scale(2); }
}
@keyframes ppLeaf2 {
  0%   { opacity: 1; transform: translate(0, 0)         rotate(0deg)   scale(1); }
  12%  { opacity: 1; transform: translate(-6%, -2%)     rotate(12deg)  scale(1.7); }
  40%  { opacity: 1; transform: translate(-22%, -3%)    rotate(45deg)  scale(1.82); }
  70%  { opacity: 1; transform: translate(-48%, -3%)    rotate(90deg)  scale(1.92); }
  88%  { opacity: 0.85; transform: translate(-68%, -6%) rotate(130deg) scale(1.98); }
  100% { opacity: 0; transform: translate(-86%, -10%)   rotate(160deg) scale(2.05); }
}
@keyframes ppLeaf3 {
  0%   { opacity: 1; transform: translate(0, 0)         rotate(0deg)   scale(1); }
  12%  { opacity: 1; transform: translate(-5%, -2%)     rotate(-10deg) scale(1.7); }
  35%  { opacity: 1; transform: translate(-20%, -7%)    rotate(-32deg) scale(1.8); }
  55%  { opacity: 1; transform: translate(-34%, 1%)     rotate(-58deg) scale(1.88); }
  72%  { opacity: 1; transform: translate(-48%, -9%)    rotate(-88deg) scale(1.94); }
  88%  { opacity: 0.85; transform: translate(-61%, -4%) rotate(-120deg) scale(2); }
  100% { opacity: 0; transform: translate(-76%, -8%)    rotate(-150deg) scale(2.05); }
}
@keyframes ppBlink {
  0%   { opacity: 0; }
  15%  { opacity: 0; }
  20%  { opacity: 1; }
  28%  { opacity: 1; }
  33%  { opacity: 0; }
  55%  { opacity: 0; }
  60%  { opacity: 1; }
  65%  { opacity: 1; }
  70%  { opacity: 0; }
  100% { opacity: 0; }
}
@keyframes ppGearCW  { to { transform: rotate(360deg); } }
@keyframes ppGearCCW { to { transform: rotate(-360deg); } }
@keyframes ppSparkle {
  0%, 100% { opacity: 0; transform: scale(0.3) rotate(0deg); }
  40%      { opacity: 1; transform: scale(1) rotate(30deg); }
  60%      { opacity: 1; transform: scale(1.15) rotate(60deg); }
}

/* ---------------------------------------------------------------------------
   GLOBAL SPARKLE STYLES (visual base + positions)
   Defined globally so the mobile auto-run block can use them too. The desktop
   hover block also declares these (identical values) — harmless duplication.
   Only the ANIMATION trigger differs between desktop (hover) and mobile (auto).
   --------------------------------------------------------------------------- */
.pp-sparkle {
  position: absolute;
  width: 6px; height: 6px;       /* small, crisp star */
  margin: -3px 0 0 -3px;         /* center on the top/left point */
  opacity: 0;
  transform-origin: center center;
  /* Star with a warm-gold body + white center, so it pops on BOTH the green
     and tan lobes. Two-stop radial keeps the core bright and defined. */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><defs><radialGradient id='g' cx='50%25' cy='50%25' r='50%25'><stop offset='0%25' stop-color='%23ffffff'/><stop offset='55%25' stop-color='%23fff3c0'/><stop offset='100%25' stop-color='%23ffcf3f'/></radialGradient></defs><path d='M12 0 L13.7 10.3 L24 12 L13.7 13.7 L12 24 L10.3 13.7 L0 12 L10.3 10.3 Z' fill='url(%23g)'/></svg>");
  background-size: contain;
  background-repeat: no-repeat;
  /* Tight, bright glow only — no wide diffuse halo. */
  filter: drop-shadow(0 0 1.5px rgba(255,255,255,0.95))
          drop-shadow(0 0 4px rgba(255,200,60,0.9));
  pointer-events: none;
}
/* 6 sparkle positions measured against disc-desktop-variegated.png,
   3 per lobe, spread top/mid/lower (avoiding the stem). */
.pp-sparkle-1 { top: 16.9%; left: 44.8%; }
.pp-sparkle-2 { top: 16.9%; left: 54.1%; }
.pp-sparkle-3 { top: 29.1%; left: 41.3%; }
.pp-sparkle-4 { top: 30.0%; left: 58.7%; }
.pp-sparkle-5 { top: 40.4%; left: 46.5%; }
.pp-sparkle-6 { top: 40.4%; left: 53.5%; }

/* Respect reduced-motion preferences */
@media (prefers-reduced-motion: reduce) {
  .pp-shootingstar { display: none; }
}

/* ===========================================================================
   DISC CLICK CUE — when a disc is clicked, briefly dim everything else
   (~200ms) before the navigation fires. The clicked disc stays bright.
   =========================================================================== */
body.pp-dimming .pp-header,
body.pp-dimming .pp-footer,
body.pp-dimming .pp-identity,
body.pp-dimming .pp-item:not(.is-chosen) {
  opacity: 0.32;
  transition: opacity 220ms var(--ease);
}
body.pp-dimming .pp-item.is-chosen {
  transition: transform 220ms var(--ease);
  transform: scale(1.04);
}
@media (prefers-reduced-motion: reduce) {
  body.pp-dimming .pp-header,
  body.pp-dimming .pp-footer,
  body.pp-dimming .pp-identity,
  body.pp-dimming .pp-item:not(.is-chosen),
  body.pp-dimming .pp-item.is-chosen {
    transition: none;
    transform: none;
  }
}

/* ===========================================================================
   DISC HOVER MICRO-ANIMATIONS — desktop-only (mouse hover).
   Each disc has overlay element(s) that play a personality-specific
   animation when the user hovers the card.
   =========================================================================== */

/* Shared: most FX overlays sit ON TOP of the disc image, full-canvas,
   hidden by default. The gears are an exception — they're part of the
   artwork (always visible), they just spin on hover. */
.pp-fx {
  position: absolute;
  pointer-events: none;
  opacity: 0;
}
.pp-fx-gear,
.pp-fx-sparkles {
  opacity: 1;   /* always visible at rest; animations control sparkle visibility */
}
/* Gear box + default pivot, defined globally (NOT inside @media hover) so the
   gears are guaranteed visible on every device, hover-capable or not. */
.pp-fx-gear {
  top: 0; left: 0;
  width: 100%; height: auto;   /* each gear is canvas-sized, overlays the disc 1:1 */
  transform-origin: center center;
}
/* Sparkle container must span the full disc box so each sparkle's top/left %
   resolves against the whole disc. NOTE: the global `.pp-disc .pp-fx` rule sets
   height:auto (2-class specificity), which collapses this <span> to 0 height and
   piles every sparkle at the top. So this rule is scoped to .pp-disc to win the
   specificity battle and force full height. */
.pp-disc .pp-fx-sparkles {
  top: 0; left: 0;
  width: 100%; height: 100%;
}

@media (hover: hover) {
  /* ---- SAPWOOD: three leaves blowing away (each with its own path) -- */
  /* Each leaf PNG is the SAME canvas as the disc — those leaves are
     REMOVED from the base disc art, so the overlays show them at rest
     and animate them away on hover. */
  .pp-fx-leaf {
    top: 0; left: 0;
    width: 100%; height: auto;
    transform-origin: center center;
    opacity: 1;  /* visible at rest (leaves are part of the artwork) */
  }
  /* LEAF 1 (yellow): short trip, gentle drop. Pops to a larger size right
     as it lifts off (quick scale-up in the first 12%), then drifts away. */
  .col-1:hover .pp-fx-leaf-1 {
    animation: ppLeaf1 3000ms cubic-bezier(.4,.05,.6,1) 0ms forwards;
  }
  @keyframes ppLeaf1 {
    0%   { opacity: 1; transform: translate(0, 0)         rotate(0deg)   scale(1); }
    12%  { opacity: 1; transform: translate(-3%, -1%)     rotate(-6deg)  scale(1.7); }
    40%  { opacity: 1; transform: translate(-10%, -2%)    rotate(-18deg) scale(1.8); }
    70%  { opacity: 1; transform: translate(-19%, 4%)     rotate(-38deg) scale(1.9); }
    88%  { opacity: 0.85; transform: translate(-23%, 15%) rotate(-58deg) scale(1.95); }
    100% { opacity: 0; transform: translate(-26%, 23%)    rotate(-75deg) scale(2); }
  }
  /* LEAF 2 (middle): directly left, further, out of frame. */
  .col-1:hover .pp-fx-leaf-2 {
    animation: ppLeaf2 3600ms cubic-bezier(.35,.1,.45,1) 250ms forwards;
  }
  @keyframes ppLeaf2 {
    0%   { opacity: 1; transform: translate(0, 0)         rotate(0deg)   scale(1); }
    12%  { opacity: 1; transform: translate(-6%, -2%)     rotate(12deg)  scale(1.7); }
    40%  { opacity: 1; transform: translate(-22%, -3%)    rotate(45deg)  scale(1.82); }
    70%  { opacity: 1; transform: translate(-48%, -3%)    rotate(90deg)  scale(1.92); }
    88%  { opacity: 0.85; transform: translate(-68%, -6%) rotate(130deg) scale(1.98); }
    100% { opacity: 0; transform: translate(-86%, -10%)   rotate(160deg) scale(2.05); }
  }
  /* LEAF 3 (right): drifts up/down with the wind. */
  .col-1:hover .pp-fx-leaf-3 {
    animation: ppLeaf3 4200ms cubic-bezier(.35,.05,.6,.9) 500ms forwards;
  }
  @keyframes ppLeaf3 {
    0%   { opacity: 1; transform: translate(0, 0)         rotate(0deg)   scale(1); }
    12%  { opacity: 1; transform: translate(-5%, -2%)     rotate(-10deg) scale(1.7); }
    35%  { opacity: 1; transform: translate(-20%, -7%)    rotate(-32deg) scale(1.8); }
    55%  { opacity: 1; transform: translate(-34%, 1%)     rotate(-58deg) scale(1.88); }
    72%  { opacity: 1; transform: translate(-48%, -9%)    rotate(-88deg) scale(1.94); }
    88%  { opacity: 0.85; transform: translate(-61%, -4%) rotate(-120deg) scale(2); }
    100% { opacity: 0; transform: translate(-76%, -8%)    rotate(-150deg) scale(2.05); }
  }

  /* ---- CURATED: frog blink ----------------------------------------- */
  .pp-fx-blink {
    top: 0; left: 0;
    width: 100%; height: auto;  /* same canvas as the disc, overlays 1:1 */
    z-index: 2;                 /* must sit ON TOP of the base disc (z-index:1) */
  }
  .col-3:hover .pp-fx-blink {
    animation: ppBlink 1600ms ease-in-out forwards;
  }
  @keyframes ppBlink {
    0%   { opacity: 0; }
    15%  { opacity: 0; }       /* delay before first blink */
    20%  { opacity: 1; }       /* eyes close */
    28%  { opacity: 1; }
    33%  { opacity: 0; }       /* open */
    55%  { opacity: 0; }
    60%  { opacity: 1; }       /* second blink */
    65%  { opacity: 1; }
    70%  { opacity: 0; }
    100% { opacity: 0; }
  }

  /* ---- SIMPLER: three gears turning -------------------------------- */
  /* (Gear box + visibility are defined at global scope so the gears show
     regardless of hover capability. Here we keep only the per-gear origins
     and the hover spin triggers.) */
  /* IMPORTANT: each gear must rotate around ITS OWN drawn center, not the
     disc center. Because every gear PNG is the full disc canvas, the origin
     is the (X%, Y%) point inside that canvas where the gear's hub sits.
     If a gear visibly ORBITS (swings around) instead of spinning in place,
     its origin is wrong — nudge the two percentages until it pivots cleanly.
     0% 0% = top-left of the disc, 50% 50% = disc center, 100% 100% = bottom-right. */
  .pp-fx-gear-top   { transform-origin: 50.1% 32.8%; }  /* exact hub from PNG file */
  .pp-fx-gear-right { transform-origin: 62.0% 64.3%; }  /* exact hub from PNG file */
  .pp-fx-gear-green { transform-origin: 39.6% 65.1%; }  /* exact hub from PNG file */
  /* Gears spin only on hover, in opposite directions (like real meshing gears).
     Slowed ~2x so the motion reads as deliberate machinery, not a blur. */
  .col-4:hover .pp-fx-gear-top   { animation: ppGearCW  5600ms linear infinite; }
  .col-4:hover .pp-fx-gear-right { animation: ppGearCW  4800ms linear infinite; }
  .col-4:hover .pp-fx-gear-green { animation: ppGearCCW 4400ms linear infinite; }
  @keyframes ppGearCW  { to { transform: rotate(360deg); } }
  @keyframes ppGearCCW { to { transform: rotate(-360deg); } }

  /* ---- VARIEGATED: scattered sparkles ------------------------------ */
  /* (Visual base + positions are defined once at global scope so mobile can
     share them. Here we only add the hover TRIGGER + staggered delays.) */
  .col-2:hover .pp-sparkle { animation: ppSparkle 1400ms ease-in-out infinite; }
  .col-2:hover .pp-sparkle-1  { animation-delay:    0ms; }
  .col-2:hover .pp-sparkle-2  { animation-delay:  120ms; }
  .col-2:hover .pp-sparkle-3  { animation-delay:  240ms; }
  .col-2:hover .pp-sparkle-4  { animation-delay:  360ms; }
  .col-2:hover .pp-sparkle-5  { animation-delay:  480ms; }
  .col-2:hover .pp-sparkle-6  { animation-delay:  600ms; }
}

/* Reduced-motion users get static state (no animations) */
@media (prefers-reduced-motion: reduce) {
  .col-1:hover .pp-fx-leaf,
  .col-3:hover .pp-fx-blink,
  .col-4:hover .pp-fx-gear-top,
  .col-4:hover .pp-fx-gear-right,
  .col-4:hover .pp-fx-gear-green,
  .col-2:hover .pp-sparkle { animation: none; }
}

/* The Simpler base disc and gears need stacking. Gears sit on top of the
   base in the order they were authored, all at z-index 1+. */
.pp-disc .pp-fx-gear { z-index: 2; }
/* The closed-eye frog overlay must also stack above the base disc. */
.pp-disc .pp-fx-blink { z-index: 2; }
/* Sparkles must sit IN FRONT of the brain art (base disc is z-index:1).
   Without this the sparkles render behind the brain and only their glow
   leaks around the edges. */
.pp-disc .pp-fx-sparkles { z-index: 4; }
.pp-disc .pp-fx-sparkles .pp-sparkle { z-index: 4; }

/* Desktop shows the desktop gear set; the mobile gear set is hidden.
   (Flipped inside the max-width:820px block below.) */
.pp-fx-gear-mobile { display: none; }
.pp-fx-gear-desktop { display: block; }
/* Frog blink: desktop overlay (aligned to the desktop curated disc) by default;
   the mobile overlay (aligned to the mobile curated disc) is hidden until the
   mobile breakpoint. They use different framing so each matches its own base. */
.pp-fx-blink-mobile  { display: none; }
.pp-fx-blink-desktop { display: block; }

/* ===========================================================================
   MOBILE AUTO-RUN ANIMATIONS (max-width: 820px)
   On touch devices there's no hover, so every disc's personality animation
   runs automatically and loops continuously. Desktop behavior (hover) is
   untouched — it lives in the @media (hover: hover) block above.
   =========================================================================== */
@media (max-width: 820px) {

  /* --- Gear set swap: hide desktop gears, show the mobile gear set --- */
  .pp-fx-gear-desktop { display: none; }
  .pp-fx-gear-mobile  { display: block; }

  /* --- Frog blink: hide the desktop overlay, show the mobile-framed one --- */
  .pp-fx-blink-desktop { display: none; }
  .pp-fx-blink-mobile  { display: block; }

  /* Mobile gear hubs — exact, read directly from the PNG files. */
  .pp-fx-gear-m-top   { transform-origin: 46.1% 29.5%; }
  .pp-fx-gear-m-left  { transform-origin: 33.1% 56.8%; }
  .pp-fx-gear-m-right { transform-origin: 61.6% 61.6%; }

  /* Auto-spin, continuous loop, opposite directions for a meshing feel. */
  .pp-fx-gear-m-top   { animation: ppGearCW  5600ms linear infinite; }
  .pp-fx-gear-m-left  { animation: ppGearCCW 4400ms linear infinite; }
  .pp-fx-gear-m-right { animation: ppGearCW  4800ms linear infinite; }

  /* --- Leaves (col-1): auto-loop the same flight paths.
     Visible at rest so they read as part of the artwork between flights. --- */
  .col-1 .pp-fx-leaf   { opacity: 1; }
  .col-1 .pp-fx-leaf-1 { animation: ppLeaf1 3000ms cubic-bezier(.4,.05,.6,1)  0ms    infinite; }
  .col-1 .pp-fx-leaf-2 { animation: ppLeaf2 3600ms cubic-bezier(.35,.1,.45,1) 250ms  infinite; }
  .col-1 .pp-fx-leaf-3 { animation: ppLeaf3 4200ms cubic-bezier(.35,.05,.6,.9) 500ms infinite; }

  /* --- Frog blink (col-3): auto-loop. Linear so each opacity stop is honored
     (the keyframe itself defines the sharp on/off of the eyelids). --- */
  .col-3 .pp-fx-blink-mobile { animation: ppBlink 4200ms linear 600ms infinite; }

  /* --- Sparkles (col-2): auto-loop, staggered across all 16 --- */
  /* Mobile brain sits slightly lower; positions measured against
     disc-mobile-variegated.png (override the desktop set). */
  .pp-sparkle-1 { top: 19.5%; left: 45.0%; }
  .pp-sparkle-2 { top: 19.5%; left: 53.8%; }
  .pp-sparkle-3 { top: 31.1%; left: 41.8%; }
  .pp-sparkle-4 { top: 32.0%; left: 58.2%; }
  .pp-sparkle-5 { top: 41.8%; left: 46.7%; }
  .pp-sparkle-6 { top: 41.8%; left: 53.3%; }
  .col-2 .pp-sparkle { animation: ppSparkle 2600ms ease-in-out infinite; }
  .col-2 .pp-sparkle-1  { animation-delay:    0ms; }
  .col-2 .pp-sparkle-2  { animation-delay:  160ms; }
  .col-2 .pp-sparkle-3  { animation-delay:  320ms; }
  .col-2 .pp-sparkle-4  { animation-delay:  480ms; }
  .col-2 .pp-sparkle-5  { animation-delay:  640ms; }
  .col-2 .pp-sparkle-6  { animation-delay:  800ms; }

  /* Reduced-motion on mobile: hold everything static. */
  @media (prefers-reduced-motion: reduce) {
    .pp-fx-gear-mobile,
    .col-1 .pp-fx-leaf,
    .col-3 .pp-fx-blink,
    .col-2 .pp-sparkle { animation: none; }
  }
}

/* ===========================================================================
   FOOTER "Need a site?" CTA — same styling as other footer links
   =========================================================================== */
.pp-cta-link {
  /* Inherits color/decoration from .pp-footer-text a — nothing extra needed */
}
