/* Home page: the illustrated hero (with its intro animation) on top, then the
   Work and About sections in the shared page grid from styles.css. The hero
   keeps its own display fonts; everything below it uses the site's sans. */

/* ---------- Hero ---------- */

/* The leaves sit at a negative z-index, under the page's in-flow content; a
   transparent body lets them show through (<html> keeps the white). */
body {
    background-color: transparent;
}

/* The lotus leaves floating around the hero (moved by /js/index.js). */
.leaf {
    z-index: -50;
    position: absolute;
    background-image: url('../assets/images/main/lotus-leaf.svg');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    cursor: pointer;
    transform-origin: center center;
}

/* The page below the hero covers any leaf the parallax carries down. */
.hero + .page {
    position: relative;
    z-index: 1;
    background-color: var(--color-background);
}

.hero {
    position: relative;
    text-align: center;
    height: 85vh;
    margin-top: 24vh;
}

.hero-image {
    width: 250px;
    z-index: 100;
    background-color: var(--color-primary);
}

.hero-title-container {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    justify-content: center;
    gap: 10px;
    margin-bottom: 10px;
}

.hero-title-icon {
    height: 81px;
}

/* top is a fixed px offset (not a % of .hero's 100vh) anchored to the fixed-size
   hero-image below it, so the callout's position stays correct at every viewport
   height instead of drifting relative to the CAROL title under short/tall vh. */
.hero-side {
    position: absolute;
    top: 154px;
    left: calc(50% - 175px - 150px);
    align-items: left;
    justify-content: left;
    text-align: left;
    gap: 10px;
    padding: 0;
    padding-left: 10px;
    border-left: 4px solid var(--color-primary);
    width: 150px;
}

.hero-side-right {
    position: absolute;
    top: 350px;
    left: calc(50% + 140px);
    display: flex;
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
    text-align: left;
    padding-left: 10px;
    width: 200px;
}

