/* ==========================================================================
   Mumbai Literature Festival — motion layer
   --------------------------------------------------------------------------
   How it works
   - Elements opt in with  data-a="<type>"  and belong to the nearest
     [data-scene]. js/motion.js adds .in to every item when its scene enters
     the viewport and writes --d (delay, seconds) on each item.
   - Items are only pre-hidden when <html> has .motion (set by the inline
     script in <head>). No JS / reduced motion / init failure = no hiding.
   - Keyframes only define the "from" state wherever possible, so they always
     land on the element's real resting style.
   - Entrances animate the individual `translate` / `scale` / `rotate`
     properties; scroll + pointer parallax writes CSS variables consumed by
     `transform`. The two never fight, and hover states stay free.
   ========================================================================== */

:root {
    --gold: #b08d57;
    --ease: cubic-bezier(.22, 1, .36, 1);       /* soft expo-out: text, fades */
    --ease-mask: cubic-bezier(.77, 0, .18, 1);  /* in-out: masks, rules, wipes */
}

html { scroll-padding-top: 72px; }
body { overflow-x: clip; }

/* --------------------------------------------------------------------------
   1. Reveal system
   -------------------------------------------------------------------------- */
.motion [data-a]:not(.in) { opacity: 0; }

.in[data-a] {
    animation-duration: var(--dur, 1.1s);
    animation-timing-function: var(--ease);
    animation-delay: var(--d, 0s);
    animation-fill-mode: backwards;
}
.in[data-a=rise]  { animation-name: a-rise; }
.in[data-a=drop]  { animation-name: a-drop; --dur: .9s; }
.in[data-a=fade]  { animation-name: a-fade; --dur: 1.3s; }
.in[data-a=pop]   { animation-name: a-pop; --dur: .95s; }
.in[data-a=leaf]  { animation-name: a-leaf; --dur: 2s; }
.in[data-a=drawy] { animation-name: a-drawy; --dur: 1.2s; animation-timing-function: var(--ease-mask); transform-origin: top; }
.in[data-a=mask]  { animation-name: a-mask; --dur: 1.4s; animation-timing-function: var(--ease-mask); }
.in[data-a=wipe]  { animation-name: a-wipe; --dur: 1.5s; animation-timing-function: var(--ease-mask); }
.in[data-a=draw]  { animation-name: a-mask; --dur: 2.2s; animation-timing-function: var(--ease-mask); }
.in[data-a=arch]  { animation-name: a-mask; --dur: 1.6s; animation-timing-function: var(--ease-mask); }
.in[data-a=photo] { animation-name: a-photo; --dur: 1.9s; animation-timing-function: var(--ease-mask); }
.in[data-a=lines] { animation: none; }

/* Line art traces itself: every <path pathLength="1"> draws from 0 to 1 */
[data-a=trace] path { fill: none; stroke-dasharray: 1; }
.motion [data-a=trace]:not(.in) { opacity: 1; }
.motion [data-a=trace]:not(.in) path { stroke-dashoffset: 1; }
.in[data-a=trace] { animation: none; }
.in[data-a=trace] path { animation: a-trace 2.4s var(--ease-mask) var(--d, 0s) backwards; }
.in[data-a=trace] path + path { animation-delay: calc(var(--d, 0s) + .35s); }
.in[data-a=trace] path + path + path { animation-delay: calc(var(--d, 0s) + 1.1s); animation-duration: 1s; }

/* Images settle from a slight zoom while their mask opens */
.in[data-a=mask] img,
.in[data-a=wipe] > img {
    animation: a-settle 1.9s var(--ease) var(--d, 0s) backwards;
}

