/* ==========================================================================
   INTERI motion layer. Load after style.css, with motion.js (defer).

   Every rule needs :root[data-motion="on"]. The inline script in index.html
   enables it before first paint on every page view. The static layout
   remains available when JavaScript or browser animation support is absent.

   Classes and variables written by motion.js:
     :root.motion-intro   hero entrance on the first view (removed after 2.6s)
     :root.motion-ready   scroll engine running; reveal targets may start hidden
     .is-revealed / .is-instant / .is-settled   reveal state on [data-reveal]
                          and [data-stagger] children
     .process-story[data-stage] and --p --sketch --plan --dims --swatch
                          --build --final   process story progress (0 to 1)
     .process-step.is-active   the step that matches the drawing
     --draw on .service-drawing   line drawing progress
     inline transform / clip-path   parallax, apertures, band and heading drift

   Without motion.js every element keeps its finished, readable state.
   ========================================================================== */

:root {
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-soft: cubic-bezier(.33, 1, .68, 1);
}

@keyframes m-rise { from { translate: 0 108%; } to { translate: 0 0; } }
@keyframes m-fade-up { from { opacity: 0; translate: 0 22px; } to { opacity: 1; translate: 0 0; } }
@keyframes m-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes m-drop { from { opacity: 0; translate: 0 -12px; } to { opacity: 1; translate: 0 0; } }
@keyframes m-curtain { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes m-settle { from { scale: 1.2; } to { scale: 1; } }

/* --------------------------------------------------------------------------
   1. Hero entrance. CSS only, so it finishes even if motion.js never runs.
   -------------------------------------------------------------------------- */

:root.motion-intro .site-header { animation: m-drop .8s var(--ease-out) both; }
:root.motion-intro .hero-copy .eyebrow { animation: m-fade-up .8s var(--ease-out) .08s both; }
:root.motion-intro .hero-copy h1 .line > * { display: block; animation: m-rise 1.2s var(--ease-out) .16s both; }
:root.motion-intro .hero-copy h1 .line + .line > * { animation-delay: .3s; }
:root.motion-intro .hero-description { animation: m-fade-up 1s var(--ease-out) .5s both; }
:root.motion-intro .hero-detail { animation: m-fade-up 1s var(--ease-out) .58s both; }
:root.motion-intro .hero-actions { animation: m-fade-up 1s var(--ease-out) .66s both; }
:root.motion-intro .hero-proof { animation: m-fade-up 1s var(--ease-out) .76s both; }
:root.motion-intro .scroll-cue { animation: m-fade 1s ease 1.1s both; }
:root.motion-intro .hero-image { animation: m-curtain 1.5s var(--ease-out) .1s both; }
:root.motion-intro .hero-image > img { animation: m-settle 2.1s var(--ease-out) .1s both; }
:root.motion-intro :is(.hero-image figcaption, .image-side-note) { animation: m-fade .9s ease 1s both; }
:root.motion-intro .craft-band { animation: m-fade 1s ease .7s both; }

/* Headline lines rise out of a mask. Padding keeps accents and descenders. */
:root.motion-intro .hero-copy h1 .line,
:root.motion-ready [data-reveal]:not(.is-settled) .line {
  overflow: hidden;
  overflow: clip;
  padding: .12em .14em .2em;
  margin: -.12em -.14em -.2em;
}

/* --------------------------------------------------------------------------
   2. Scroll reveals. Hidden states need .motion-ready (set by motion.js)
      and apply only below the fold; a failed script never hides content.
   -------------------------------------------------------------------------- */

:root.motion-ready [data-reveal]:not(.is-revealed) .line > * { display: block; translate: 0 108%; }

:root.motion-ready .section-heading[data-reveal]:not(.is-revealed) :is(.eyebrow, .heading-aside),
:root.motion-ready :is(.studio-copy, .contact-copy)[data-reveal]:not(.is-revealed) > :not(h2),
:root.motion-ready .project-card[data-reveal]:not(.is-revealed) :is(.project-caption, .image-tag, .photo-count, .project-open-icon),
:root.motion-ready :is(.portfolio-invitation, .inquiry-form)[data-reveal]:not(.is-revealed),
:root.motion-ready [data-stagger] > :not(.is-revealed) {
  opacity: 0;
}

:root.motion-ready [data-reveal].is-revealed:not(.is-instant) .line > * {
  display: block;
  animation: m-rise 1.15s var(--ease-out) calc(var(--reveal-delay, 0ms) + 60ms) both;
}
:root.motion-ready [data-reveal].is-revealed:not(.is-instant) .line + .line > * { animation-delay: calc(var(--reveal-delay, 0ms) + 180ms); }
:root.motion-ready .section-heading.is-revealed:not(.is-instant) .eyebrow { animation: m-fade-up .9s var(--ease-out) var(--reveal-delay, 0ms) both; }
:root.motion-ready .section-heading.is-revealed:not(.is-instant) .heading-aside { animation: m-fade-up 1s var(--ease-out) calc(var(--reveal-delay, 0ms) + 320ms) both; }
:root.motion-ready :is(.studio-copy, .contact-copy).is-revealed:not(.is-instant) > :not(h2) { animation: m-fade-up 1s var(--ease-out) calc(var(--reveal-delay, 0ms) + 300ms) both; }
:root.motion-ready :is(.studio-copy, .contact-copy).is-revealed:not(.is-instant) > .eyebrow { animation-delay: var(--reveal-delay, 0ms); }
:root.motion-ready .project-card.is-revealed:not(.is-instant) .project-caption { animation: m-fade-up 1s var(--ease-out) calc(var(--reveal-delay, 0ms) + 240ms) both; }
:root.motion-ready .project-card.is-revealed:not(.is-instant) :is(.image-tag, .photo-count, .project-open-icon) { animation: m-fade .8s ease calc(var(--reveal-delay, 0ms) + 480ms) both; }
:root.motion-ready :is(.portfolio-invitation, .inquiry-form).is-revealed:not(.is-instant) { animation: m-fade-up 1.1s var(--ease-out) var(--reveal-delay, 0ms) both; }
:root.motion-ready [data-stagger] > .is-revealed:not(.is-instant) { animation: m-fade-up 1s var(--ease-out) var(--reveal-delay, 0ms) both; }

/* --------------------------------------------------------------------------
   3. Photographs: parallax and scroll apertures. motion.js writes the
      transform; these base scales match it so the first paint agrees.
   -------------------------------------------------------------------------- */

:root[data-motion="on"] .hero-image > img { transform: scale(1.11); }
:root[data-motion="on"] :is(.project-image, .studio-image, .miami-frame) > img {
  transform: scale(1.14);
  will-change: transform;
  transition: scale .9s var(--ease-out);
}

@media (hover: hover) {
  :root[data-motion="on"] .project-open:hover .project-image > img { scale: 1.045; }
  :root[data-motion="on"] .project-open:hover .project-open-icon { translate: 3px -3px; }
}
:root[data-motion="on"] .project-open:focus-visible .project-image > img { scale: 1.045; }
:root[data-motion="on"] .project-open-icon { transition: translate .5s var(--ease-out), background-color .3s; }

/* --------------------------------------------------------------------------
   4. Craft band: a ruler of services that slides with the scroll.
   -------------------------------------------------------------------------- */

:root[data-motion="on"] .craft-strip {
  display: flex;
  justify-content: flex-start;
  width: max-content;
  gap: 0;
  padding: 36px 0 46px;
  font: 400 clamp(30px, 3.3vw, 52px)/1.1 var(--display);
  letter-spacing: -.025em;
  transform: translate3d(-140px, 0, 0);
  will-change: transform;
}
:root[data-motion="on"] .craft-strip li { gap: 0; white-space: nowrap; }
:root[data-motion="on"] .craft-strip li[aria-hidden] { display: flex; }
:root[data-motion="on"] .craft-strip li::before {
  content: '';
  flex: none;
  width: 8px;
  height: 8px;
  margin: 0 clamp(26px, 3vw, 50px);
  border-radius: 0;
  background: var(--red);
}
:root[data-motion="on"] .craft-strip li.alt { font-style: italic; color: var(--sage); }
:root[data-motion="on"] .craft-ruler {
  display: block;
  position: absolute;
  left: -240px;
  right: -240px;
  bottom: 0;
  height: 13px;
  opacity: .7;
  background:
    linear-gradient(90deg, var(--sage) 1px, transparent 1px) 0 100% / 12px 5px repeat-x,
    linear-gradient(90deg, var(--sage) 1px, transparent 1px) 0 100% / 60px 13px repeat-x;
  will-change: transform;
}

/* --------------------------------------------------------------------------
   5. Service drawings draw themselves with the scroll.
   -------------------------------------------------------------------------- */

:root.motion-ready .service-drawing :is(path, circle):not(.guide) {
  stroke-dasharray: 1 1;
  stroke-dashoffset: calc(1 - var(--draw, 1));
}
:root.motion-ready .service-drawing .guide { opacity: var(--draw, 1); }

/* --------------------------------------------------------------------------
   6. Process story: the kitchen is sketched, drawn, built and installed
      while the four steps scroll past. Signature sequence.
   -------------------------------------------------------------------------- */

@media (min-width: 900px) {
  :root[data-motion="on"] .story-visual { position: sticky; top: calc(var(--header-h) + 3vh); }
  :root[data-motion="on"] .story-frame { width: min(100%, calc(100vh - var(--header-h) - 3vh - 92px)); }
  :root[data-motion="on"] .process-grid { padding: 14vh 0 34vh; }
  :root[data-motion="on"] .process-step { min-height: 64vh; align-content: center; border-top: 0; }
}

@media (max-width: 899px) {
  :root[data-motion="on"] .process-story { gap: 0; }
  :root[data-motion="on"] .story-visual {
    position: sticky;
    top: var(--header-h);
    z-index: 3;
    padding: 6px 0 4px;
    background: var(--paper);
  }
  :root[data-motion="on"] .story-visual::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    height: 44px;
    background: linear-gradient(var(--paper), rgba(245, 245, 242, 0));
    pointer-events: none;
  }
  :root[data-motion="on"] .story-frame { width: min(100%, calc(44svh * 8 / 7)); margin: 0 auto; }
  :root[data-motion="on"] .story-meta { min-height: 34px; padding-top: 10px; }
  :root[data-motion="on"] .process-grid { padding: 12svh 0 30svh; }
  :root[data-motion="on"] .process-step { min-height: 46svh; align-content: center; border-top: 0; }
}

