/* ==========================================================================
   Cavara Circle — motion layer
   Calm, architectural motion: things rise, curtains open, lines draw.
   Everything here switches off under prefers-reduced-motion, and every hidden
   state is scoped under html.motion, which motion.js adds only when it can
   reveal content again (so the page never stays blank if a script fails).
   ========================================================================== */

:root {
  --ease-out: cubic-bezier(.2, .7, .2, 1);
  --ease-io: cubic-bezier(.7, 0, .2, 1);
  --intro: 1.55s;              /* time the intro curtain holds the screen */
}

/* ---------- Image placeholders (blur-up) ----------
   Every photo carries a tiny inline preview as its background. Until the real
   file arrives it shows blurred; then it sharpens into place. */
img[data-lqip] { background-size: cover; background-position: center; background-repeat: no-repeat; }
.motion img.is-loading { filter: blur(18px) saturate(.9); }
.motion img.is-loaded { animation: sharpen 1.1s var(--ease-out) both; }
@keyframes sharpen { from { filter: blur(18px) saturate(.9); } to { filter: none; } }

/* ---------- Plan & map placeholders ---------- */
.plan-view img { transition: opacity .35s ease; }
.plan-view img.is-swapping { opacity: 0; }

@media (prefers-reduced-motion: no-preference) {

  /* ---------- Intro curtain (CSS-driven, lifts itself) ---------- */
  .intro {
    position: fixed; inset: 0; z-index: 120; background: var(--night); color: var(--ivory);
    display: grid; place-items: center; pointer-events: none;
    animation: introLift 1.1s var(--ease-io) var(--intro) both;
  }
  .intro-inner { display: flex; flex-direction: column; align-items: center; gap: 1.6rem; }
  .intro .mark { width: 54px; height: auto; overflow: visible; }
  .intro .mark path { fill: var(--sand); fill-opacity: 0; stroke: var(--bronze); stroke-width: .6; stroke-dasharray: 1; stroke-dashoffset: 1; animation: drawMark 1s var(--ease-io) .1s forwards, fillMark .6s ease .85s forwards; }
  .intro .lg { height: clamp(40px, 9vw, 58px); color: var(--ivory); opacity: 0; animation: introLogo 1s var(--ease-out) .55s forwards; }
  .intro-line { width: 120px; height: 1px; background: rgba(224,214,203,.2); position: relative; overflow: hidden; }
  .intro-line::after { content: ""; position: absolute; inset: 0; background: var(--bronze); transform: scaleX(0); transform-origin: left; animation: introBar 1.2s var(--ease-io) .2s forwards; }
  html[dir="rtl"] .intro-line::after { transform-origin: right; }
  @keyframes drawMark { to { stroke-dashoffset: 0; } }
  @keyframes fillMark { to { fill-opacity: 1; stroke-opacity: 0; } }
  @keyframes introLogo { from { opacity: 0; letter-spacing: .2em; transform: translateY(8px); } to { opacity: 1; transform: none; } }
  @keyframes introBar { to { transform: scaleX(1); } }
  @keyframes introLift { to { transform: translateY(-100%); visibility: hidden; } }
  html.no-intro .intro { display: none; }

  /* Hero lockup waits for the curtain on first visit */
  .hero-media img { animation: heroIn 2.6s var(--ease-out) calc(var(--intro) + .2s) both; }
  .hero-lockup .logo { animation: rise 1.6s var(--ease-out) calc(var(--intro) + .55s) both; }
  .hero-tag { animation: rise 1.6s var(--ease-out) calc(var(--intro) + .8s) both; }
  .hero-panel .wrap > * { animation: rise 1.2s var(--ease-out) calc(var(--intro) + 1s) both; }
  .hero-panel .wrap > :last-child { animation-delay: calc(var(--intro) + 1.12s); }
  html.no-intro { --intro: -0.6s; }

  /* Scroll cue */
  .scroll-cue { position: absolute; left: 50%; bottom: 26px; width: 1px; height: 56px; background: rgba(224,214,203,.25); overflow: hidden; transform: translateX(-50%); animation: rise 1s var(--ease-out) calc(var(--intro) + 1.4s) both; }
  .scroll-cue::after { content: ""; position: absolute; left: 0; top: -40%; width: 1px; height: 40%; background: var(--ivory); animation: cue 2.2s var(--ease-io) infinite; }
  @keyframes cue { from { top: -40%; } to { top: 100%; } }

  /* ---------- Scroll reveals ---------- */
  .motion [data-reveal] { opacity: 0; transform: translateY(26px); transition: opacity 1s ease, transform 1.2s var(--ease-out); transition-delay: var(--d, 0s); }
  .motion [data-reveal].in { opacity: 1; transform: none; }

  /* Image curtain: the frame opens upward while the photo settles */
  .motion [data-reveal="frame"] { opacity: 1; transform: none; clip-path: inset(100% 0 0 0); transition: clip-path 1.4s var(--ease-io); transition-delay: var(--d, 0s); overflow: hidden; }
  .motion [data-reveal="frame"] img { transform: scale(1.16); transition: transform 2s var(--ease-out); transition-delay: var(--d, 0s); }
  .motion [data-reveal="frame"].in { clip-path: inset(0 0 0 0); }
  .motion [data-reveal="frame"].in img { transform: none; }
  .motion [data-reveal="solo"] { opacity: 1; transform: none; clip-path: inset(100% 0 0 0); transition: clip-path 1.3s var(--ease-io); transition-delay: var(--d, 0s); }
  .motion [data-reveal="solo"].in { clip-path: inset(0 0 0 0); }

  /* Titles rise word by word from behind a mask */
  .title .w, .collection h3 .w, .buyer h3 .w, .success h3 .w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .08em; margin-bottom: -.08em; }
  .title .w > span, .collection h3 .w > span, .buyer h3 .w > span, .success h3 .w > span { display: inline-block; transform: translateY(105%); transition: transform 1.1s var(--ease-out); transition-delay: calc(var(--d, 0s) + var(--i, 0) * 55ms); }
  .motion [data-split].in .w > span, html:not(.motion) .w > span { transform: none; }

  /* Hairline that draws across the payment timeline */
  .plan-steps { position: relative; border-top-color: transparent !important; }
  .plan-steps::before { content: ""; position: absolute; top: -1px; inset-inline: 0; height: 1px; background: var(--line-dark); transform: scaleX(0); transform-origin: left; transition: transform 1.8s var(--ease-io); }
  html[dir="rtl"] .plan-steps::before { transform-origin: right; }
  .plan-steps.in::before, html:not(.motion) .plan-steps::before { transform: scaleX(1); }
  .motion .plan-steps li::before { transform: scale(0); transition: transform .5s var(--ease-out); transition-delay: calc(.3s + var(--i, 0) * 180ms); }
  .motion .plan-steps.in li::before { transform: scale(1); }
  .motion .plan-steps li .figure-num, .motion .plan-steps li p { opacity: 0; transform: translateY(12px); transition: opacity .8s ease, transform .9s var(--ease-out); transition-delay: calc(.4s + var(--i, 0) * 180ms); }
  .motion .plan-steps.in li .figure-num, .motion .plan-steps.in li p { opacity: 1; transform: none; }

  /* ---------- Header: hides on the way down, returns on the way up ---------- */
  .site-header { transition: background .35s ease, color .35s ease, border-color .35s ease, transform .5s var(--ease-io); }
  .site-header.is-hidden { transform: translateY(calc(-100% - env(safe-area-inset-top, 0px))); }

  /* ---------- Tabs: indicator slides, panels settle in ---------- */
  .tab-panel.is-entering { animation: panelIn .9s var(--ease-out) both; }
  .tab-panel.is-entering .media { animation: curtain 1.2s var(--ease-io) both; }
  @keyframes panelIn { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
  @keyframes curtain { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }

  /* ---------- Lightbox ---------- */
  .lightbox { opacity: 0; transition: opacity .45s ease; }
  .lightbox.is-open { opacity: 1; }
  .lightbox .lb-stage img { transition: opacity .35s ease, transform .6s var(--ease-out); }
  .lightbox:not(.is-open) .lb-stage img { transform: scale(.97); }
  .lightbox .lb-stage img.is-swapping { opacity: 0; transform: translateX(calc(var(--dir, 1) * 24px)); }

  /* ---------- Drawer links cascade in ---------- */
  .drawer nav a { opacity: 0; transform: translateY(16px); transition: opacity .5s ease, transform .7s var(--ease-out); transition-delay: calc(.15s + var(--i, 0) * 55ms); }
  .drawer.is-open nav a { opacity: 1; transform: none; }

  /* ---------- Gallery hovers ---------- */
  .amen { overflow: visible; }
  .amen-strip button { overflow: hidden; }
  .amen-strip img, .plan-floors img, .map img { transition: transform 1.2s var(--ease-out); }
  .amen-strip button:hover img, .plan-floors button:hover img { transform: scale(1.05); }
  .amen-strip span { transition: transform .6s var(--ease-out); }
  .amen-strip button:hover span { transform: translateY(-4px); }

  /* ---------- Text links: underline retracts and redraws ---------- */
  .text-link { border-bottom: 0; background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat; }
  .text-link:hover { animation: relink .9s var(--ease-io); }
  @keyframes relink {
    0% { background-size: 100% 1px; background-position: 100% 100%; }
    45% { background-size: 0 1px; background-position: 100% 100%; }
    46% { background-size: 0 1px; background-position: 0 100%; }
    100% { background-size: 100% 1px; background-position: 0 100%; }
  }

  /* ---------- Form fields: focus line draws from the start edge ---------- */
  .field input, .field textarea { background-image: linear-gradient(var(--ink), var(--ink)); background-size: 0 1px; background-position: 0 100%; background-repeat: no-repeat; transition: background-size .6s var(--ease-io); }
  html[dir="rtl"] .field input, html[dir="rtl"] .field textarea { background-position: 100% 100%; }
  .field input:focus, .field textarea:focus { background-size: 100% 1px; box-shadow: none; }
  .segmented span { transition: background .35s ease, color .35s ease, border-color .35s ease; }
  .chip { transition: background .35s ease, color .35s ease, border-color .35s ease; }
  .chip:hover { border-color: var(--ink); }

  /* Success: the mark draws itself */
  .success-mark { width: 44px; color: var(--ink); }
  .success-mark path { fill-opacity: 0; stroke: var(--ink); stroke-width: .7; stroke-dasharray: 1; stroke-dashoffset: 1; }
  .success:not([hidden]) .success-mark path { animation: drawMark 1.1s var(--ease-io) .15s forwards, fillMark .6s ease 1s forwards; }
  .success:not([hidden]) > :not(.success-mark) { animation: rise .9s var(--ease-out) both; }
  .success:not([hidden]) > :nth-child(3) { animation-delay: .12s; }
  .success:not([hidden]) > :nth-child(4) { animation-delay: .22s; }

  /* ---------- Map: a quiet pulse on the plot ---------- */
  .map-pin { position: absolute; left: 46.1%; top: 64.6%; width: 14px; height: 14px; margin: -7px 0 0 -7px; pointer-events: none; }
  .map-pin::before, .map-pin::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 1px solid var(--ink); animation: pulse 2.8s var(--ease-out) infinite; }
  .map-pin::after { animation-delay: 1.4s; }
  @keyframes pulse { from { transform: scale(.6); opacity: .9; } to { transform: scale(4.2); opacity: 0; } }

  /* Submit button while sending */
  .btn.is-sending::after { content: ""; position: absolute; inset: auto 0 0 0; height: 2px; background: var(--bronze); transform-origin: left; animation: sending 1.1s var(--ease-io) infinite; }
  @keyframes sending { 0% { transform: scaleX(0); transform-origin: left; } 50% { transform: scaleX(1); transform-origin: left; } 51% { transform-origin: right; } 100% { transform: scaleX(0); transform-origin: right; } }
}

