/* ============================================================
   Tea Plevneshi — portfolio
   Design tokens
   ============================================================ */
:root {
    /* palette (from Desktop-PORTFOLIO.svg) */
    --navy-950: #05070F;
    --navy-900: #0D1631;
    --navy-800: #14203F;
    --steel-700: #3F5678;
    --steel-500: #6E86A6;
    --steel-300: #A9BCD4;
    --steel-100: #D8E2EE;
    --yellow: #F7FF00;
    --cream: #F4F1E8;
    --white: #FFFFFF;

    /* type */
    --font-display: 'Handjet', monospace;
    --font-body: 'Kufam', system-ui, sans-serif;
    --font-hand: 'Caveat', cursive;

    /* spacing scale */
    --space-1: .5rem;
    --space-2: 1rem;
    --space-3: 1.5rem;
    --space-4: 2.5rem;
    --space-5: 4rem;
    --space-6: 6.5rem;

    --gutter: clamp(1.25rem, 4vw, 4rem);
    --radius-pill: 999px;
    --radius-card: 14px;

    --nav-h: 76px;
    --ease-out: cubic-bezier(.22, .8, .3, 1);

    /* the site is dark by design — declaring it stops Chrome's
       Auto Dark Theme from rewriting the yellows into muddy olives */
    color-scheme: dark;
}

/* ============================================================
   Base
   ============================================================ */
*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

html.lenis {
    height: auto;
    scroll-behavior: auto;
}

.lenis.lenis-smooth {
    scroll-behavior: auto;
}

body {
    width: 100%;
    overflow-x: hidden;
    /* deepest navy, not navy-900: on fast momentum scroll a pinned layer
       can lag a frame and expose the base — at navy-950 that flash is
       indistinguishable from the dark sections instead of a bright blue band */
    background: var(--navy-950);
    color: var(--white);
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

img,
canvas,
svg {
    display: block;
    max-width: 100%;
}

a {
    color: inherit;
}

ul {
    list-style: none;
}

::selection {
    background: var(--yellow);
    color: var(--navy-900);
}

:focus-visible {
    outline: 2px solid var(--yellow);
    outline-offset: 3px;
    border-radius: 4px;
}

.skip-link {
    position: fixed;
    top: -100%;
    left: var(--space-2);
    z-index: 200;
    padding: .6em 1.2em;
    background: var(--yellow);
    color: var(--navy-900);
    font-weight: 600;
    text-decoration: none;
    border-radius: 0 0 8px 8px;
    transition: top .3s var(--ease-out);
}

.skip-link:focus {
    top: 0;
}

/* the page texture lives on a real fixed element, not on
   background-attachment: fixed — mobile browsers ignore/jank that
   attachment, which painted a bare band at every section seam */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    background: var(--navy-900) url('../assets/images/background.webp') center / cover no-repeat;
}

/* subtle film grain over everything */
body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 90;
    pointer-events: none;
    opacity: .05;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ============================================================
   Shared components
   ============================================================ */
.pill-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.pill-list--column {
    flex-direction: column;
    align-items: flex-start;
}

.pill {
    display: inline-block;
    padding: .3em .9em;
    border: 1px solid rgba(255, 255, 255, .85);
    border-radius: var(--radius-pill);
    font-family: var(--font-display);
    font-weight: 500;
    /* desktop floor was ~.85rem — too small next to the display type.
       Scales up with the viewport, capped so it stays a pill not a chip. */
    font-size: clamp(.9rem, 1.05vw, 1.15rem);
    letter-spacing: .06em;
    text-transform: uppercase;
    white-space: nowrap;
    backdrop-filter: blur(3px);
}

.pill--ghost {
    border-color: rgba(255, 255, 255, .5);
    color: var(--steel-100);
}

.btn {
    display: inline-block;
    padding: .6em 1.5em;
    font-family: var(--font-display);
    font-size: clamp(1rem, 1.5vw, 1.25rem);
    font-weight: 600;
    letter-spacing: .03em;
    text-decoration: none;
    border-radius: 4px;
    transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out), background-color .35s, color .35s;
}

.btn:hover {
    transform: translateY(-3px);
}

.btn:active {
    transform: translateY(-1px);
}

.btn--solid {
    background: var(--yellow);
    color: var(--navy-900);
    box-shadow: 0 0 0 rgba(247, 255, 0, 0);
}

.btn--solid:hover {
    box-shadow: 0 8px 30px rgba(247, 255, 0, .35);
}

.btn--ghost {
    border: 2px solid var(--yellow);
    color: var(--yellow);
}

.btn--ghost:hover {
    background: rgba(247, 255, 0, .1);
}

.section-heading {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(2.2rem, 5vw, 4rem);
    letter-spacing: .02em;
    text-transform: uppercase;
}