.hero-side-right > a {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

.hero-side-right p {
    margin: 0;
    font-size: 16px;
    position: relative;
    display: inline-block;
}

/* Underline draws left to right under the label. */
.hero-side-right p::after {
    content: '';
    position: absolute;
    left: 0;
    top: calc(100% + 1px);
    width: 100%;
    height: 2.5px;
    background-color: currentColor;
    pointer-events: none;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.hero-side-right > a:hover p::after,
.hero-side-right > a:focus-visible p::after {
    transform: scaleX(1);
}

.hero-side-image {
    width: 16px;
    height: 16px;
    object-fit: contain;
    flex-shrink: 0;
}

.hero-side-title {
    color: var(--color-background);
    background-color: var(--color-foreground);
    padding: 5px 10px;
    margin: 0;
    margin-bottom: 10px;
    width: auto;
    display: inline-block;
    flex: 0 0 auto;
    align-self: flex-start;
}

.hero-title {
    font-size: 64px;
    font-family: 'GajrajOne', sans-serif;
    margin: 0;
    margin-top: -20px;
    margin-bottom: -25px;
    color: var(--color-foreground);
}

.hero-side-description {
    line-height: 1.3;
}

.parallax-leaves {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 110vh;
}

.hero-fish-icon {
    position: absolute;
    top: 14%;
    left: 38%;
    z-index: 200;
    display: block;
    /* How far above the image's centre the intro swim starts. */
    --intro-fish-rise: 70px;
    /* The settled tilt, leaning the way it swam. Kept here rather than only in
       the keyframes so it holds once the intro classes come off, and as its own
       property so the keyframes animate it without a transform to fight over. */
    rotate: -10deg;
}

.leaf-1 {
    width: 200px;
    height: 200px;
    top: 41%;
    left: 31%;
}

.leaf-2 {
    width: 100px;
    height: 100px;
    /* background-image: url('/assets/images/main/lotus-leaf-2.svg'); */
    background-image: none;
    background-color: var(--color-green-secondary);
    border-radius: 50%;
    top: 45%;
    left: 22%;
}

.leaf-3 {
    width: 68px;
    height: 68px;
    top: 40%;
    left: 26%;
}

.leaf-4 {
    width: 70px;
    height: 70px;
    top: 31%;
    right: 19%;
    background-image: url('../assets/images/main/lotus-leaf-2.svg');
}

.leaf-5 {
    width: 95px;
    height: 95px;
    top: 23%;
    right: 21%;
}

.leaf-6 {
    width: 70px;
    height: 70px;
    top: 0%;
    left: 12%;
}


/* The header is in the page flow now (sticky), so the hero's 24vh drop is
   measured from below it, landing the hero where it sat under the old
   transparent header. */
.hero {
    margin-top: calc(24vh - var(--header-height));
    margin-bottom: -4vh;
}

/* The hero's own type: the display faces, not the site's sans. */
.hero-title {
    font-weight: 400;
    line-height: normal;
    letter-spacing: 0;
}

.hero p {
    font-family: 'Gabarito', sans-serif;
    font-size: 16px;
    line-height: 1.2;
}

@media (max-width: 720px) {
    .hero {
        height: 55vh;
        margin-top: 18vh;
        margin-bottom: 18vh;
    }

    .hero-title {
        font-size: 36px;
    }

    .hero-title-icon {
        height: 45px;
    }

    .hero-image {
        width: 180px;
    }

    .hero-side {
        position: static;
        margin: 40px auto 20px;
        width: 90%;
        max-width: 300px;
        border-left: none;
        padding-left: 0;
        text-align: center;
    }

    .hero-side-right {
        display: none;
    }

    .hero-side-title {
        display: none;
    }

    .hero-title-carol {
        margin-top: 0px;
    }

    .hero-title-container {
        align-items: center;
    }

    .parallax-leaves {
        display: block;
        height: 70vh;
    }

    .hero-fish-icon {
        left: 30%;
    }

    .leaf-1 { top: 44%; left: -15%; }
    .leaf-2 { display: none; }
    .leaf-3 { display: none; }
    .leaf-4 { top: 30%; right: -4%; left: auto; }
    .leaf-5 { display: none; }
    .leaf-6 { display: none; }

    /* One screenful under the sticky header, content centred. */
    .hero {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: auto;
        min-height: calc(100vh - var(--header-height));
        min-height: calc(100dvh - var(--header-height));
        margin: 0;
    }

    .parallax-leaves {
        overflow: hidden;
        height: 100%;
    }

    /* Decorative positions tuned to the full-screen phone hero. */
    .hero-fish-icon {
        top: 26%;
        left: 13%;
    }

    .leaf-1 { top: 50%; left: -15%; }
    .leaf-4 { top: 40%; right: -4%; left: auto; }
}

@media (max-width: 480px) {
    .hero-title {
        font-size: 36px;
    }

    .hero-title-carol {
        margin-top: 0px;
    }

    .hero-side {
        margin-top: 40px;
    }

    .hero-side-title {
        display: none;
    }

    .hero-title-icon {
        height: 45px;
    }

    .hero-image {
        width: 180px;
    }
}

/* ---------------------------------------------------------------------------
   Hero intro. `html.intro` is set by index.vue while the loader is up; with
   `intro-paused` every piece holds on its first keyframe (fill-mode both), and
   the loader lifting removes it so the sequence plays: the loader's mark flips
   into the hero image and grows into place, and everything else slides out from
   behind it.

   Each piece starts stacked on the image's centre — index.vue measures that
   offset into --intro-from-x/y per element, so the travel is exact at any
   viewport size. Only the standalone `translate` / `scale` properties are
   animated, so nothing fights the inline `transform` that index.js and GSAP
   write on these elements.
   --------------------------------------------------------------------------- */
html.intro .site-header,
html.intro .hero-image,
html.intro .hero-title-container,
html.intro .hero-title-carol,
html.intro .hero .leaf,
html.intro .hero-fish-icon,
html.intro .hero-side,
html.intro .hero-side-right > a {
    animation-fill-mode: both;
    animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}

html.intro-paused .site-header,
html.intro-paused .hero-image,
html.intro-paused .hero-title-container,
html.intro-paused .hero-title-carol,
html.intro-paused .hero .leaf,
html.intro-paused .hero-fish-icon,
html.intro-paused .hero-side,
html.intro-paused .hero-side-right > a {
    animation-play-state: paused;
}

/* One synchronous frame with the intro suppressed, so index.vue can measure
   each piece where it actually lands rather than where the animation parks it. */
html.intro-measuring .site-header,
html.intro-measuring .hero-image,
html.intro-measuring .hero-title-container,
html.intro-measuring .hero-title-carol,
html.intro-measuring .hero .leaf,
html.intro-measuring .hero-fish-icon,
html.intro-measuring .hero-side,
html.intro-measuring .hero-side-right > a {
    animation: none !important;
}

/* The image has to cover what is sliding out from under it. The leaves already
   sit at z-index -50; the titles and side notes are lifted just enough to stay
   below it and above the page. */
html.intro .hero-image {
    position: relative;
    z-index: 60;
}

html.intro .hero-title-container,
html.intro .hero-title-carol {
    position: relative;
    z-index: 1;
}

html.intro .hero-side,
html.intro .hero-side-right {
    z-index: 1;
}

/* The sequence runs a piece at a time, each step overlapping the tail of the
   one before, with two deliberate pairings: the header comes out with YU / HF,
   and the four tags arrive together.
   Timeline (ms from the loader lifting):
     0     image grows from the loader's mark   (900, played by IntroLoader.vue)
     450   YU / HF slides up and the header drops (450)
     550   the leaves drift in from the right edge alongside the words, the
           top-left one first (1050), the rest 100 apart from 700 (1200 each)
     750   CAROL slides down                   (450)
     600   the fish appears over the image as it lands, above its centre, and
           swims out to the left (1000)
     1550  Hello note slides left, once every leaf is on its way (420)
     1800  the four tags slide right out from behind the image, together (420)
   Shifting one step means shifting the delays under it; INTRO_DURATION in
   index.vue is what takes the classes off at the end, so keep it past the last
   piece. */
/* The loader flips its mark into a stand-in of this image and grows it onto
   this exact box, so the real image just stays hidden until the stand-in lands
   (GROW_DURATION in IntroLoader.vue) and then takes over. */
html.intro .hero-image {
    animation-name: intro-image-hold;
    animation-duration: 900ms;
    animation-timing-function: steps(1, end);
}

html.intro .hero-title-container {
    animation-name: intro-emerge;
    animation-duration: 450ms;
    animation-delay: 450ms;
}

/* One-shot swim, out of the image's centre and up to the left. It sets off
   while the image is still settling (GROW_DURATION in IntroLoader.vue is 900),
   held hidden by the 0% keyframe until then; fill-mode both then holds the last frame until the intro classes come off
   and the CSS top/left take over. */
html.intro .hero-fish-icon {
    z-index: 200;
    animation-name: intro-fish-emerge;
    animation-duration: 1000ms;
    animation-delay: 600ms;
    animation-iteration-count: 1;
    animation-fill-mode: both;
}

html.intro .hero-title-carol {
    animation-name: intro-emerge;
    animation-duration: 450ms;
    animation-delay: 750ms;
}

html.intro .hero-side {
    animation-name: intro-emerge;
    animation-duration: 420ms;
    animation-delay: 1550ms;
}

/* The four tags arrive as one block rather than in turn, sliding straight out
   to the right from behind the image (no scale, no vertical travel). */
html.intro .hero-side-right > a {
    animation-name: intro-slide-out;
    animation-duration: 420ms;
    animation-delay: 1800ms;
}

/* Drops in with the first words (YU / HF) rather than waiting for the notes. */
html.intro .site-header {
    animation-name: intro-header-drop;
    animation-duration: 450ms;
    animation-delay: 450ms;
}

/* The leaves come from off the right edge instead of from behind the image,
   drifting across like something on a river: a long, near-even glide that only
   settles at the end, each one setting off after the one before it. */
html.intro .hero .leaf {
    animation-name: intro-drift-in;
    animation-duration: 1200ms;
    animation-timing-function: cubic-bezier(0.18, 0.62, 0.3, 1);
}

/* The leaves set off with the words rather than after them. The top-left one
   (leaf-6) has the farthest to travel, so it leaves first and a little quicker;
   the rest follow close behind. */
html.intro .hero .leaf-6 { animation-delay: 550ms; animation-duration: 1050ms; }
html.intro .hero .leaf-1 { animation-delay: 700ms; }
html.intro .hero .leaf-3 { animation-delay: 800ms; }
html.intro .hero .leaf-2 { animation-delay: 900ms; }
html.intro .hero .leaf-5 { animation-delay: 1000ms; }
html.intro .hero .leaf-4 { animation-delay: 1100ms; }

@keyframes intro-image-hold {
    0% { opacity: 0; }
    100% { opacity: 1; }
}

@keyframes intro-emerge {
    0% {
        opacity: 0;
        translate: var(--intro-from-x, 0px) var(--intro-from-y, 0px);
        scale: var(--intro-from-scale, 0.6);
    }
    16% { opacity: 1; }
    100% {
        opacity: 1;
        translate: 0 0;
        scale: 1;
    }
}

@keyframes intro-slide-out {
    0% {
        opacity: 0;
        translate: var(--intro-from-x, 0px) 0;
    }
    10% { opacity: 1; }
    100% {
        opacity: 1;
        translate: 0 0;
    }
}

/* Starts hidden just above the image's centre (measured into --intro-from-x/y,
   lifted by --intro-fish-rise), shows itself there, then swims out to its rest
   position once, tilting left as it goes. No scale: the fish keeps its size the
   whole way. The fade is short so it is already on its way as it appears. */
@keyframes intro-fish-emerge {
    0% {
        opacity: 0;
        translate: var(--intro-from-x, 0px) calc(var(--intro-from-y, 0px) - var(--intro-fish-rise));
        rotate: 30deg;
    }
    18% {
        opacity: 1;
    }
    100% {
        opacity: 1;
        translate: 0 0;
        rotate: -10deg;
    }
}

/* No fade and no scale: a leaf carried in on the water arrives at full size,
   righting itself from its tilt as it slows into place. `rotate` is its own
   property here, so it stacks onto the parallax rotation index.js writes into
   `transform` rather than replacing it. */
@keyframes intro-drift-in {
    0% {
        translate: var(--intro-from-x, 0px) var(--intro-from-y, 0px);
        rotate: var(--intro-from-tilt, 0deg);
    }
    100% {
        translate: 0 0;
        rotate: 0deg;
    }
}

@keyframes intro-header-drop {
    0% { opacity: 0; translate: 0 -100%; }
    100% { opacity: 1; translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
    html.intro .site-header,
    html.intro .hero-image,
    html.intro .hero-title-container,
    html.intro .hero-title-carol,
    html.intro .hero .leaf,
    html.intro .hero-fish-icon,
    html.intro .hero-side,
    html.intro .hero-side-right > a {
        animation-name: intro-fade;
        animation-duration: 400ms;
        animation-delay: 0ms;
    }

    @keyframes intro-fade {
        from { opacity: 0; }
        to { opacity: 1; }
    }
}


/* ---------- Work and About ---------- */

.home-about-body {
    display: grid;
    grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
    gap: 48px;
    align-items: start;
}

.home-about-figure {
    margin: 0;
}

.home-about-figure img {
    display: block;
    width: 100%;
    height: auto;
}

.home-about-text {
    display: flex;
    flex-direction: column;
    gap: 20px;
    max-width: 640px;
}

.home-about-text .button-row {
    margin-top: 8px;
}

@media (max-width: 720px) {
    .home-about-body {
        grid-template-columns: 1fr;
        gap: 24px;
    }
}
