/* Motion tokens + shared physics. Behaviour: assets/js/animations.js */

:root {
  --dur-reveal: 700ms;
  --dur-hover: 250ms;
  --dur-photo: 800ms;
  --dur-arch: 900ms;
  --dur-stagger: 90ms;
  --dur-count: 1400ms;
  --dur-nav: 500ms;
  --dur-icon: 340ms;
  --dur-ic: 320ms;
  --dur-zoom: 700ms;
  --dur-dec: 1200ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-hover: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-soft: cubic-bezier(0.2, 0.7, 0.2, 1);
  --ease-draw: cubic-bezier(0.25, 0.7, 0.2, 1);
  --reveal-y: 24px;
  --reveal-y-text: 16px;
  --reveal-y-hero: 18px;
  --reveal-scale-card: 0.98;
  --reveal-scale-photo: 1.04;
}

@keyframes pk-appear-up {
  from { opacity: 0; transform: translateY(var(--reveal-y-hero)); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes pk-arch-in {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes pk-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes pk-breathe {
  /* opacity only — transform reserved for scroll parallax */
  0%, 100% { opacity: 0.82; }
  50%      { opacity: 1; }
}

@keyframes pk-soft-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}

@keyframes pk-portrait-drift {
  0%, 100% { transform: scale(1.01) translate3d(0, 0, 0); }
  50%      { transform: scale(1.035) translate3d(0, -1.2%, 0); }
}

@keyframes pk-hdr-in {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}

@keyframes pk-veil-out {
  from { opacity: 1; }
  to   { opacity: 0; visibility: hidden; }
}

@keyframes pk-chip-in {
  from { opacity: 0; transform: translateY(10px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}

/* Soft boot veil — calm cream fade, not a splash screen */
.pk-boot-veil {
  position: fixed;
  inset: 0;
  z-index: 2000;
  pointer-events: none;
  background:
    radial-gradient(circle at 50% 18%, rgba(255, 255, 255, 0.55), transparent 42%),
    #F8F2EE;
  opacity: 0;
}

html.pk-booting .pk-boot-veil {
  opacity: 1;
  animation: pk-veil-out 720ms var(--ease-out) 180ms forwards;
}

html.pk-hero-prep .pk-hdrbar {
  opacity: 0;
  animation: pk-hdr-in 700ms var(--ease-out) 40ms forwards;
}

/* ——— Solid navbar: never glass. The bar itself only appears once scrolled,
   as in the import; what changes is that it is opaque instead of blurred. ——— */
.pk-hdrbar,
.pk-hdrbar.is-stuck {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.pk-hdrbar {
  background: transparent;
  border-bottom: 1px solid transparent;
  box-shadow: none;
}

.pk-hdrbar.is-stuck {
  background: var(--bg, #F8F2EE);
  border-bottom-color: rgba(226, 210, 197, 0.75);
  box-shadow: 0 8px 26px rgba(90, 55, 38, 0.07);
}

.pk-nav {
  overflow: visible;
}

/* Colour applies to the drawer links too, exactly as in the import; only the
   grow-underline is desktop-nav-only. */
.pk-navlink {
  position: relative;
  color: var(--ink);
  transition: color var(--dur-nav) var(--ease-out);
}

.pk-nav .pk-navlink {
  display: inline-block;
}

.pk-nav .pk-navlink::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-nav) var(--ease-out);
  pointer-events: none;
}

.pk-navlink:hover,
.pk-navlink.is-active {
  color: var(--accent);
}

.pk-nav .pk-navlink:hover::after,
.pk-nav .pk-navlink.is-active::after {
  transform: scaleX(1);
}

/* Photo frames clip their image so the radius holds. The hover scale lives in
   the reduced-motion guard below, but the clip must apply unconditionally. */
.pk-zoom {
  overflow: hidden;
}

/* Scroll reveals — JS strips inline opacity/transform so these cascade cleanly.
   Distances and durations mirror the import's per-kind reveal table. */
html.pk-motion-on .pk-reveal:not(.is-in),
html.pk-motion-on .pk-adv-item:not(.is-in) {
  opacity: 0;
  transform: translateY(var(--reveal-y));
}

html.pk-motion-on p.pk-reveal:not(.is-in) {
  transform: translateY(var(--reveal-y-text));
}

html.pk-motion-on .pk-reveal.pk-q-line:not(.is-in) {
  transform: translateY(var(--reveal-y));
}

html.pk-motion-on .pk-reveal.pk-req-card:not(.is-in),
html.pk-motion-on .pk-reveal.pk-price-card:not(.is-in),
html.pk-motion-on .pk-adv-item:not(.is-in) {
  transform: translateY(var(--reveal-y)) scale(var(--reveal-scale-card));
}

html.pk-motion-on .pk-reveal.pk-about-photo:not(.is-in),
html.pk-motion-on .pk-reveal.pk-cta-photo:not(.is-in) {
  transform: scale(var(--reveal-scale-photo));
}

html.pk-motion-on .pk-reveal.is-in,
html.pk-motion-on .pk-adv-item.is-in {
  opacity: 1;
  transform: none;
}

/* The import hands transitions back to the stylesheet once an element has
   arrived, so hovers play at their own duration. Mirror that by dropping the
   reveal transition from elements that do not declare one themselves. */
html.pk-motion-on .pk-reveal.is-settled:not(.pk-req-card):not(.pk-price-card):not(a) {
  transition: all 0s;
}

/* Mobile drawer keeps hairline separators — no grow-underline */
.pk-mnav .pk-navlink::after {
  display: none !important;
}

.pk-foot-nav a {
  position: relative;
}

.pk-foot-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-nav) var(--ease-out);
  pointer-events: none;
}

.pk-foot-nav a:hover::after {
  transform: scaleX(1);
}

/* Footer menu items sit on a 43px pitch, so the link box itself cannot grow to
   the 44px tap floor without pushing the footer off the import's layout.
   Reach into the gap with an invisible pseudo-element instead: it belongs to
   the link, so it takes the tap and triggers the hover underline, and it
   paints nothing. Touch only — on a mouse the 19px box is already precise. */
@media (pointer: coarse) {
  .pk-foot-nav a::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 44px;
    transform: translateY(-50%);
  }
}

/* ——— Reading progress ——— */
.pk-progress {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: rgba(180, 111, 82, 0.55);
  pointer-events: none;
  z-index: 2;
}

/* ——— Reveal surfaces ——— */
.pk-reveal {
  transition-property: opacity, transform;
  transition-duration: var(--dur-reveal);
  transition-timing-function: var(--ease-out);
}

.pk-about-photo,
.pk-cta-photo {
  transition-duration: var(--dur-photo);
}

.pk-adv-item {
  transition: opacity 0.8s var(--ease-soft), transform 0.55s var(--ease-out);
}

.pk-req-card,
.pk-price-card,
a.pk-reveal {
  transition-property: opacity, transform, box-shadow, border-color, background-color;
  transition-duration: var(--dur-reveal), var(--dur-reveal), var(--dur-hover), var(--dur-hover), var(--dur-hover);
  transition-timing-function: var(--ease-out), var(--ease-out), var(--ease-hover), var(--ease-hover), var(--ease-hover);
}

.pk-count-num {
  font-variant-numeric: tabular-nums;
  display: inline-block;
  text-align: right;
}

.pk-count-suf {
  opacity: 0;
  transition: opacity 400ms var(--ease-hover);
}

.pk-count-suf.is-in {
  opacity: 1;
}

/* Hero: hidden until JS staggers in (or fallback). Class on <html>.
   The header bar is never hidden — the import shows it from the first paint. */
html.pk-hero-prep .pk-label,
html.pk-hero-prep .pk-title,
html.pk-hero-prep .pk-desc,
html.pk-hero-prep .pk-btn,
html.pk-hero-prep .pk-social,
html.pk-hero-prep .pk-divider,
html.pk-hero-prep .pk-stats,
html.pk-hero-prep .pk-visual {
  opacity: 0;
}

html.pk-hero-prep .pk-label,
html.pk-hero-prep .pk-title,
html.pk-hero-prep .pk-desc,
html.pk-hero-prep .pk-btn,
html.pk-hero-prep .pk-social,
html.pk-hero-prep .pk-divider,
html.pk-hero-prep .pk-stats {
  transform: translateY(var(--reveal-y-hero));
}

html.pk-hero-prep .pk-visual {
  transform: scale(0.97);
}

html.pk-hero-prep .pk-label.is-hero-in,
html.pk-hero-prep .pk-title.is-hero-in,
html.pk-hero-prep .pk-desc.is-hero-in,
html.pk-hero-prep .pk-btn.is-hero-in,
html.pk-hero-prep .pk-social.is-hero-in,
html.pk-hero-prep .pk-divider.is-hero-in,
html.pk-hero-prep .pk-stats.is-hero-in {
  opacity: 1;
  /* `none`, not translateY(0), so the entrance leaves no stacking context */
  transform: none;
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
}

html.pk-hero-prep .pk-visual.is-hero-in {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-arch) var(--ease-out), transform var(--dur-arch) var(--ease-out);
}