/* blueprint grid overlay used on sky sections */
.sky-grid {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image:
        linear-gradient(rgba(255, 255, 255, .07) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, .07) 1px, transparent 1px);
    background-size: 100px 100px;
    mask-image: linear-gradient(#000 60%, transparent);
    -webkit-mask-image: linear-gradient(#000 60%, transparent);
}

/* ============================================================
   Preloader
   ============================================================ */
.preloader {
    position: fixed;
    inset: 0;
    z-index: 150;
    display: grid;
    place-content: center;
    gap: var(--space-2);
    /* same texture as the page underneath, so the hand-off reads as a
       curtain lifting rather than one background swapping for another */
    background: var(--navy-900) url('../assets/images/background.webp') center / cover no-repeat;
    overflow: hidden;
    transition: opacity .6s var(--ease-out), visibility .6s;
}

/* blueprint grid, faded toward the edges like the sky sections */
.preloader__grid {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image:
        linear-gradient(rgba(255, 255, 255, .06) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, .06) 1px, transparent 1px);
    background-size: 100px 100px;
    mask-image: radial-gradient(ellipse 75% 65% at 50% 50%, #000 30%, transparent 82%);
    -webkit-mask-image: radial-gradient(ellipse 75% 65% at 50% 50%, #000 30%, transparent 82%);
}

/* the filter-def svg must not take up layout */
.visually-hidden-svg {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

/* fallback path (reduced motion / no filter support) */
.preloader.is-done {
    opacity: 0;
    visibility: hidden;
}

/* the site's cup mark, breathing while it steeps */
.preloader__logo {
    width: 72px;
    margin: 0 auto var(--space-1);
    animation: logoFloat 3.4s ease-in-out infinite;
}

@keyframes logoFloat {

    0%,
    100% {
        transform: translateY(0);
    }

    50% {
        transform: translateY(-7px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .preloader__logo {
        animation: none;
    }
}

.preloader__label {
    font-family: var(--font-display);
    font-size: 1.3rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--steel-300);
    text-align: center;
}

.preloader__pct {
    color: var(--yellow);
    margin-left: .6em;
}

/* thin progress line */
.preloader__bar {
    width: min(60vw, 280px);
    height: 2px;
    margin-inline: auto;
    background: rgba(244, 241, 232, .15);
    border-radius: 1px;
    overflow: hidden;
}

.preloader__bar-fill {
    display: block;
    height: 100%;
    width: 0%;
    background: var(--yellow);
    transition: width .5s var(--ease-out);
}

/* fixed-height slot so the button doesn't shove the layout when it appears */
/* ============================================================
   Nav
   ============================================================ */
/* floating glass pill, centered — same chrome as the case pages */
.nav {
    position: fixed;
    top: .9rem;
    left: 50%;
    translate: -50% 0;
    z-index: 100;
    display: flex;
    align-items: center;
    gap: clamp(2.4rem, 6vw, 4rem);
    padding: .45rem 1.6rem .45rem .7rem;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .12);
    background: rgba(5, 7, 15, .45);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: 0 12px 34px rgba(0, 0, 0, .35);
    transition: transform .45s var(--ease-out), background-color .45s;
}

.nav.is-hidden {
    transform: translateY(-140%);
}

.nav.is-scrolled {
    background: rgba(5, 7, 15, .6);
}

.nav__logo {
    display: grid;
    place-items: center;
}

.nav__logo img {
    width: 42px;
    height: auto;
    /* the global img { max-width: 100% } resolves against this auto-sized
       grid cell and collapses the cup to 0×0 — opt out */
    max-width: none;
    transition: transform .4s var(--ease-out);
}

.nav__logo:hover img {
    transform: rotate(-10deg) translateY(-2px);
}

.nav__links {
    display: flex;
    gap: clamp(1.8rem, 4vw, 3.4rem);
}

.nav__links a {
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 500;
    letter-spacing: .05em;
    text-decoration: none;
    color: var(--steel-100);
    white-space: nowrap;
    transition: color .3s;
}

.nav__links a:hover {
    color: var(--yellow);
}

/* the logo is a mouse target, not a keyboard stop — no ring on click */
.nav__logo:focus:not(:focus-visible) {
    outline: none;
}

/* ============================================================
   Hero — pinned image sequence
   ============================================================ */
.hero {
    position: relative;
}

.hero__viewport {
    position: relative;
    height: 100vh;
    height: 100svh;
    z-index: 5;
    background: transparent;
}

.hero__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: .92;
    -webkit-mask-image: linear-gradient(to bottom, black 0%, black 70%, transparent 100%);
    mask-image: linear-gradient(to bottom, black 0%, black 70%, transparent 100%);
}

.hero__stage {
    position: absolute;
    inset: 0;
    z-index: 2;
    padding: calc(var(--nav-h) + var(--space-4)) var(--gutter) var(--space-4);
    pointer-events: none;
}

.hero__stage>* {
    pointer-events: auto;
}

.hero__tagline {
    max-width: 14ch;
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(2rem, 4.6vw, 3.8rem);
    line-height: 1.1;
    letter-spacing: .02em;
    text-transform: uppercase;
    margin-top: clamp(1rem, 8vh, 6rem);
}

.hero__sub {
    margin-top: 1rem;
    max-width: 34ch;
    font-family: var(--font-body);
    font-size: clamp(1rem, 1.4vw, 1.2rem);
    line-height: 1.55;
    color: var(--steel-100);
}

/* discipline pills: vertical column on the right, clear of the big name */
.hero__disciplines {
    position: absolute;
    right: var(--gutter);
    top: 40%;
    margin: 0;
    max-width: none;
    flex-direction: column;
    align-items: flex-end;
    gap: 1rem;
}

.hero__disciplines .pill {
    font-size: clamp(1rem, 1.35vw, 1.4rem);
    padding: .5em 1.2em;
}

.hero__doodle {
    position: absolute;
    color: var(--yellow);
    font-family: var(--font-hand);
    line-height: 1.1;
    display: flex;
    align-items: flex-start;
    gap: .3rem;
    filter: drop-shadow(0 2px 8px rgba(13, 22, 49, .55));
}

.hero__doodle--me {
    top: 14%;
    right: 9%;
    transform: rotate(-3deg);
}

.doodle-note {
    font-size: clamp(1.5rem, 2.1vw, 2rem);
    font-weight: 600;
    text-align: left;
}

.doodle-note em {
    font-style: normal;
    font-size: .78em;
    opacity: .9;
}

.doodle-arrow {
    order: -1;
    margin-top: 2.2rem;
    margin-right: -0.4rem;
    transform: rotate(8deg);
}

.hero__cup-mini {
    display: none;
}

.hero__name {
    position: absolute;
    bottom: -.14em;
    left: 50%;
    /* centering transform lives in JS (gsap xPercent) — a CSS transform
       here gets wiped by the scale/yPercent tweens and the name shifts
       half its width off screen */
    width: max-content;
    z-index: 2;
    font-family: var(--font-display);
    font-weight: 900;
    font-size: clamp(5.5rem, 18vw, 15.5rem);
    line-height: 1;
    letter-spacing: .05em;
    color: var(--white);
    mix-blend-mode: soft-light;
    white-space: nowrap;
    pointer-events: none;
}

.hero__stage--b {
    opacity: 0;
    visibility: hidden;
}

/* stage B copy: one statement, title-sized, aside tucked under it */
.hero__copy {
    position: absolute;
    top: calc(var(--nav-h) + var(--space-4));
    left: var(--gutter);
    pointer-events: none;
}

.hero__statement {
    max-width: 18ch;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(1.9rem, 3.2vw, 3rem);
    line-height: 1.2;
    letter-spacing: .02em;
    color: var(--white);
}

/* highlighter swipe inside display copy */
.hl-mark {
    background: var(--yellow);
    color: var(--navy-900);
    padding: .02em .18em;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

.hero__aside {
    margin-top: 1rem;
    max-width: 22ch;
    font-family: var(--font-hand);
    font-size: clamp(1.3rem, 2vw, 1.7rem);
    line-height: 1.25;
    color: var(--yellow);
    transform: rotate(-2deg);
    transform-origin: left center;
}

.hero__ctas {
    position: absolute;
    bottom: clamp(8rem, 15vh, 14rem);
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
}

/* ============================================================
   Skyfall — one continuous scene: sky, fall through clouds, water
   ============================================================ */
#skyfall {
    margin-top: -100svh;
}

.skyfall {
    position: relative;
    /* above .works, so the dive panel slides out over the vortex during
       the overlap instead of vanishing behind it */
    z-index: 2;
}

.skyfall__viewport {
    position: relative;
    width: 100vw;
    height: 100vh;
    /* lvh, NOT svh: this box is the backdrop for .dive__content, which is
       position:fixed and therefore spans the LARGE viewport. Sized to svh it
       came up ~one address-bar short on phones, and that strip showed the
       raw page texture as a bright band under the dive callouts. */
    height: 100lvh;
    overflow: hidden;
    /* sky wash over an OPAQUE copy of the page texture. Opacity matters:
       the works section's dark top edge scrolls up behind this pinned
       viewport during the overlap, and a translucent viewport lets that
       edge read as a hard line cutting across the dive. While pinned the
       viewport box equals the screen, so this copy lines up pixel-exact
       with the fixed body::before layer the mask edges dissolve into. */
    background-image: linear-gradient(180deg, rgba(38, 52, 78, .28) 0%, rgba(122, 143, 172, .18) 100%), url('../assets/images/background.webp');
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    /* both edges dissolve: the top against the hero, the bottom against
       the vortex canvas as the panel slides out over it. The stops ride
       CSS vars so the timeline can close the mask once underwater — the
       page texture bleeding through the edges reads as a stray light
       band against the dark water (initSkyfall tweens these to 0%/100%) */
    --mask-top: 15%;
    --mask-btm: 82%;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black var(--mask-top), black var(--mask-btm), transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0%, black var(--mask-top), black var(--mask-btm), transparent 100%);
}

.skyfall__clouds-bg {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    overflow: hidden;
}

/* the water: fades in as the cup splashes down.
   Same gradient as .works so the dive ends exactly where the vortex begins */
.skyfall__water {
    position: absolute;
    inset: 0;
    z-index: 1;
    opacity: 0;
    background: linear-gradient(180deg, rgb(19, 22, 32) 0%, rgba(5, 7, 15, 1) 40%, rgba(5, 7, 15, 1) 100%);
}

/* solid abyss that swallows the water gradient's lighter surface band during
   the exit, so the whole frame matches the .works background (#05070F) by the
   time the pin releases */
.skyfall__abyss {
    position: absolute;
    inset: 0;
    z-index: 1;
    opacity: 0;
    background: rgb(5, 7, 15);
}

.cloud-bg {
    position: absolute;
    object-fit: contain;
    opacity: 0.4;
}

.cloud-bg--1 {
    width: 80%;
    bottom: 20%;
    left: -10%;
    opacity: 0.3;
    animation: floatLeft 30s ease-in-out infinite alternate;
}

.cloud-bg--2 {
    width: 60%;
    top: 10%;
    right: -5%;
    opacity: 0.2;
    animation: floatRight 35s ease-in-out infinite alternate;
}

.cloud-bg--3 {
    width: 90%;
    bottom: -5%;
    right: -20%;
    opacity: 0.4;
    animation: floatLeft 40s ease-in-out infinite alternate-reverse;
}

@keyframes floatLeft {
    from {
        transform: translateX(5%);
    }

    to {
        transform: translateX(-5%);
    }
}

@keyframes floatRight {
    from {
        transform: translateX(-5%);
    }

    to {
        transform: translateX(5%);
    }
}

.skyfall__clouds-fg {
    position: absolute;
    inset: 0;
    z-index: 3;
    /* above background, below annotations (z:4) */
    pointer-events: none;
    overflow: hidden;
}

.cloud-fg {
    position: absolute;
    object-fit: contain;
    opacity: 0.6;
}

.cloud-fg--1 {
    width: 120%;
    bottom: -15%;
    left: -20%;
    opacity: 0.5;
    animation: floatRight 25s ease-in-out infinite alternate;
}

.cloud-fg--2 {
    width: 110%;
    top: 5%;
    right: -10%;
    opacity: 0.4;
    animation: floatLeft 28s ease-in-out infinite alternate;
}

/* overlay: every text layer of the skyfall lives here, FIXED and above
   the WebGL canvas (z 5 > canvas z 2) — the cup passes behind the words */
.skyfall-overlay {
    pointer-events: none;
    /* hidden until the timeline takes over — fixed children would flash
       over the hero on slow loads (initSkyfall reveals it; the
       reduced-motion block below shows it statically) */
    opacity: 0;
}

/* sky phase title — small eyebrow, same voice as "The actual work." */
.skyfall__title {
    position: fixed;
    top: calc(var(--nav-h) + var(--space-2));
    left: var(--gutter);
    z-index: 5;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .9rem;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--steel-300);
    text-shadow: 0 1px 12px rgba(13, 22, 49, .55);
    opacity: 0;
    visibility: hidden;
}