/* Static pieces that exist with or without motion */
.map { position: relative; }
@media (max-width: 700px) { .map-pin { left: 47.9%; top: 56.5%; } }
.success-mark { display: block; width: 44px; height: auto; color: var(--ink); }
.success-mark svg { width: 100%; height: auto; display: block; }
@media (prefers-reduced-motion: reduce) { .intro, .scroll-cue, .map-pin, .view-cursor { display: none !important; } }

/* Scroll progress: a hairline under the header */
.progress { position: absolute; inset-inline: 0; bottom: -1px; height: 1px; background: currentColor; opacity: .7; transform: scaleX(var(--p, 0)); transform-origin: left; pointer-events: none; }
html[dir="rtl"] .progress { transform-origin: right; }

/* Interiors rail: drag to scroll + progress track */
.rail.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.rail.is-dragging * { pointer-events: none; user-select: none; }
@media (pointer: fine) { .rail { cursor: grab; } }
.rail-track { height: 1px; background: var(--line); position: relative; margin-top: .4rem; }
.rail-track span { position: absolute; top: 0; height: 1px; background: var(--ink); inset-inline-start: 0; width: var(--w, 30%); transform: translateX(var(--x, 0)); transition: transform .15s linear; }
.rail { scrollbar-width: none; }
.rail::-webkit-scrollbar { display: none; }

/* "View" cursor over galleries (mouse only) */
.view-cursor {
  position: fixed; left: 0; top: 0; z-index: 80; width: 84px; height: 84px; margin: -42px 0 0 -42px; border-radius: 50%;
  display: grid; place-items: center; background: rgba(35,31,32,.82); color: var(--ivory);
  font-size: .66rem; letter-spacing: .2em; text-transform: uppercase; pointer-events: none;
  translate: -200px -200px; scale: 0; transition: scale .45s var(--ease-out);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.view-cursor.is-on { scale: 1; }
html[dir="rtl"] .view-cursor { font-family: var(--arabic); font-size: .85rem; }
@media (pointer: coarse) { .view-cursor { display: none; } }

/* Sliding tab indicator */
.tabs { position: relative; }
.tab-ink { position: absolute; left: 0; bottom: 0; height: 1px; width: 0; background: var(--ink); pointer-events: none; transition: transform .6s cubic-bezier(.7,0,.2,1), width .6s cubic-bezier(.7,0,.2,1); }
.tabs.has-ink .tab[aria-selected="true"] { border-bottom-color: transparent; }
html[dir="rtl"] .title .w { padding-block: .18em; margin-block: -.18em; }
