/* ==========================================================================
   LOVELY EVENTS & DECORATION — motion.css
   Royal, animated enhancement layer. Additive only: extends the existing
   .reveal / IntersectionObserver system in app.js, never replaces it.

   Loaded LAST (after styles.css). Every hidden/animated *state* introduced
   here is gated behind `html.motion-ready`, a class motion.js adds itself —
   so if motion.js never runs (blocked/errors), nothing in this file ever
   hides anything: the page renders exactly as styles.css already paints it.

   Sections:
     0. Guards, helpers, reduced-motion
     1. Ornamental gold dividers
     2. Section heading motion (rule draw / word rise / shimmer)
     3. Grid stagger + card tilt / glow / shine
     4. Welcome section — royal centrepiece
     5. Featured & gallery — clip-path wipe + gold "View" pill
     6. Back-to-top ring + scroll progress bar
     7. Footer shimmer + flourish
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Guards & helpers
   -------------------------------------------------------------------------- */
.m-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   1. Ornamental gold dividers (inserted by motion.js between major sections)
   -------------------------------------------------------------------------- */
.m-divider {
  display: flex; align-items: center; justify-content: center;
  padding-block: clamp(1.1rem, 4vw, 2.2rem);
  background: transparent;
}
.m-divider-svg {
  width: min(300px, 62vw); height: 32px; overflow: visible;
  color: var(--color-accent, #C9A45C);
}
.m-divider-path {
  fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; opacity: .8;
}
.m-divider-center path { fill: currentColor; opacity: .95; }
.m-divider-center circle { fill: none; stroke: currentColor; stroke-width: 1.1; opacity: .9; }

html.motion-ready .m-divider-path {
  stroke-dasharray: 300; stroke-dashoffset: 300;
  transition: stroke-dashoffset 1.1s var(--ease, ease);
}
html.motion-ready .m-divider.in-view .m-divider-path--l { stroke-dashoffset: 0; }
html.motion-ready .m-divider.in-view .m-divider-path--r { stroke-dashoffset: 0; transition-delay: .12s; }
html.motion-ready .m-divider-center {
  transform-box: fill-box; transform-origin: center;
  transform: scale(0); opacity: 0;
  transition: transform .5s var(--ease, ease) .55s, opacity .5s var(--ease, ease) .55s;
}
html.motion-ready .m-divider.in-view .m-divider-center { transform: scale(1); opacity: 1; }

/* --------------------------------------------------------------------------
   2. Section heading motion
   -------------------------------------------------------------------------- */
html.motion-ready .m-head .section-head-rule {
  transform-origin: left center; transform: scaleX(0);
  transition: transform .7s var(--ease, ease);
}
html.motion-ready .m-head .section-head-rule--center { transform-origin: center center; }
html.motion-ready .m-head.m-in .section-head-rule { transform: scaleX(1); }

.m-split { display: inline; }
.m-word { display: inline-block; }
html.motion-ready .m-heading-split .m-word {
  opacity: 0; transform: translateY(22px);
  transition: opacity .6s var(--ease, ease), transform .6s var(--ease, ease);
  transition-delay: calc(var(--i, 0) * 60ms);
}
html.motion-ready .m-head.m-in .m-heading-split .m-word { opacity: 1; transform: translateY(0); }

html.motion-ready .m-heading-plain {
  opacity: 0; transform: translateY(18px);
  transition: opacity .6s var(--ease, ease), transform .6s var(--ease, ease);
}
html.motion-ready .m-head.m-in .m-heading-plain { opacity: 1; transform: translateY(0); }

html.motion-ready .m-word-shimmer {
  background-image: linear-gradient(100deg, var(--color-accent) 32%, #fff6df 50%, var(--color-accent) 68%);
  background-size: 250% 100%;
  background-position: 200% 0;
  -webkit-background-clip: text; background-clip: text;
  color: var(--color-accent); -webkit-text-fill-color: transparent;
}
html.motion-ready .m-head.m-in .m-word-shimmer {
  animation: mShimmerWord 1.4s ease-out calc(var(--i, 0) * 60ms + .5s) 1 both;
}
@keyframes mShimmerWord { from { background-position: 200% 0; } to { background-position: -40% 0; } }

/* --------------------------------------------------------------------------
   3. Grid stagger + card tilt / glow / shine sweep
   -------------------------------------------------------------------------- */
/* Staggered reveal, pure CSS (works even on dynamically re-rendered gallery
   items after a filter change, no JS re-hook needed). */
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card):nth-child(1) { transition-delay: 0ms; }
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card):nth-child(2) { transition-delay: 60ms; }
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card):nth-child(3) { transition-delay: 120ms; }
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card):nth-child(4) { transition-delay: 180ms; }
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card):nth-child(5) { transition-delay: 240ms; }
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card):nth-child(6) { transition-delay: 300ms; }
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card):nth-child(7) { transition-delay: 360ms; }
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card):nth-child(n+8) { transition-delay: 420ms; }