/* "teacup will be your guide" note — sits ABOVE the cup, arrow pointing
   down at it, always on top of the annotation layer */
.skyfall__guide-note {
    position: fixed;
    left: 50%;
    top: 11%;
    translate: -50% 0;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .25rem;
    font-family: var(--font-hand);
    font-size: clamp(1.1rem, 1.5vw, 1.4rem);
    font-weight: 600;
    line-height: 1.15;
    text-align: center;
    color: var(--yellow);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    filter: drop-shadow(0 2px 8px rgba(13, 22, 49, .55));
}

.exploration__annotations {
    position: fixed;
    inset: 0;
    z-index: 5;
    pointer-events: none;
}

.annotation {
    position: absolute;
    width: min(300px, 34vw);
    opacity: 0;
    text-shadow: 0 1px 10px rgba(13, 22, 49, .55);
}

.annotation__line {
    position: absolute;
    width: 130px;
    height: 90px;
    overflow: visible;
}

.annotation__line path {
    fill: none;
    stroke: var(--yellow);
    stroke-width: 2;
    vector-effect: non-scaling-stroke;
}

.annotation__title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.15rem, 1.7vw, 1.5rem);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--yellow);
}

/* bodies read in the normal text font — only titles keep the display face */
.annotation__text {
    margin-top: .4rem;
    font-family: var(--font-body);
    font-weight: 400;
    font-size: clamp(.85rem, 1vw, .95rem);
    line-height: 1.55;
    color: var(--yellow);
    opacity: .92;
}