:root.motion-ready .story-drawing { opacity: 1; }
:root.motion-ready .story-stage { scale: calc(1.035 - .035 * var(--final, 1)); }
.story-paper > rect:first-child { fill: var(--paper); }
#story-grid path { stroke: #dde2d7; stroke-width: 1.6; }
:root.motion-ready .story-paper,
:root.motion-ready .story-lines { opacity: calc(1 - var(--final, 1)); }

.story-lines path { fill: none; stroke-width: 2.6; stroke-linejoin: round; }
.story-room { stroke: var(--sage); --g: var(--sketch, 1); }
.story-cabinets { stroke: var(--ink); --g: var(--plan, 1); }
.story-dims { stroke: var(--red); --g: var(--dims, 1); }
.story-dims path { stroke-width: 2.1; }
:root.motion-ready .story-lines path {
  stroke-dasharray: 1 1;
  stroke-dashoffset: calc(1 - clamp(0, (var(--g) * (var(--n) + 3) - var(--i)) / 4, 1));
}
/* Cabinet fronts take on the real photograph one by one. */
.story-holes > * { fill: #000; }
:root.motion-ready .story-holes > * { opacity: clamp(0, var(--build, 1) * var(--n) - var(--i), 1); }

@media (max-width: 899px) {
  .story-lines path { stroke-width: 5; }
  .story-dims path { stroke-width: 4; }
}

/* Material swatches cut from the same photograph appear while designing. */
:root.motion-ready .story-swatches {
  display: grid;
  gap: 10px;
  position: absolute;
  right: 3.6%;
  top: 50%;
  translate: 0 -50%;
  z-index: 1;
}
.story-swatches i {
  display: block;
  width: clamp(24px, 6.4vmin, 46px);
  aspect-ratio: 1;
  border: 2px solid var(--paper);
  border-radius: 50%;
  box-shadow: 0 4px 14px rgba(37, 41, 37, .2);
  background: url('assets/portfolio/mazas-butas-5.webp') var(--at) / 1100% auto no-repeat;
  --shown: clamp(0, var(--swatch, 0) * 1.6 - var(--i) * .2, 1);
  opacity: var(--shown);
  scale: calc(.5 + .5 * var(--shown));
}
.story-swatches i:nth-child(1) { --at: 20.5% 8.6%; }
.story-swatches i:nth-child(2) { --at: 58% 18.5%; }
.story-swatches i:nth-child(3) { --at: 56.6% 47.4%; }
.story-swatches i:nth-child(4) { --at: 25% 60.5%; }

/* Stage label in the frame corner. */
:root.motion-ready .story-stamps { display: block; position: absolute; left: 14px; top: 14px; z-index: 2; width: 190px; height: 30px; }
.story-stamps > span {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 30px;
  padding: 0 12px;
  background: var(--paper);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  translate: 0 8px;
  transition: opacity .45s ease, translate .6s var(--ease-out);
}
.story-stamps b { font-weight: 600; color: var(--red); }
.process-story:not([data-stage]) .story-stamps > span:nth-child(1),
.process-story[data-stage="0"] .story-stamps > span:nth-child(1),
.process-story[data-stage="1"] .story-stamps > span:nth-child(2),
.process-story[data-stage="2"] .story-stamps > span:nth-child(3),
.process-story[data-stage="3"] .story-stamps > span:nth-child(4) { opacity: 1; translate: 0 0; }

/* Progress rail under the frame. */
:root.motion-ready .story-rail {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  position: relative;
  flex: none;
  width: min(280px, 52%);
  padding-top: 12px;
  font-size: 10px;
  letter-spacing: .08em;
}
.story-rail::before,
.story-rail-fill { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--line); }
.story-rail-fill { background: var(--red); transform: scaleX(var(--p, 1)); transform-origin: 0 50%; }
.story-rail b { font-weight: 500; color: var(--muted); transition: color .3s; }
.process-story[data-stage="0"] .story-rail b:nth-of-type(1),
.process-story[data-stage="1"] .story-rail b:nth-of-type(-n+2),
.process-story[data-stage="2"] .story-rail b:nth-of-type(-n+3),
.process-story[data-stage="3"] .story-rail b { color: var(--red); }
:root.motion-ready .story-note { display: inline; }