/* Gallery items animate via an unconditional keyframe (no IntersectionObserver
   needed — same JS-independent guarantee as the original fadein rule this
   replaces), so give them an equivalent nth-child stagger on animation-delay. */
.gallery-item:nth-child(1) { animation-delay: 0ms; }
.gallery-item:nth-child(2) { animation-delay: 40ms; }
.gallery-item:nth-child(3) { animation-delay: 80ms; }
.gallery-item:nth-child(4) { animation-delay: 120ms; }
.gallery-item:nth-child(5) { animation-delay: 160ms; }
.gallery-item:nth-child(6) { animation-delay: 200ms; }
.gallery-item:nth-child(n+7) { animation-delay: 240ms; }

/* Tilt + lift + gold glow. Base transform always present (custom props
   default to 0), so hover-lift works everywhere via plain CSS; motion.js only
   ever nudges --m-rx/--m-ry on (hover:hover) + fine-pointer devices. */
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card, .gallery-item) {
  transform: perspective(1000px) rotateX(var(--m-rx, 0deg)) rotateY(var(--m-ry, 0deg)) translateY(var(--m-ty, 0px));
  transition: transform .25s var(--ease, ease), box-shadow .25s var(--ease, ease);
}
@media (hover: hover) {
  :is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card, .gallery-item):hover,
  :is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card, .gallery-item):focus-within {
    --m-ty: -6px;
    box-shadow: 0 0 0 1px var(--color-border-gold, rgba(201, 164, 92, .45)), 0 22px 44px rgba(0, 0, 0, .38), 0 0 30px rgba(201, 164, 92, .16);
  }
}

/* Diagonal image shine sweep on hover.
   .category-tile is deliberately excluded here: styles.css gives its .media
   `position: absolute; inset: 0` so the photo fills the whole bento tile
   (the overlay label sits on top of it). Re-asserting `position: relative`
   for it too (same specificity, loaded after styles.css) used to win the
   cascade and silently collapse the tile back to the image's own intrinsic
   aspect-ratio height, leaving the caption stranded in empty space below the
   photo. `.media`'s own `position: absolute` already gives the ::after
   shine sweep below a valid positioning context, so category-tile never
   needed this rule. */
:is(.service-card, .welcome-card, .featured-item, .popular-card, .why-card, .gallery-item) .media {
  position: relative;
}
:is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .gallery-item) .media::after {
  content: ''; position: absolute; inset: -40% -15%; z-index: 2; pointer-events: none;
  background: linear-gradient(75deg, transparent 42%, rgba(255, 255, 255, .32) 50%, transparent 58%);
  transform: translateX(-130%);
  transition: transform .85s var(--ease, ease);
}
@media (hover: hover) {
  :is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .gallery-item):hover .media::after {
    transform: translateX(130%);
  }
}

/* --------------------------------------------------------------------------
   4. Welcome section — royal centrepiece
   -------------------------------------------------------------------------- */