.annotation--1 {
    top: 25%;
    left: 8%;
}

.annotation--1 .annotation__line {
    right: -140px;
    top: 10px;
}

.annotation--2 {
    top: 22%;
    right: 8%;
    text-align: left;
}

.annotation--2 .annotation__line {
    left: -140px;
    top: 14px;
}

.annotation--3 {
    top: 46%;
    left: 14%;
}

.annotation--3 .annotation__line {
    right: -140px;
    bottom: 10px;
}

.annotation--4 {
    top: 42%;
    right: 10%;
}

.annotation--4 .annotation__line {
    left: -140px;
    bottom: 14px;
}

/* clouds sit ABOVE the WebGL canvas (z 3 > canvas z 2) so the
   falling cup passes behind them; never clipped mid-shape because
   they live inside the full-height pinned viewport */

/* ============================================================
   Dive Text Section
   ============================================================ */
.dive-section {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 70vh;
    background: linear-gradient(180deg, rgba(13, 22, 49, 1) 0%, rgba(5, 7, 15, 1) 40%, rgba(5, 7, 15, 1) 100%);
    padding: var(--space-8) var(--gutter);
    text-align: center;
    z-index: 2;
    /* Ensure it stays above the scrolling skyfall behind it if needed */
}

/* underwater: two annotation beats — "Why choose me." then "Why not." —
   framed around the floating cup exactly like the sky ingredients */
.dive__content {
    position: fixed;
    inset: 0;
    z-index: 5;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

.dive__title {
    position: absolute;
    top: calc(var(--nav-h) + var(--space-2));
    left: var(--gutter);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .9rem;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--steel-300);
    opacity: 0;
    visibility: hidden;
}

.dive-annotations {
    position: absolute;
    inset: 0;
}