/* The active step follows the drawing. */
:root.motion-ready .process-step { position: relative; }
:root.motion-ready .process-step::before {
  content: '';
  position: absolute;
  left: -24px;
  top: 50%;
  width: 2px;
  height: 72px;
  translate: 0 -50%;
  background: var(--red);
  transform: scaleY(0);
  transition: transform .5s var(--ease-out);
}
:root.motion-ready .process-step > span { color: var(--muted); transition: color .4s ease; }
:root.motion-ready .process-step > div { transition: translate .7s var(--ease-out); }
:root.motion-ready .process-step.is-active::before { transform: scaleY(1); }
:root.motion-ready .process-step.is-active > span { color: var(--red); }
:root.motion-ready .process-step.is-active > div { translate: 10px 0; }

@media (max-width: 899px) {
  :root.motion-ready .process-step::before { left: -14px; height: 56px; }
  :root.motion-ready .process-step.is-active > div { translate: 6px 0; }
}

/* --------------------------------------------------------------------------
   7. Small hover and focus feedback.
   -------------------------------------------------------------------------- */

:root[data-motion="on"] .button { transition: background-color .3s ease, border-color .3s ease, color .3s ease, translate .5s var(--ease-out); }
:root[data-motion="on"] :is(.button, .text-link, .contact-phone) > span[aria-hidden] { display: inline-block; transition: translate .5s var(--ease-out); }
:root[data-motion="on"] .button:focus-visible { translate: 0 -2px; }
:root[data-motion="on"] :is(.button, .text-link, .contact-phone):focus-visible > span[aria-hidden] { translate: 3px -3px; }

@media (hover: hover) {
  :root[data-motion="on"] .button:hover { translate: 0 -2px; }
  :root[data-motion="on"] .button:hover:active { translate: 0 0; }
  :root[data-motion="on"] :is(.button, .text-link, .contact-phone):hover > span[aria-hidden] { translate: 3px -3px; }
}

@media (max-width: 760px) {
  :root[data-motion="on"] .craft-strip { padding: 26px 0 34px; font-size: 30px; }
  :root[data-motion="on"] .craft-strip li::before { width: 6px; height: 6px; margin: 0 22px; }
}

@media print {
  .story-drawing, .story-swatches, .story-stamps, .scroll-progress { display: none !important; }
}