.section-welcome { position: relative; }
.section-welcome::after {
  content: ''; position: absolute; inset: -12%; z-index: 0; pointer-events: none;
  background:
    radial-gradient(circle at 28% 22%, rgba(215, 25, 32, .16), transparent 55%),
    radial-gradient(circle at 76% 78%, rgba(201, 164, 92, .18), transparent 55%);
  opacity: .9;
}
html.motion-ready .section-welcome::after { animation: mWelcomeGlow 11s ease-in-out infinite alternate; }
@keyframes mWelcomeGlow {
  from { transform: scale(1) translate(0, 0); }
  to { transform: scale(1.08) translate(-2%, 2%); }
}

html.motion-ready #welcome .hairline-flank:first-child {
  transform-origin: right center; transform: scaleX(0);
  transition: transform .7s var(--ease, ease);
}
html.motion-ready #welcome .hairline-flank:last-child {
  transform-origin: left center; transform: scaleX(0);
  transition: transform .7s var(--ease, ease) .1s;
}
html.motion-ready #welcome.m-welcome-in .hairline-flank { transform: scaleX(1); }

html.motion-ready .welcome-title {
  opacity: 0; transform: translateY(20px);
  transition: opacity .7s var(--ease, ease), transform .7s var(--ease, ease);
}
html.motion-ready #welcome.m-welcome-in .welcome-title { opacity: 1; transform: translateY(0); }

.welcome-title { position: relative; overflow: hidden; }
.welcome-title::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background: linear-gradient(100deg, transparent 35%, rgba(255, 246, 223, .5) 50%, transparent 65%);
  transform: translateX(-120%);
  mix-blend-mode: screen;
}
html.motion-ready #welcome.m-welcome-in .welcome-title::before {
  animation: mShimmerPass 1.3s ease-out .5s 1 both;
}
@keyframes mShimmerPass { from { transform: translateX(-120%); } to { transform: translateX(120%); } }

.welcome-card { position: relative; }

/* Illustration swap (teddy / popcorn) — gentle float + illustration badge. */
.m-illustration-img { width: 100%; height: 100%; object-fit: contain; position: relative; z-index: 1; }
html.motion-ready .m-illustration-img { animation: mFloat 6s ease-in-out infinite; }
@keyframes mFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
.m-illustration-badge {
  position: absolute; left: 12px; bottom: 12px; z-index: 2;
  font-size: .65rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-accent); background: rgba(11, 11, 12, .55);
  border: 1px solid var(--color-border-gold); padding: .3em .75em; border-radius: 999px;
}

/* Gold sparkle particles spawned on hover by motion.js. */
.m-sparkle {
  position: absolute; width: 5px; height: 5px; border-radius: 50%; z-index: 3; pointer-events: none;
  background: radial-gradient(circle, #fff6df 0%, var(--color-accent) 60%, transparent 100%);
  animation: mSparkle var(--d, 900ms) ease-out forwards;
}
@keyframes mSparkle {
  0% { opacity: 0; transform: translate(0, 0) scale(.4); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--x2, 0px), -28px) scale(1); }
}

/* --------------------------------------------------------------------------
   5. Featured & gallery — clip-path wipe + gold "View" pill
   -------------------------------------------------------------------------- */
html.motion-ready .featured-item .media {
  clip-path: inset(0 100% 0 0);
  transition: clip-path .9s var(--ease, ease);
}
html.motion-ready .featured-item.m-wipe-in .media { clip-path: inset(0 0 0 0); }

.featured-view {
  border-color: var(--color-border-gold);
  color: var(--color-accent);
  background: rgba(11, 11, 12, .35);
  transition: transform .3s var(--ease, ease), box-shadow .3s var(--ease, ease);
}
.featured-item:hover .featured-view, .featured-item:focus-visible .featured-view {
  box-shadow: 0 0 0 1px var(--color-border-gold), 0 10px 22px rgba(201, 164, 92, .28);
  transform: translateY(-2px);
}

/* Gallery items reveal via clip-path wipe on every render (overrides the
   styles.css `fadein` keyframe — same JS-independent guarantee: no fill-mode,
   so before/after the animation the element simply uses its normal, fully
   visible styles). */