/* underwater callouts break from the sky yellow: white titles, grey
   bodies — only the lines stay yellow */
.dive-ann .annotation__title {
    color: var(--white);
}

.dive-ann .annotation__text {
    color: var(--steel-300);
    opacity: 1;
}

/* both beats wear the highlight tape — same voice, two chapters */
.dive__title--fit,
.dive__title--miss {
    background: var(--yellow);
    color: var(--navy-900);
    padding: .25em .7em;
    transform: rotate(-1.5deg);
}

.dive-annotations--miss .annotation__line path {
    stroke: var(--white);
}

.dive-annotations--miss .annotation__title {
    color: var(--yellow);
}

.dive-ann--f1 {
    top: 22%;
    left: 8%;
}

.dive-ann--f1 .annotation__line {
    right: -140px;
    top: 10px;
}

.dive-ann--f2 {
    top: 19%;
    right: 8%;
}

.dive-ann--f2 .annotation__line {
    left: -140px;
    top: 14px;
}

.dive-ann--f3 {
    top: 50%;
    left: 13%;
}

.dive-ann--f3 .annotation__line {
    right: -140px;
    bottom: 10px;
}

.dive-ann--f4 {
    top: 42%;
    right: 10%;
}

.dive-ann--f4 .annotation__line {
    left: -140px;
    bottom: 14px;
}

.dive-ann--m1 {
    top: 21%;
    right: 8%;
}

.dive-ann--m1 .annotation__line {
    left: -140px;
    top: 14px;
}

.dive-ann--m2 {
    top: 24%;
    left: 8%;
}

.dive-ann--m2 .annotation__line {
    right: -140px;
    top: 10px;
}

/* "scared of teacups" sits UNDER the left column, "logo and a flyer"
   takes the right — mirrors the pairing on the fit beat */
.dive-ann--m3 {
    top: 52%;
    left: 13%;
}

.dive-ann--m3 .annotation__line {
    right: -140px;
    bottom: 10px;
}

.dive-ann--m4 {
    top: 50%;
    right: 11%;
}

.dive-ann--m4 .annotation__line {
    left: -140px;
    bottom: 14px;
}

/* ============================================================
   Works — vortex
   ============================================================ */
.works {
    position: relative;
    /* overlap the skyfall's unpin tail: the vortex starts the moment the
       dive's pin releases, and the dive panel slides out over it */
    margin-top: -100svh;
    /* keep background.webp texture but restore underwater darkness;
       starts at the same value the dive's water gradient ends on (.88)
       so there is no visible seam between the two sections */
    /* eases in from the dive's water value instead of slamming to 1 —
       kills the visible line where the vortex begins */
    background: linear-gradient(180deg, rgba(5, 7, 15, .88) 0, rgba(5, 7, 15, 1) 45vh, rgba(5, 7, 15, 1) 100%);
}

/* soft apron above the section: the skyfall viewport fades out at the
   end of its pin, and any leftover spacer-tail between the two sections
   would flash the raw page texture as a bright band. This dissolves that
   strip into the vortex dark with no hard edge on either side. */
.works::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -35vh;
    height: 35vh;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(5, 7, 15, 0) 0%, rgba(5, 7, 15, .88) 100%);
}

/* small fixed label, top-left, shown while the vortex is on screen */
.works__eyebrow {
    position: fixed;
    top: calc(var(--nav-h) + var(--space-2));
    left: var(--gutter);
    z-index: 5;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .9rem;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--steel-300);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

.works__step {
    /* scroll distance per card — shorter than a full viewport so one
       deliberate wheel push actually reaches the next card */
    height: 80vh;
}

.works__hud {
    position: fixed;
    left: var(--gutter);
    bottom: clamp(2rem, 8vh, 5rem);
    z-index: 5;
    max-width: 320px;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

.works__hud.is-active {
    pointer-events: auto;
}

.works__counter {
    font-family: var(--font-display);
    font-size: 1.1rem;
    letter-spacing: .2em;
    color: var(--steel-500);
}

.works__counter span {
    color: var(--yellow);
}

.works__title {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: clamp(2.4rem, 5vw, 3.6rem);
    line-height: 1;
    letter-spacing: .02em;
    text-transform: uppercase;
    margin-top: .3rem;
}

.works__meta {
    color: var(--steel-300);
    margin-top: .35rem;
    font-size: .95rem;
}

.works__open {
    margin-top: var(--space-3);
}

/* ============================================================
   Contact form — glass card on the sea floor
   ============================================================ */
.contact-form {
    position: relative;   /* anchors the sent-state overlay */
    width: min(560px, 100%);
    margin-top: var(--space-2);
    padding: clamp(1.2rem, 2.6vw, 1.75rem);
    display: grid;
    gap: .75rem;
    text-align: left;
    border-radius: 18px;
    /* proper glass: translucent wash + heavy blur, faint top light edge */
    background: linear-gradient(160deg, rgba(169, 188, 212, .10), rgba(13, 22, 49, .35));
    border: 1px solid rgba(216, 226, 238, .28);
    backdrop-filter: blur(22px) saturate(1.35);
    -webkit-backdrop-filter: blur(22px) saturate(1.35);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 30px 70px rgba(0, 0, 0, .45);
}

.contact-form__row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

.contact-form label {
    display: grid;
    gap: .35rem;
    font-family: var(--font-display);
    font-size: .85rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--steel-300);
}