/* Kill legacy CSS hero animations — JS owns entrance */
html.pk-hero-prep .pk-hdrbar,
html.pk-hero-prep .pk-label,
html.pk-hero-prep .pk-title,
html.pk-hero-prep .pk-desc,
html.pk-hero-prep .pk-btn,
html.pk-hero-prep .pk-social,
html.pk-hero-prep .pk-divider,
html.pk-hero-prep .pk-stats,
html.pk-hero-prep .pk-portrait {
  animation: none !important;
}

@media (prefers-reduced-motion: no-preference) {
  .pk-req-card:hover,
  .pk-price-card:hover {
    transition-duration: var(--dur-hover);
    transition-timing-function: var(--ease-hover);
    border-color: var(--accent);
  }

  /* !important: the reveal end-state sets transform:none at higher specificity */
  .pk-adv-item:hover {
    transform: translateY(-4px) !important;
  }

  .pk-req-card > svg,
  .pk-price-card svg,
  .pk-adv-icon svg {
    transition: transform var(--dur-hover) var(--ease-hover);
  }

  .pk-adv-item:hover .pk-adv-icon { transform: translateY(-7px); }
  .pk-about-item:hover .pk-about-ic { transform: translateY(-4px); }
  .pk-req-card:hover > svg,
  .pk-price-card:hover svg { transform: scale(1.06); }

  .pk-btn svg,
  .pk-fab svg,
  .pk-price-card a span:last-child {
    transition: transform var(--dur-nav) var(--ease-out);
  }

  .pk-btn:hover svg,
  .pk-fab:hover svg {
    transform: translateX(4px);
  }

  .pk-price-card a:hover span:last-child {
    transform: translateX(5px);
  }

  .pk-zoom img,
  .pk-q-photo > div img {
    transition: transform var(--dur-zoom) var(--ease-out);
  }
  .pk-zoom:hover img {
    transform: scale(1.04);
  }
  .pk-q-photo > div:hover img {
    transform: scale(1.05);
  }

  .pk-social > div > div {
    transition: transform var(--dur-hover) var(--ease-hover);
  }
  .pk-social:hover > div > div:nth-child(1) { transform: translateX(-7px); }
  .pk-social:hover > div > div:nth-child(3) { transform: translateX(5px); }
  .pk-social:hover > div > div:nth-child(4) { transform: translateX(10px); }

  .pk-dec.is-in {
    animation: pk-breathe 9s ease-in-out infinite;
  }

  .pk-visual.is-hero-in .pk-portrait img,
  .pk-visual.is-hero-in .pk-zoom img {
    animation: pk-portrait-drift 14s ease-in-out infinite;
    transform-origin: 50% 28%;
  }

  .pk-cta-arch {
    transition: transform var(--dur-arch) var(--ease-out), opacity var(--dur-arch) var(--ease-out);
  }
  html.pk-motion-on .pk-cta-photo:not(.is-in) .pk-cta-arch {
    opacity: 0;
    transform: translateY(28px) scale(0.97);
  }
  html.pk-motion-on .pk-cta-photo.is-in .pk-cta-arch {
    opacity: 1;
    transform: none;
  }

  .pk-dip-stage.is-fan-in .pk-dip-card {
    transition:
      transform 520ms var(--ease-soft),
      opacity 520ms ease-out,
      box-shadow 300ms ease;
  }

  .pk-fab.is-in,
  .pk-top.is-in {
    animation: pk-chip-in 480ms var(--ease-out);
  }

  .pk-social > div {
    animation: pk-soft-float 7.5s ease-in-out infinite;
  }

  .pk-btn,
  .pk-writebtn,
  a.pk-reveal[href] {
    position: relative;
    overflow: hidden;
  }
  .pk-btn::after,
  .pk-writebtn::after,
  a.pk-reveal[href]::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, transparent 30%, rgba(253, 243, 236, 0.22) 48%, transparent 62%);
    transform: translateX(-120%);
    transition: transform 700ms var(--ease-out);
    pointer-events: none;
  }
  .pk-btn:hover::after,
  .pk-writebtn:hover::after,
  a.pk-reveal[href]:hover::after {
    transform: translateX(120%);
  }
}