@keyframes mGalleryReveal {
  from { opacity: 0; transform: scale(.97); clip-path: inset(0 32% 0 0); }
  to { opacity: 1; transform: scale(1); clip-path: inset(0 0 0 0); }
}
.gallery-item { animation-name: mGalleryReveal; animation-duration: var(--dur-med, .5s); animation-timing-function: var(--ease, ease); }

.gallery-item-overlay {
  flex-direction: column; gap: .5rem;
  background: linear-gradient(180deg, rgba(11, 11, 12, .12), rgba(11, 11, 12, .62));
}
.gallery-item-overlay .icon { color: var(--color-accent); }
.gallery-item-overlay::after {
  content: 'View';
  font-size: .68rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: #fff; border: 1px solid var(--color-border-gold); border-radius: 999px;
  padding: .3em 1em; background: rgba(0, 0, 0, .28);
}

/* --------------------------------------------------------------------------
   6. Back-to-top ring + scroll progress bar
   -------------------------------------------------------------------------- */
.m-scrollbar {
  position: fixed; top: var(--header-h, 74px); left: 0; width: 100%; height: 3px;
  z-index: 59; pointer-events: none; background: transparent;
}
.m-scrollbar-fill {
  display: block; width: 100%; height: 100%; transform-origin: left center; transform: scaleX(0);
  background: linear-gradient(90deg, var(--color-secondary, #D71920), var(--color-accent, #C9A45C));
}

.m-top {
  position: fixed; left: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  width: 52px; height: 52px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(11, 11, 12, .78);
  color: var(--color-accent); border: 1px solid var(--color-border-gold);
  box-shadow: var(--shadow-md, 0 16px 40px rgba(0, 0, 0, .35));
  z-index: 55;
  opacity: 0; transform: translateY(12px) scale(.9); pointer-events: none;
  transition: opacity var(--dur-fast, .2s) var(--ease, ease), transform var(--dur-fast, .2s) var(--ease, ease);
}
.m-top.is-visible { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.m-top:hover, .m-top:focus-visible { color: #fff6df; }
.m-top-ring { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.m-top-ring-track { fill: none; stroke: rgba(201, 164, 92, .25); stroke-width: 2.4; }
.m-top-ring-progress {
  fill: none; stroke: var(--color-accent); stroke-width: 2.4; stroke-linecap: round;
  transition: stroke-dashoffset .15s linear;
}
.m-top-arrow { width: 20px; height: 20px; position: relative; z-index: 1; }
@media (max-width: 480px) {
  .m-top { width: 48px; height: 48px; left: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); }
}

/* --------------------------------------------------------------------------
   7. Footer shimmer + flourish
   -------------------------------------------------------------------------- */
.site-footer .footer-brand .brand-mark { position: relative; overflow: hidden; }
.site-footer .footer-brand .brand-mark::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, rgba(201, 164, 92, .55) 50%, transparent 70%);
  transform: translateX(-120%);
  mix-blend-mode: screen;
}
html.motion-ready .site-footer .footer-brand .brand-mark::after {
  animation: mFooterShimmer 5s ease-in-out infinite;
}
@keyframes mFooterShimmer {
  0% { transform: translateX(-120%); }
  30% { transform: translateX(120%); }
  100% { transform: translateX(120%); }
}

/* --------------------------------------------------------------------------
   8. Reduced motion — explicit belt-and-braces on top of the sitewide
      duration squash already in styles.css (matches the existing convention
      used for .hero-media img's kenburns animation).
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .section-welcome::after,
  .m-illustration-img,
  .site-footer .footer-brand .brand-mark::after,
  html.motion-ready #welcome.m-welcome-in .welcome-title::before,
  html.motion-ready .m-head.m-in .m-word-shimmer {
    animation: none !important;
  }
  .m-sparkle { display: none; }
  :is(.service-card, .category-tile, .welcome-card, .featured-item, .popular-card, .why-card, .gallery-item) {
    --m-rx: 0deg; --m-ry: 0deg; --m-ty: 0px;
  }
}

/* --------------------------------------------------------------------------
   9. No horizontal overflow / small-screen safety
   -------------------------------------------------------------------------- */
@media (max-width: 360px) {
  .m-divider-svg { width: min(240px, 78vw); }
}