.contact-form input,
.contact-form textarea {
    font-family: var(--font-body);
    font-size: 1rem;
    color: var(--white);
    background: rgba(5, 7, 15, .55);
    border: 1px solid rgba(169, 188, 212, .25);
    border-radius: 10px;
    padding: .7rem .9rem;
    resize: vertical;
    transition: border-color .3s;
}

.contact-form input::placeholder,
.contact-form textarea::placeholder {
    color: var(--steel-700);
}

.contact-form input:hover,
.contact-form textarea:hover {
    border-color: rgba(169, 188, 212, .5);
}

.contact-form input:focus-visible,
.contact-form textarea:focus-visible {
    outline: 2px solid var(--yellow);
    outline-offset: 1px;
}

.contact-form .btn {
    justify-self: center;
    /* breathing room from the message box */
    margin-top: .55rem;
    border: 0;
    cursor: pointer;
    font-family: var(--font-display);
}

/* Sent state. The fields keep their space (visibility, not display) and the
   confirmation lays over them, so the card is the exact same height before
   and after sending — a reflow here would move the pinned section under
   ScrollTrigger's cached measurements and break the snap. */
.contact-form.is-sent .contact-form__row,
.contact-form.is-sent > label,
.contact-form.is-sent button[type="submit"],
.contact-form.is-sent .contact-form__status {
    visibility: hidden;
}

/* must out-specify the display:grid below — a bare [hidden] only carries
   the UA sheet's display:none and loses to any author display rule */
.contact-form__done[hidden] {
    display: none;
}

.contact-form__done {
    position: absolute;
    inset: 0;
    display: grid;
    align-content: center;
    justify-items: center;
    gap: .4rem;
    text-align: center;
    color: var(--yellow);
}

.contact-form__done .steam {
    animation: steamRise 1.8s ease-in-out infinite;
    opacity: 0;
}

.contact-form__done .steam--2 {
    animation-delay: .6s;
}

@keyframes steamRise {
    0% { opacity: 0; transform: translateY(3px); }
    35% { opacity: 1; }
    100% { opacity: 0; transform: translateY(-4px); }
}

.contact-form__done-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.8rem, 3vw, 2.4rem);
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--white);
}

.contact-form__done-sub {
    font-family: var(--font-hand);
    font-size: clamp(1.25rem, 1.8vw, 1.55rem);
    color: var(--yellow);
}

.contact-form__done .btn {
    margin-top: 1rem;
    border: 2px solid var(--yellow);
}

.contact-form .btn:disabled {
    opacity: .6;
    cursor: wait;
}