@media (prefers-reduced-motion: reduce) {
  html.pk-motion-on .pk-reveal,
  html.pk-motion-on .pk-adv-item,
  .pk-reveal,
  .pk-adv-item,
  .pk-req-card,
  .pk-price-card,
  .pk-dec,
  html.pk-hero-prep .pk-hdrbar,
  html.pk-hero-prep .pk-label,
  html.pk-hero-prep .pk-title,
  html.pk-hero-prep .pk-desc,
  html.pk-hero-prep .pk-btn,
  html.pk-hero-prep .pk-social,
  html.pk-hero-prep .pk-divider,
  html.pk-hero-prep .pk-stats,
  html.pk-hero-prep .pk-visual,
  html.pk-hero-prep .pk-portrait,
  .pk-boot-veil,
  .pk-lb,
  .pk-lb-img,
  .pk-visual .pk-portrait img,
  .pk-social > div,
  .pk-fab,
  .pk-top {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
  }

  .pk-boot-veil { display: none !important; }
  .pk-count-suf { opacity: 1 !important; }

  .pk-nav .pk-navlink::after,
  .pk-foot-nav a::after,
  .pk-btn::after,
  .pk-writebtn::after,
  a.pk-reveal[href]::after {
    transition: none;
  }
}

@media (hover: none), (pointer: coarse) {
  .pk-btn,
  .pk-writebtn,
  .pk-fab,
  .pk-top {
    transform: none !important;
  }
}