/* Split headings: each line rises through its own mask */
.split[data-a=lines] { display: flex; flex-direction: column; }
.ln {
    display: block;
    overflow: hidden;
    padding: .08em .12em .12em;
    margin: -.08em -.12em -.12em;
}
.ln-i { display: block; }
.ln:nth-child(2) .ln-i { --li: 1; }
.ln:nth-child(3) .ln-i { --li: 2; }
.ln:nth-child(4) .ln-i { --li: 3; }
.in[data-a=lines] .ln-i {
    animation: a-line var(--line-dur, 1.1s) var(--ease) calc(var(--d, 0s) + var(--li, 0) * var(--line-step, .11s)) backwards;
}

/* Scenes revealed while already above the viewport skip the animation */
.instant[data-a], .instant .ln-i, .instant img, .instant path { animation: none !important; }

@keyframes a-rise   { from { opacity: 0; translate: 0 26px; } }
@keyframes a-drop   { from { opacity: 0; translate: 0 -14px; } }
@keyframes a-fade   { from { opacity: 0; } }
@keyframes a-pop    { from { opacity: 0; scale: .6; } }
@keyframes a-leaf   { from { opacity: 0; rotate: -14deg; translate: 0 18px; } }
@keyframes a-drawy  { from { scale: 1 0; } }
@keyframes a-line   { from { translate: 0 110%; } }
@keyframes a-settle { from { scale: 1.18; } }
@keyframes a-mask   { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
/* visibility keeps fully-clipped layers from leaving an anti-aliased sliver while they wait */
@keyframes a-wipe   { from { clip-path: inset(0 100% 0 0); visibility: hidden; } to { clip-path: inset(0 0 0 0); } }
@keyframes a-trace  { from { stroke-dashoffset: 1; } }
/* The hero arch rises up through its frame, crown first (same 31 points as .hero-photo's clip) */
@keyframes a-photo {
    from {
        clip-path: polygon(0% 200%, 0% 144%, 0.44% 138.38%, 1.72% 133.18%, 3.74% 128.41%, 6.41% 124.05%, 9.66% 120.08%, 13.38% 116.49%, 17.5% 113.27%, 21.92% 110.41%, 26.57% 107.89%, 31.34% 105.7%, 36.16% 103.83%, 40.93% 102.27%, 45.58% 100.99%, 50% 100%, 54.42% 100.99%, 59.07% 102.27%, 63.84% 103.83%, 68.66% 105.7%, 73.43% 107.89%, 78.08% 110.41%, 82.5% 113.27%, 86.62% 116.49%, 90.34% 120.08%, 93.59% 124.05%, 96.26% 128.41%, 98.28% 133.18%, 99.56% 138.38%, 100% 144%, 100% 200%);
        scale: 1.1;
    }
}
@keyframes a-birds  { from { opacity: 0; translate: 16px 10px; } }
@keyframes a-drift  { 0%, 100% { translate: 0 0; } 50% { translate: -10px -6px; } }

/* --------------------------------------------------------------------------
   2. Shared interaction details
   -------------------------------------------------------------------------- */
:focus-visible { outline: 2px solid var(--wine); outline-offset: 3px; }
.dark :focus-visible,
.register :focus-visible { outline-color: #e6c39d; }

.skip {
    position: fixed; top: 12px; left: 16px; z-index: 100;
    padding: 10px 16px; border-radius: 40px;
    background: var(--wine); color: #fff8ef; font-size: 11px;
    translate: 0 -160%; transition: translate .3s var(--ease);
}
.skip:focus { translate: 0 0; }

/* Directional arrows nudge toward where they point */
.arr { display: inline-block; transition: transform .45s var(--ease); }
a:hover .arr, a:focus-visible .arr, button:hover .arr, button:focus-visible .arr { transform: translateX(4px); }
a:hover .arr.ne, a:focus-visible .arr.ne { transform: translate(3px, -3px); }
#prev:hover .arr, #prev:focus-visible .arr { transform: translateX(-4px); }

/* Buttons: a darker fill sweeps in from the left */
.btn {
    position: relative; overflow: hidden; isolation: isolate;
    transition: transform .45s var(--ease), box-shadow .45s var(--ease);
}
.btn::before {
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
    background: #591917;
    transform: scaleX(0); transform-origin: right;
    transition: transform .6s var(--ease);
}
.btn:hover, .btn:focus-visible { transform: translateY(-2px); box-shadow: 0 12px 22px -14px rgba(89, 25, 23, .75); }
.btn:hover::before, .btn:focus-visible::before { transform: scaleX(1); transform-origin: left; }
.cream::before { background: var(--paper); }
.textlink { transition: color .3s; }

/* --------------------------------------------------------------------------
   3. Header & navigation
   -------------------------------------------------------------------------- */
.header {
    transition: height .5s var(--ease), background-color .5s, box-shadow .5s;
}
.header.is-compact {
    height: 64px;
    background-color: rgba(247, 240, 229, .96);
    -webkit-backdrop-filter: saturate(1.2) blur(10px);
    backdrop-filter: saturate(1.2) blur(10px);
    box-shadow: 0 1px 0 rgba(216, 200, 180, .9);
}
nav a { position: relative; padding: 4px 0; transition: color .3s; }
nav a::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
    background: currentColor;
    transform: scaleX(0); transform-origin: right;
    transition: transform .5s var(--ease);
}
nav a:hover::after, nav a:focus-visible::after, nav a[aria-current]::after { transform: scaleX(1); transform-origin: left; }
nav a[aria-current] { color: var(--wine); }

.burger { position: relative; display: inline-block; width: 16px; height: 9px; margin-left: 9px; vertical-align: -1px; }
.burger::before, .burger::after {
    content: ""; position: absolute; left: 0; right: 0; height: 1.5px; background: currentColor;
    transition: transform .45s var(--ease);
}
.burger::before { top: 0; }
.burger::after { bottom: 0; }
.menu[aria-expanded=true] .burger::before { transform: translateY(3.75px) rotate(45deg); }
.menu[aria-expanded=true] .burger::after { transform: translateY(-3.75px) rotate(-45deg); }
.menu { cursor: pointer; }

/* --------------------------------------------------------------------------
   4. Hero
   -------------------------------------------------------------------------- */
.hero { isolation: isolate; --line-dur: .8s; --line-step: .12s; }
/* Hero runs on a tighter clock than the rest of the page: the CTA is usable within a second */
.hero .in[data-a=rise] { --dur: .8s; }
.hero .in[data-a=arch] { --dur: 1.2s; }
.hero .in[data-a=photo] { --dur: 1.3s; }
.hero .in[data-a=draw] { --dur: 1.6s; }

/* Gateway framed in a four-centred Mughal arch, echoing its own openings */
.heroart .hero-photo {
    clip-path: polygon(0% 100%, 0% 44%, 0.44% 38.38%, 1.72% 33.18%, 3.74% 28.41%, 6.41% 24.05%, 9.66% 20.08%, 13.38% 16.49%, 17.5% 13.27%, 21.92% 10.41%, 26.57% 7.89%, 31.34% 5.7%, 36.16% 3.83%, 40.93% 2.27%, 45.58% 0.99%, 50% 0%, 54.42% 0.99%, 59.07% 2.27%, 63.84% 3.83%, 68.66% 5.7%, 73.43% 7.89%, 78.08% 10.41%, 82.5% 13.27%, 86.62% 16.49%, 90.34% 20.08%, 93.59% 24.05%, 96.26% 28.41%, 98.28% 33.18%, 99.56% 38.38%, 100% 44%, 100% 100%);
}
.herocopy { transform: translate3d(0, var(--cy, 0px), 0); opacity: var(--co, 1); }
.heroart [data-depth], .brush {
    transform: translate3d(var(--px, 0px), var(--py, 0px), 0);
}
.heroart .hero-photo { z-index: 2; transform: translate3d(var(--px, 0px), var(--py, 0px), 0) scale(var(--ps, 1)); transform-origin: 50% 100%; }
.brush { transform: translate3d(var(--px, 0px), var(--py, 0px), 0) rotate(-3deg); }

.hero-line, .hero-moon, .hero-birds { position: absolute; height: auto; object-fit: contain; pointer-events: none; }
/* Line art: brightened so its ivory paper drops out under multiply, edges feathered */
.hero-line {
    left: -15%; top: 16%; width: 30%; z-index: 1; opacity: .85;
    mix-blend-mode: multiply; filter: brightness(1.07) contrast(1.15);
    -webkit-mask-image: radial-gradient(closest-side, #000 70%, transparent);
    mask-image: radial-gradient(closest-side, #000 70%, transparent);
}
/* Moon sits in the photograph's evening sky; screen blend lets it glow */
.hero-moon {
    top: 24%; right: 14%; width: 8%; max-width: 56px; aspect-ratio: 1; object-fit: cover;
    border-radius: 50%; z-index: 3; mix-blend-mode: screen; opacity: .5;
    box-shadow: 0 0 26px 4px rgba(255, 236, 214, .35);
}
/* The flock continues up and out of the frame */
.hero-birds { top: -4%; left: 10%; width: 24%; z-index: 3; opacity: .7; mix-blend-mode: multiply; }
.caption { z-index: 4; }

.in.hero-birds {
    animation: a-birds 1.8s var(--ease) var(--d, 0s) backwards,
               a-drift 16s ease-in-out calc(var(--d, 0s) + 1.8s) infinite;
}
.hero.off .hero-birds { animation-play-state: paused; }

/* --------------------------------------------------------------------------
   5. Painted edges — a dry-brush edge is laid left-to-right where the page
      enters a colour band (hero → navy About, gallery → burgundy Register).
      Lives at the bottom of the preceding section, coloured like the next.
   -------------------------------------------------------------------------- */
.edge {
    position: absolute; left: 0; bottom: -1px; z-index: 5;
    width: 100%; height: 56px; pointer-events: none;
}
.edge-navy { color: var(--navy); }
.edge-wine { color: var(--wine); }
.edge use { fill: currentColor; }
.in.edge { --dur: 1.6s; }

/* About */
.aboutart { position: relative; }
.aboutpic { position: relative; }
.aboutpic img {
    position: absolute; left: 0; top: -8%; height: 116%;
    transform: translate3d(0, var(--py, 0px), 0);
    transition: scale 1.4s var(--ease);
}
.aboutpic:hover img { scale: 1.04; }
.about-leaf {
    position: absolute; left: -24%; bottom: -10%; z-index: 1;
    width: 34%; max-width: 140px; height: auto; object-fit: contain;
    mix-blend-mode: lighten; opacity: .9; pointer-events: none;
    clip-path: inset(3px); /* trims light edge pixels in the source crop */
    transform-origin: 80% 100%;
}

/* --------------------------------------------------------------------------
   6. Festival highlights — hairline rules draw, cards cascade
   -------------------------------------------------------------------------- */
.cards::before, .cards::after {
    content: ""; position: absolute; left: 0; right: 0; height: 1px; background: var(--line);
    transform-origin: left; transition: transform 1.5s var(--ease-mask);
}
.cards::before { top: 0; }
.cards::after { bottom: 0; transition-delay: .15s; }
.card:not(:last-child)::after {
    content: ""; position: absolute; top: 0; bottom: 0; right: 0; width: 1px; background: var(--line);
    transform-origin: top; transition: transform 1.2s var(--ease-mask) calc(var(--b, 0s) + .35s);
}
.motion .cards:not(.in)::before, .motion .cards:not(.in)::after { transform: scaleX(0); }
.motion .card:not(.in)::after { transform: scaleY(0); }

.card {
    transition: background-color .6s var(--ease), transform .6s var(--ease), box-shadow .6s var(--ease);
}
.card:hover, .card:focus-within {
    transform: translateY(-5px);
    box-shadow: 0 22px 34px -28px rgba(70, 30, 22, .55);
}
.card::before {
    content: ""; position: absolute; top: -1px; left: 32%; right: 32%; height: 2px; z-index: 1;
    background: var(--wine); transform: scaleX(0); transition: transform .6s var(--ease);
}
.card:hover, .card:focus-within { background-color: rgba(239, 225, 207, .55); }
.card:hover::before, .card:focus-within::before { transform: scaleX(1); }
.icon { transition: background-color .5s var(--ease), color .5s var(--ease), border-color .5s var(--ease); }
.card:hover .icon, .card:focus-within .icon { background-color: var(--wine); border-color: var(--gold); color: var(--ivory); }
.card > a { transition: transform .45s var(--ease); }
.card:hover > a, .card > a:focus-visible { transform: translate(3px, -3px); }

/* --------------------------------------------------------------------------
   7. Speakers — fixed arch frames, colour returns on hover
   -------------------------------------------------------------------------- */
/* Base 1.03 crops light edge rows present in the source portraits */
.portrait img { scale: 1.03; transition: filter .8s var(--ease), scale 1.2s var(--ease); }
.person h3 { transition: color .4s; }
.person:hover .portrait img { filter: grayscale(0) sepia(.08); scale: 1.08; }
.person:hover h3 { color: var(--wine); }
.speakers .textlink { color: var(--wine); }

/* --------------------------------------------------------------------------
   8. Experience — image wipes open from the text side
   -------------------------------------------------------------------------- */
.experience { position: relative; overflow: hidden; background: var(--ivory); } /* own backdrop for the blended art */
.experiencepic { overflow: hidden; }
.experiencepic img {
    position: absolute; left: 0; top: -6%; height: 112%;
    transform: translate3d(0, var(--py, 0px), 0);
}
.exp-wave, .exp-palm { position: absolute; height: auto; object-fit: contain; mix-blend-mode: multiply; pointer-events: none; }
.exp-wave {
    left: 3%; bottom: 14px; width: min(300px, 32%); opacity: .55;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
    transform: translate3d(var(--px, 0px), 0, 0);
}
.exp-palm {
    top: 34px; left: calc(45% - 92px); width: 58px; opacity: .8; z-index: 2;
    transform: rotate(var(--rot, 0deg)); transform-origin: 50% 100%;
}

/* --------------------------------------------------------------------------
   9. Gallery — scroll-snap carousel
   -------------------------------------------------------------------------- */
.gallerytrack { scroll-behavior: smooth; }
.gallerytrack:focus-visible { outline-offset: 6px; }
.frame { overflow: hidden; }
.frame img { scale: 1.03; transition: scale 1.3s var(--ease), filter .7s; }
.gallery figure:hover .frame img { scale: 1.08; filter: saturate(1); }
figcaption { position: relative; transition: translate .55s var(--ease); }
figcaption::before {
    content: ""; position: absolute; left: -24px; top: 50%; width: 16px; height: 1px;
    background: var(--wine); transform: scaleX(0); transform-origin: left; transition: transform .55s var(--ease);
}
.gallery figure:hover figcaption { translate: 24px 0; }
.gallery figure:hover figcaption::before { transform: scaleX(1); }

.gallery button { transition: background-color .35s, color .35s, opacity .35s, border-color .35s; }
.gallery button:hover:not(:disabled) { background: var(--wine); border-color: var(--wine); color: var(--ivory); }
.gallery button:disabled { opacity: .35; cursor: default; }
.galleryprogress { height: 1px; margin-top: 26px; background: var(--line); overflow: hidden; }
.galleryprogress span {
    display: block; height: 100%; background: var(--wine);
    transform: scaleX(var(--gp, .4)); transform-origin: left;
    transition: transform .4s var(--ease);
}

/* --------------------------------------------------------------------------
   10. Register — painted edge in, then the arch traces around the heading
   -------------------------------------------------------------------------- */
.register { isolation: isolate; }
.register-arch {
    position: absolute; z-index: -1; left: 50%; top: 26px;
    width: min(330px, 78vw); height: auto; translate: -50% 0;
    stroke: #e3bf8e; stroke-width: 1.1; opacity: .55;
    vector-effect: non-scaling-stroke;
    -webkit-mask-image: linear-gradient(#000 52%, transparent 88%);
    mask-image: linear-gradient(#000 52%, transparent 88%);
}
.register-arch path { vector-effect: non-scaling-stroke; }
.register-art {
    position: absolute; inset: -10% 0; z-index: -1; pointer-events: none;
    background: url(../images/cta-bg.jpg) center bottom / cover no-repeat;
    mix-blend-mode: lighten; opacity: .5;
    transform: translate3d(0, var(--py, 0px), 0);
}

/* --------------------------------------------------------------------------
   11. Footer
   -------------------------------------------------------------------------- */
footer { background: var(--ivory); } /* own backdrop for the blended skyline */
.footart {
    display: block; width: min(340px, 70%); height: auto; margin: -10px auto 14px;
    object-fit: contain; mix-blend-mode: multiply; opacity: .75;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.email { transition: border-color .35s, box-shadow .35s; }
.email:focus-within { border-color: var(--wine); box-shadow: 0 0 0 3px rgba(127, 32, 30, .08); }
.email input:focus { outline: none; }
.email button .arr { transition: transform .45s var(--ease), opacity .3s; }
.email.sent { border-color: var(--wine); }
#message.show { animation: a-rise .7s var(--ease) backwards; display: block; }

/* --------------------------------------------------------------------------
   12. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
    .hero-line { left: -10%; width: 28%; }
    .about-leaf { left: -14%; width: 30%; }
    .exp-palm { left: calc(45% - 72px); width: 48px; }
}

@media (max-width: 700px) {
    html { scroll-padding-top: 64px; }
    .header.is-compact { height: 60px; }

    /* Mobile menu panel: unrolls downward, links follow */
    nav {
        clip-path: inset(0 0 100% 0);
        transition: clip-path .55s var(--ease), opacity .35s, visibility 0s linear .55s;
        gap: 4px; font-size: 13px;
    }
    .header nav.open {
        clip-path: inset(0 0 -40px 0);
        transition: clip-path .55s var(--ease), opacity .35s, visibility 0s;
    }
    nav a { padding: 8px 0; align-self: flex-start; transition: color .3s, opacity .4s, translate .5s var(--ease); }
    nav:not(.open) a { opacity: 0; translate: 0 -8px; }
    nav.open a:nth-child(2) { transition-delay: .04s; }
    nav.open a:nth-child(3) { transition-delay: .08s; }
    nav.open a:nth-child(4) { transition-delay: .12s; }
    nav.open a:nth-child(5) { transition-delay: .16s; }

    .hero-line { left: -6%; top: 2%; width: 30%; }
    .hero-moon { width: 9%; }
    .hero-birds { left: 6%; top: -6%; width: 30%; }

    .edge { height: 30px; }
    .register-arch { top: 18px; width: min(260px, 72vw); }
    .aboutart { max-width: 330px; width: 100%; margin: auto; }
    .about-leaf { left: auto; right: -6%; bottom: -8%; width: 90px; }

    .card::after { display: none; }
    .card:hover, .card:focus-within { transform: none; box-shadow: none; } /* stacked cards: tint only */

    .exp-palm { top: 30px; left: auto; right: 8%; }
    .exp-wave { display: none; }
}

/* --------------------------------------------------------------------------
   13. Reduced motion — everything visible, nothing travels
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html, .gallerytrack { scroll-behavior: auto; }
    .motion [data-a]:not(.in) { opacity: 1; }
    [data-a], .ln-i, [data-a] img, [data-a] path { animation: none !important; }
    .motion [data-a=trace] path { stroke-dashoffset: 0; }
    .motion .cards:not(.in)::before, .motion .cards:not(.in)::after, .motion .card:not(.in)::after { transform: none; }
    *, *::before, *::after { transition-duration: .01ms !important; transition-delay: 0s !important; }
}