/* honeypot: invisible to humans, irresistible to bots */
.contact-form__honey {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.contact-form__status {
    margin: 0;
    min-height: 1.4em;
    text-align: center;
    font-size: .95rem;
    color: var(--steel-300);
}

.contact-form__status.is-ok {
    color: var(--yellow);
}

.contact-form__status.is-error {
    color: #f0857d;
}

@media (max-width: 560px) {
    .contact-form__row {
        grid-template-columns: 1fr;
    }
}

/* the locked card's button: present, but clearly not a door */
.works__open.is-locked {
    cursor: not-allowed;
    opacity: .55;
    filter: saturate(.4);
}

.works__open.is-locked::before {
    content: '🔒 ';
}

.works__list {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ============================================================
   Contact — sea floor
   ============================================================ */
.contact {
    position: relative;
    z-index: 3;
    /* exactly one screen — at 130vh the section spilled into a second
       viewport and the scroll snap had two places to settle */
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    overflow: hidden;
    /* opens SOLID at the vortex's exact colour and only then clears to
       the sea floor — the canvas edge and the cards can never show
       through as a hard line */
    background: linear-gradient(180deg,
            #05070F 0%,
            rgba(5, 7, 15, .96) 14%,
            rgba(13, 22, 49, .25) 42%,
            rgba(5, 7, 15, .93) 78%);
}

/* case pages reuse the same section, but there is no vortex canvas behind
   it — paint the deep water in so the gradient's clear middle doesn't
   read as the page background showing through */
.case .contact {
    background-color: #05070F;
}

/* a soft lip at the bottom of the vortex, ABOVE the canvas (z 2 < 3):
   bubbles and cards dissolve into dark before the contact line instead
   of being cut by it */
.works::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 85vh;
    z-index: 3;
    pointer-events: none;
    background: linear-gradient(180deg,
            rgba(5, 7, 15, 0) 0%,
            rgba(5, 7, 15, .35) 40%,
            rgba(5, 7, 15, .8) 70%,
            #05070F 95%);
}

/* drifting sand: two grain layers sliding at different speeds over the
   floor — CSS approximation of stirred sediment */
.sand-drift {
    position: absolute;
    left: -10%;
    right: -10%;
    bottom: 0;
    height: 45%;
    pointer-events: none;
    opacity: .5;
    background-image:
        radial-gradient(2px 2px at 12% 78%, rgba(213, 202, 191, .8), transparent 60%),
        radial-gradient(1.5px 1.5px at 34% 62%, rgba(213, 202, 191, .55), transparent 60%),
        radial-gradient(2.5px 2.5px at 57% 84%, rgba(190, 180, 168, .6), transparent 60%),
        radial-gradient(1.5px 1.5px at 72% 70%, rgba(213, 202, 191, .5), transparent 60%),
        radial-gradient(2px 2px at 88% 80%, rgba(190, 180, 168, .7), transparent 60%),
        radial-gradient(1px 1px at 45% 92%, rgba(230, 222, 210, .6), transparent 60%);
    background-size: 340px 260px;
    -webkit-mask-image: linear-gradient(to top, #000 30%, transparent 100%);
    mask-image: linear-gradient(to top, #000 30%, transparent 100%);
    animation: sandDrift 26s linear infinite;
}

.sand-drift--far {
    height: 30%;
    opacity: .3;
    background-size: 220px 180px;
    animation-duration: 44s;
    animation-direction: reverse;
}

@keyframes sandDrift {
    from { background-position: 0 0; }
    to   { background-position: 340px -18px; }
}

@media (prefers-reduced-motion: reduce) {
    .sand-drift { animation: none; }
}

.contact__inner {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* tight rhythm: the whole sea-floor beat has to land in one screen */
    gap: var(--space-2);
    text-align: center;
    padding: var(--space-5) var(--gutter) var(--space-3);
}

.contact__eyebrow {
    font-family: var(--font-display);
    font-size: 1.15rem;
    letter-spacing: .25em;
    text-transform: uppercase;
    color: var(--steel-500);
}

.contact__heading {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: clamp(2.6rem, 6vw, 4.75rem);
    line-height: .95;
    letter-spacing: .01em;
    text-transform: uppercase;
}

/* whispered kettle line under the heading — highlighter swipe on the text */
.contact__kettle {
    display: flex;
    align-items: center;
    gap: .6rem;
    font-family: var(--font-hand);
    font-size: clamp(1.35rem, 2vw, 1.7rem);
    font-weight: 600;
    color: var(--steel-500);
    transform: rotate(-1.5deg);
}

.contact__kettle span {
    background: var(--yellow);
    color: var(--navy-900);
    padding: .05em .5em .12em;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

.contact__kettle svg {
    opacity: .75;
    flex: none;
}

.contact__email {
    font-family: var(--font-display);
    font-size: clamp(1.4rem, 3vw, 2.1rem);
    color: var(--yellow);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    transition: border-color .3s;
}

.contact__email:hover {
    border-color: var(--yellow);
}

.contact__socials {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
    margin-top: var(--space-2);
}

.contact__socials a {
    display: flex;
    align-items: center;
    gap: .55rem;
    font-family: var(--font-display);
    font-size: 1.15rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--steel-300);
    text-decoration: none;
    transition: color .3s;
}

.contact__socials a:hover {
    color: var(--yellow);
}

.social-badge {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border: 1.5px solid currentColor;
    border-radius: 9px;
    font-size: .95rem;
    font-weight: 700;
    text-transform: lowercase;
}

.footer {
    position: relative;
    z-index: 2;
    padding: var(--space-3) var(--gutter);
    text-align: center;
    color: var(--steel-700);
    font-size: .85rem;
}

/* algae */
.algae {
    position: absolute;
    inset: 0;
    color: #0A1128;
    pointer-events: none;
}

.algae__plant {
    position: absolute;
    bottom: -12px;
    width: clamp(30px, 4vw, 56px);
    height: auto;
    transform-origin: bottom center;
    animation: sway 7s ease-in-out infinite alternate;
    opacity: .85;
}

.algae__plant--1 {
    left: 6%;
    height: 34vh;
    animation-duration: 8s;
}

.algae__plant--2 {
    left: 15%;
    height: 22vh;
    animation-duration: 6.4s;
    animation-delay: -2s;
}

.algae__plant--3 {
    right: 12%;
    height: 30vh;
    animation-duration: 7.2s;
    animation-delay: -4s;
}

.algae__plant--4 {
    right: 4%;
    height: 19vh;
    animation-duration: 5.8s;
    animation-delay: -1s;
}

@keyframes sway {
    from {
        transform: rotate(-6deg) skewX(-3deg);
    }

    to {
        transform: rotate(6deg) skewX(3deg);
    }
}

/* ============================================================
   WebGL canvas
   ============================================================ */
#webgl-canvas {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    z-index: 2;
    pointer-events: none;
    opacity: 0;
    transition: opacity .5s var(--ease-out);
}

#webgl-canvas.is-visible {
    opacity: 1;
}

/* the contact section pulls the whole GL layer to transparent —
   declared after .is-visible so it wins while both classes are on */
#webgl-canvas.is-dimmed {
    opacity: 0;
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 900px) {
    .annotation {
        width: min(240px, 42vw);
    }

    .annotation--1 {
        left: 5%;
    }

    .annotation--2 {
        right: 5%;
    }

    .annotation--3 {
        top: 50%;
        left: 6%;
    }

    .annotation--4 {
        top: 47%;
        right: 4%;
    }

    .annotation__line {
        display: none;
    }

    /* the dive corners were positioned for three callouts a side; at four
       they collide on short/landscape tablets, so both beats stack into a
       single bottom-anchored column and let the cup have the space above */
    .dive-annotations {
        position: absolute;
        inset: auto var(--gutter) 12% var(--gutter);
        display: flex;
        flex-direction: column;
    }

    .dive-ann {
        position: static;
        width: 100%;
        margin-bottom: var(--space-3);
    }

    .hero__stage--b {
        flex-direction: column;
        align-items: flex-start;
        justify-content: center;
    }

    .hero__stage-b-right {
        max-width: 100%;
    }
}

@media (max-width: 640px) {
    :root {
        --nav-h: 62px;
    }

    .nav {
        gap: 1rem;
        padding-right: .8rem;
    }

    .nav__links {
        gap: 1rem;
    }

    .nav__links a {
        font-size: 1.05rem;
    }

    /* cover-crop centres the frame; the face sits right-of-centre, so
       centred crop cuts it off. Bias the crop toward the right side of
       the footage so the face lands in view on portrait screens. */
    .hero__canvas {
        object-position: 68% center;
    }

    .hero__doodle--me {
        top: 13%;
        right: 4%;
    }

    .doodle-note {
        font-size: 1.35rem;
    }

    .hero__tagline {
        margin-top: 2vh;
    }

    /* the film stays full-bleed (cover) — the pills drop back to a
       horizontal strip above the name, so the face stays clear */
    .hero__disciplines {
        top: auto;
        left: var(--gutter);
        right: var(--gutter);
        bottom: 7.5rem;
        flex-direction: row;
        align-items: center;
    }

    .hero__name {
        /* sized so all 13 glyphs of Handjet span ~87vw — the old clamp
           floor overflowed the screen and cropped the name to
           "EA PLEVNESH" */
        font-size: 18vw;
    }

    .pill {
        font-size: 1rem;
        padding: .5em 1.2em;
    }

    .annotation {
        position: static;
        width: 100%;
        opacity: 1;
        margin-bottom: var(--space-2);
    }

    /* phones: titles-only, anchored under the section title — the full
       bodies + the cup could never share one small screen */
    .exploration__annotations {
        position: fixed;
        inset: calc(var(--nav-h) + 3.4rem) var(--gutter) auto var(--gutter);
        display: flex;
        flex-direction: column;
    }

    .exploration__annotations .annotation__text {
        display: none;
    }

    .works__hud {
        left: var(--gutter);
        right: var(--gutter);
        max-width: none;
        bottom: 1.5rem;
    }

    /* phones: the dive callouts read as a plain list — separator rows,
       titles only, and a caret that drops the note open on tap
       (initDiveAccordion toggles .is-open) */
    .dive-ann {
        position: relative;
        /* the desktop corner offsets (left/right per callout) would apply
           as relative shifts — neutralise them so rows stack flush */
        inset: auto;
        margin: 0;
        padding: .6em 1.6em .6em 0;
        border-bottom: 1px solid rgba(244, 241, 232, .18);
        pointer-events: auto;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
    }

    .dive-ann::after {
        content: '';
        position: absolute;
        right: .35em;
        top: 1em;
        width: .45em;
        height: .45em;
        border-right: 2px solid var(--yellow);
        border-bottom: 2px solid var(--yellow);
        transform: rotate(45deg);
        transition: transform .3s var(--ease-out);
    }

    .dive-ann.is-open::after {
        transform: rotate(225deg);
        top: 1.25em;
    }

    .dive-ann .annotation__text {
        display: block;
        max-height: 0;
        margin: 0;
        overflow: hidden;
        opacity: 0;
        transition: max-height .35s var(--ease-out), opacity .3s, margin .3s;
    }

    .dive-ann.is-open .annotation__text {
        max-height: 8em;
        margin-top: .4em;
        opacity: 1;
    }

    /* shorter vortex ride on phones: less thumb travel per card */
    .works__step {
        height: 65vh;
    }

    .hero__sub {
        font-size: .95rem;
        max-width: 30ch;
    }

    .skyfall__guide-note {
        top: 42%;
        font-size: 1.05rem;
    }
}

/* ============================================================
   Reduced motion
   ============================================================ */
@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }

    html {
        scroll-behavior: auto;
    }

    .hero__stage--b {
        opacity: 1;
        visibility: visible;
    }

    .annotation {
        opacity: 1;
    }

    .skyfall__title,
    .skyfall__guide-note,
    .dive__title {
        opacity: 1;
        visibility: visible;
        position: static;
    }

    .exploration__annotations {
        position: static;
    }

    .skyfall-overlay {
        opacity: 1;
    }

    .dive__content {
        position: static;
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        padding-top: var(--space-5);
    }

    .dive-annotations {
        position: static;
    }

    .dive-ann {
        position: static;
        margin: var(--space-3) var(--gutter);
    }

    .skyfall__water {
        opacity: 1;
    }

    #webgl-canvas {
        display: none;
    }

    .works__hud {
        opacity: 1;
        visibility: visible;
        position: static;
        margin: var(--space-4) var(--gutter);
    }

    .works__eyebrow {
        position: static;
        opacity: 1;
        visibility: visible;
        margin: var(--space-4) var(--gutter) 0;
    }

    .works__step {
        display: none;
    }

    .works__list {
        position: static;
        width: auto;
        height: auto;
        clip-path: none;
        white-space: normal;
        padding: var(--space-4) var(--gutter) var(--space-6);
    }

    .works__list a {
        display: block;
        padding: var(--space-3);
        margin-bottom: var(--space-2);
        border: 1px solid var(--steel-700);
        border-radius: var(--radius-card);
        font-family: var(--font-display);
        font-size: 1.3rem;
        text-decoration: none;
    }
}