/* =========================================================================
   KLIMA — Fashion Archive
   Contemporary editorial · Swiss-inspired asymmetric grid · adaptive ground
   ========================================================================= */

/* ---- Tokens ------------------------------------------------------------ */
:root {
    --c-bg:        #D9DEE1; /* soft grey blue */
    --c-fog:       #E6E8E7; /* light fog */
    --c-ink:       #252B2E; /* gunmetal */
    --c-graphite:  #151819;
    --c-muted:     #AAB5BD; /* muted blue grey */
    --c-warm:      #C9C7C2; /* warm grey */

    /* Live, JS-driven ground + text (transition between projects). */
    --bg: var(--c-bg);
    --fg: var(--c-ink);

    --pad: 28px;
    --gutter: 12px;
    --header-h: 72px;

    /* KLIMA motion system: one unhurried, liquid curve for every entrance,
       reveal and page change. The wave is the expressive layer; everything
       else simply follows its calm momentum. */
    --ease: cubic-bezier(0.65, 0, 0.18, 1);
    --reveal-dur: 1s;

    --fs-nav: 12px;
    --fs-caption: 12px;
    --fs-meta: 11px;
}

/* ---- Reset ------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
html, body { height: 100%; }

body {
    font-family: "Inter Tight", "Helvetica Neue", Arial, sans-serif;
    font-weight: 400;
    color: var(--fg);
    background: var(--bg);
    transition: background-color 0.8s var(--ease), color 0.8s var(--ease);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    line-height: 1.45;
    overflow-x: clip; /* clip (not hidden) so body never becomes a scroll container — keeps IntersectionObserver reveals working */
}
html { overflow-x: clip; }

img { display: block; max-width: 100%; }
/* <picture> is only a format-picker wrapper — it must not affect layout. */
picture { display: contents; }

/* Idle word — appears while the sheets fall to the floor, hides on wake. */
.field-idle-word {
    position: fixed; left: 50%; top: 38%; transform: translate(-50%, -50%) translateY(14px);
    z-index: 400; pointer-events: none;
    font-size: clamp(34px, 7vw, 92px); font-weight: 500;
    letter-spacing: 0.22em; text-transform: uppercase;
    white-space: nowrap;               /* always a single line */
    color: var(--fg); opacity: 0;
    transition: opacity 1.1s var(--ease) 0.45s, transform 1.1s var(--ease) 0.45s;
}
@media (max-width: 768px) {
    .field-idle-word { font-size: clamp(22px, 8.5vw, 34px); letter-spacing: 0.18em; }
}
.field-idle-word.is-on { opacity: 0.2; transform: translate(-50%, -50%); }

/* Living WebGL ground — fixed behind all content, non-interactive. */
.webgl-bg {
    position: fixed; inset: 0; width: 100%; height: 100%;
    z-index: -1; display: block; pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { .webgl-bg { display: none; } }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul { list-style: none; }

/* ---- Utilities --------------------------------------------------------- */
.visually-hidden, .skip-link {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link:focus {
    position: fixed; top: 12px; left: 12px; width: auto; height: auto;
    clip: auto; margin: 0; padding: 10px 16px; background: var(--fg); color: var(--bg);
    z-index: 1000; font-size: var(--fs-meta); letter-spacing: 0.08em;
}

:focus-visible { outline: 1.5px solid var(--fg); outline-offset: 3px; }

/* ---- Header (transparent, always visible) ----------------------------- */
.site-header {
    position: fixed; inset: 0 0 auto 0; z-index: 900;
    height: var(--header-h);
    display: flex; align-items: center;
    padding: 0 var(--pad);
    background: transparent;
    color: #fff;                 /* base for the blend */
    mix-blend-mode: difference;  /* stays legible over fog or photo */
}
.site-header__inner {
    width: 100%;
    display: flex; align-items: center; justify-content: space-between;
}
.brand {
    font-size: 15px; font-weight: 500;
    letter-spacing: 0.22em; text-transform: none;
}
/* Inline nav at the top → collapses to MENU+ once scrolled (Dash-style). */
.site-header__nav { position: relative; display: flex; align-items: center; }
.nav-inline { display: flex; gap: 26px; transition: opacity 0.5s var(--ease); }
.nav-inline__link {
    font-size: var(--fs-nav); letter-spacing: 0.14em; text-transform: uppercase;
    position: relative; padding-bottom: 2px; opacity: 0.85; transition: opacity 0.4s var(--ease);
}
.nav-inline__link::after {
    content: ""; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px;
    background: currentColor; transform: scaleX(0); transform-origin: left; transition: transform 0.5s var(--ease);
}
.nav-inline__link:hover { opacity: 1; }
.nav-inline__link:hover::after, .nav-inline__link.is-active::after { transform: scaleX(1); }
.nav-inline__link.is-active { opacity: 1; }

.menu-toggle {
    position: absolute; right: 0; top: 50%; transform: translateY(-50%);
    display: inline-flex; align-items: baseline; gap: 3px;
    font-size: var(--fs-nav); letter-spacing: 0.16em; text-transform: uppercase;
    opacity: 0; pointer-events: none; transition: opacity 0.5s var(--ease);
}
/* Scrolled: nav collapses to MENU+. Clicking MENU+ adds .nav-open which
   expands the SAME inline nav back in place — no fullscreen overlay. Any
   further scroll re-collapses it (see headerScroll). */
.site-header.is-scrolled .nav-inline { opacity: 0; pointer-events: none; }
.site-header.is-scrolled .menu-toggle { opacity: 1; pointer-events: auto; }
.site-header.is-scrolled.nav-open .nav-inline { opacity: 1; pointer-events: auto; }
.site-header.is-scrolled.nav-open .menu-toggle { opacity: 0; pointer-events: none; }
.menu-toggle__sign {
    display: inline-block; transition: transform 0.5s var(--ease);
    font-size: 1.05em;
}
.menu-toggle:hover .menu-toggle__sign { transform: rotate(90deg); }

/* Full-screen menu is mobile-only; hidden on desktop (inline nav is used). */
.klima-menu { display: none; }

/* ---- Preloader --------------------------------------------------------- */
/* ---- Page transition: a quiet tonal crossfade ------------------------ */
.page-transition {
    position: fixed; inset: 0;
    z-index: 1150; pointer-events: none; /* above the mobile menu (1100) so the
                                            curtain sweeps over it when navigating */
    background: #14181a;
    transform: translateY(0);   /* new documents arrive covered; JS lifts it */
    will-change: transform;
}
/* Soft liquid caps beyond both edges — the curtain leads with a crest as it
   rises over the old page and trails one as it lifts off the new page. */
.page-transition::before,
.page-transition::after {
    content: ""; position: absolute; left: -6%; right: -6%; height: 11vh;
    background: inherit;
}
.page-transition::before { bottom: calc(100% - 1px); border-radius: 50% 50% 0 0 / 100% 100% 0 0; }
.page-transition::after  { top: calc(100% - 1px);  border-radius: 0 0 50% 50% / 0 0 100% 100%; }
.page-transition__wave { display: none; }
/* The destination page name rides the curtain — centred, fading in as the ink
   covers and lifting away with it. It moves with the panel's transform. */
.page-transition__word {
    display: block; position: fixed; left: 0; right: 0; top: 50%;
    transform: translateY(-50%);
    text-align: center; color: #E6E8E7;
    font-size: clamp(30px, 6.4vw, 82px); font-weight: 500;
    letter-spacing: 0.005em; line-height: 1;
    opacity: 0; transition: opacity 0.55s var(--ease);
    pointer-events: none; z-index: 1001;
}
.page-transition.is-word .page-transition__word { opacity: 0.96; }

/* Content breathes with the curtain: dims as it falls, fades in as it lifts. */
main { transition: opacity 0.7s var(--ease); }
body.page-leave main { opacity: 0.4; }
body.page-enter main { opacity: 0 !important; transition: none !important; }

/* Reduced motion: a plain, quick crossfade instead of the curtain. */
@media (prefers-reduced-motion: reduce) {
    .page-transition {
        background: #14181a; opacity: 0; transform: none !important;
        transition: opacity 0.2s ease;
    }
    .page-transition::before, .page-transition::after { display: none; }
    .page-transition.is-cover { opacity: 1; }
    main { transition: none; }
}

.preloader {
    position: fixed; inset: 0; z-index: 1200;
    background: #0E1214;
    color: #E6E8E7;
    overflow: hidden;
    transition: transform 1.1s var(--ease), opacity 0.55s var(--ease) 0.2s;
    will-change: transform, opacity;
    backface-visibility: hidden;
}
.preloader.is-done { transform: translateY(-101%); opacity: 0; }
/* Already seen this session → never render the preloader again (no flash on
   internal navigation; set before paint by the inline head script). */
html.klima-preloaded .preloader { display: none !important; }

/* Bottom row: wordmark bottom-left, counter bottom-right — same size, same
   baseline, sitting right above the thick progress bar. */
.preloader__row {
    position: absolute; left: var(--pad); right: var(--pad); bottom: calc(var(--pad) + 6px);
    display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;
    font-size: clamp(40px, 9vw, 128px);
    font-weight: 600; letter-spacing: -0.01em; line-height: 0.92;
}
/* The wordmark fills like water from below: a dim base word with a bright copy
   on top, clipped by a JS-driven wave path (crest rises with load progress). */
.preloader__brand { position: relative; display: inline-block; white-space: nowrap; }
.preloader__brand-base { color: rgba(230, 232, 231, 0.14); }
.preloader__brand-fill {
    position: absolute; left: 0; top: 0;
    color: #E6E8E7;
    clip-path: inset(100% 0 0 0);
    will-change: clip-path;
}
.preloader__count {
    color: #E6E8E7;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.preloader__progress {
    position: absolute; right: 0; bottom: 0; left: 0; height: 6px; overflow: hidden;
    background: rgba(230, 232, 231, 0.14);
}
.preloader__progress span {
    display: block; width: 100%; height: 100%; transform: scaleX(0); transform-origin: left center;
    background: #E6E8E7; will-change: transform;
}
@media (max-width: 700px) {
    .preloader__row { font-size: clamp(30px, 9.6vw, 60px); gap: 12px; bottom: calc(var(--pad) + 8px); }
}
body.is-loading { overflow: hidden; }

/* ---- Custom cursor ----------------------------------------------------- */
.cursor {
    position: fixed; top: 0; left: 0; z-index: 900;
    width: 62px; height: 62px; border-radius: 50%;
    display: grid; place-items: center; pointer-events: none;
    background: var(--fg); color: var(--bg);
    transform: translate(-50%, -50%) scale(0);
    transition: transform 0.4s var(--ease), background-color 0.6s var(--ease), color 0.6s var(--ease);
    mix-blend-mode: normal;
}
.cursor.is-active { transform: translate(-50%, -50%) scale(1); }
.cursor__label { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; }
@media (hover: none), (pointer: coarse) { .cursor { display: none; } }

/* ---- Reveal (overflow mask via inner image transform) -----------------
   The mask lives on an inner transform, never on the observed element itself,
   so IntersectionObserver always sees a full-size box (a clipped-to-zero box
   would never report as intersecting and would never reveal). */
[data-reveal] { overflow: hidden; }
[data-reveal] .klima-img { --reveal-y: 101%; }
[data-reveal].is-in .klima-img { --reveal-y: 0%; }

[data-reveal-item] {
    opacity: 0; transform: translateY(14px);
    transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
[data-reveal-item].is-in { opacity: 1; transform: none; }
[data-scroll-text].is-in {
    opacity: var(--scroll-opacity, 1);
    transform: translateY(var(--scroll-y, 0));
    transition: opacity 0.45s linear, transform 0.7s var(--ease);
}

/* Single composed transform: reveal slide + parallax + hover scale. */
.klima-img {
    width: 100%; height: 100%; object-fit: cover;
    --reveal-y: 0%; --par-y: 0px; --img-scale: 1.04;
    transform: translateY(calc(var(--reveal-y) + var(--par-y))) scale(var(--img-scale));
    transition: transform var(--reveal-dur) var(--ease);
    will-change: transform;
}

/* ======================================================================
   INDEX — curated archive grid
   ====================================================================== */
.index {
    padding-top: calc(var(--header-h) + 6vh);
    padding-bottom: 8vh;
}
.index__grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 6vh var(--gutter);
    padding: 0 var(--pad);
    align-items: start;
}

.work {
    grid-column: var(--col-start) / span var(--col-span);
    margin-top: var(--shift);
    display: block;
}
/* Differential scroll parallax runs on desktop only — promote layers there. */
@media (hover: hover) and (min-width: 769px) {
    .work, .closing { will-change: transform; }
}
.work__frame {
    display: block; position: relative; overflow: hidden;
    aspect-ratio: var(--ratio);
    background: color-mix(in srgb, var(--fg) 8%, transparent);
}
.work:hover .work__frame .klima-img { --img-scale: 1.065; }

.work__caption {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; margin-top: 12px;
    font-size: var(--fs-caption); letter-spacing: 0.08em; text-transform: uppercase;
    opacity: 0; transform: translateY(8px);
    transition: opacity 0.7s var(--ease) 0.15s, transform 0.7s var(--ease) 0.15s;
}
.work.is-in .work__caption { opacity: 0.9; transform: none; }
.work:hover .work__caption { opacity: 1; }
.work__title { font-weight: 400; }
.work__count { opacity: 0.6; font-variant-numeric: tabular-nums; }

/* Closing full-bleed campaign */
.closing {
    display: block; margin-top: 12vh;
    padding: 0 var(--pad);
}
.closing__frame {
    display: block; overflow: hidden; aspect-ratio: 16 / 9;
    background: color-mix(in srgb, var(--fg) 8%, transparent);
}
.closing:hover .closing__frame .klima-img { --img-scale: 1.06; }
.closing__caption {
    display: flex; justify-content: space-between; margin-top: 14px;
    font-size: var(--fs-caption); letter-spacing: 0.08em; text-transform: uppercase;
}
.closing__caption .work__count { opacity: 0.6; }

/* ======================================================================
   INDEX — works suspended in the air (floating field, no titles)
   ====================================================================== */
.field-page { overflow: clip; }
.field { position: relative; width: 100%; }

.card {
    position: absolute;
    left: var(--x); top: var(--y); width: var(--w);
    /* scroll drift (--px/--py) + user drag (--dragx/--dragy) + spin + resize scale */
    transform: translate3d(calc(var(--px, 0px) + var(--dragx, 0px)),
                           calc(var(--py, 0px) + var(--dragy, 0px)), 0)
               rotate(calc(var(--rot, 0deg) + var(--rz, 0deg) + var(--rotu, 0deg)))
               scale(var(--rescale, 1));
    will-change: transform;
    /* depth → nearer sheets sit clearer, far ones recede into air.
       NO filter here: a blur on 66 cards whose children animate forced the
       GPU to re-filter every sheet every frame — the main cause of jank. */
    opacity: calc(0.55 + var(--depth, 1) * 0.45);
    touch-action: none;   /* let a finger drag the sheet instead of scrolling */
    cursor: grab;
    -webkit-user-select: none; user-select: none;
}
.card.is-dragging { cursor: grabbing; }
.card.is-dragging .card__inner { animation-play-state: paused; } /* hold the float while held */
.card img { -webkit-user-drag: none; user-drag: none; pointer-events: none; }
/* The image inside a sheet does not need its own compositor layer (the card
   and its floating inner already have one each) — fewer layers, less VRAM. */
.card .klima-img { will-change: auto; }
/* Sheets far outside the viewport drop out of compositing entirely. */
.card.is-far { visibility: hidden; }
/* Resize handle — grab the bottom-right corner to scale the sheet. */
.card__handle {
    position: absolute; right: -2px; bottom: -2px; width: 30px; height: 30px;
    cursor: nwse-resize; touch-action: none; z-index: 3;
    opacity: 0; transition: opacity 0.35s var(--ease);
}
.card__handle::after {
    content: ""; position: absolute; right: 7px; bottom: 7px; width: 12px; height: 12px;
    border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
    color: var(--fg);
}
.card:hover .card__handle, .card.is-resizing .card__handle { opacity: 0.7; }
.card__inner {
    display: block;
    /* the "paper in the air" idle float — desynced per card */
    animation: klima-float var(--fd, 12s) ease-in-out var(--fdelay, 0s) infinite;
    will-change: transform;
}
.card__frame {
    display: block; overflow: hidden;
    background: color-mix(in srgb, var(--fg) 8%, transparent);
    box-shadow: 0 40px 80px -48px rgba(21, 24, 25, 0.5); /* soft lift off the ground */
}
.card:hover .klima-img { --img-scale: 1.06; }

@keyframes klima-float {
    0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
    50%  { transform: translate3d(var(--fx, 6px), calc(var(--fy, 10px) * -1), 0) rotate(var(--fr, 1.5deg)); }
    100% { transform: translate3d(0, 0, 0) rotate(0deg); }
}
@media (prefers-reduced-motion: reduce) {
    .card__inner { animation: none; }
}

/* ======================================================================
   SINGLE PROJECT
   ====================================================================== */
.project { padding-top: calc(var(--header-h) + 12vh); }

.project__intro {
    padding: 0 var(--pad);
    max-width: 780px;
    margin-bottom: 10vh;
}
.project__title {
    font-size: clamp(30px, 5vw, 64px); font-weight: 400;
    letter-spacing: 0.02em; line-height: 1.0; text-transform: uppercase;
}
.project__meta {
    margin-top: 14px; font-size: var(--fs-meta); letter-spacing: 0.14em;
    text-transform: uppercase; opacity: 0.75;
}
.project__count { opacity: 0.6; }
.project__credits {
    margin-top: 40px;
    display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 18px 32px;
}
.project__credit dt {
    font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.5;
    margin-bottom: 4px;
}
.project__credit dd {
    font-size: var(--fs-nav); letter-spacing: 0.06em; text-transform: uppercase;
}

.project__gallery {
    display: grid; grid-template-columns: repeat(12, 1fr);
    gap: var(--gutter); padding: 0 var(--pad);
    align-items: start;
}
.shot { overflow: hidden; background: color-mix(in srgb, var(--fg) 8%, transparent); }
.shot--col  { grid-column: span 6; }
.shot--wide { grid-column: span 8; }
.shot--full { grid-column: 1 / -1; }
.project__gallery .shot:not(:nth-child(-n+2)) { margin-top: 2vh; }

.next-project {
    display: flex; flex-direction: column; gap: 10px;
    padding: 16vh var(--pad) 12vh;
    align-items: center; text-align: center;
}
.next-project__label { font-size: var(--fs-meta); letter-spacing: 0.2em; text-transform: uppercase; opacity: 0.55; }
.next-project__name {
    font-size: clamp(28px, 5vw, 60px); font-weight: 400; letter-spacing: 0.02em; text-transform: uppercase;
}
.next-project:hover .next-project__name span { display: inline-block; transform: translateX(8px); transition: transform 0.5s var(--ease); }

/* ======================================================================
   INFO
   ====================================================================== */
.info { padding-top: calc(var(--header-h) + 10vh); padding-bottom: 12vh; }
.info__grid {
    display: grid; grid-template-columns: minmax(0, 42%) minmax(0, 1fr);
    gap: 8%; padding: 0 var(--pad); align-items: start;
}
/* Sticky editorial image sequence. No shadow/border/decoration — just the
   frame. Photos are stacked; JS reveals the active one with a fabric/liquid
   wave clip-mask. */
.info__portrait {
    position: sticky; top: calc(var(--header-h) + 3vh); align-self: start;
    overflow: hidden; aspect-ratio: 2 / 3;
    background: color-mix(in srgb, var(--fg) 10%, transparent);
}
.info__shots { position: absolute; inset: 0; }
.info__shot {
    position: absolute; inset: 0; margin: 0; opacity: 0;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
    will-change: -webkit-mask-image, mask-image;
}
.info__shot[data-index="0"] { opacity: 1; } /* first shown pre-JS */
.info__img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    transform: scale(var(--imscale, 1));
    will-change: transform;
}
/* Counter + thin progress line — editorial image metadata, no box. */
.info__meta {
    position: absolute; left: 20px; bottom: 18px; z-index: 30;
    display: flex; align-items: center; gap: 12px;
    color: #fff; mix-blend-mode: difference; pointer-events: none;
}
.info__count { font-size: 11px; letter-spacing: 0.14em; font-variant-numeric: tabular-nums; }
.info__bar { position: relative; width: 46px; height: 1px; background: rgba(255, 255, 255, 0.32); }
.info__bar-fill { position: absolute; inset: 0 auto 0 0; width: 20%; background: #fff; transition: width 0.6s var(--ease); }
@media (prefers-reduced-motion: reduce) {
    .info__shot { -webkit-mask-image: none !important; mask-image: none !important; }
    .info__img { transform: none !important; }
}
.info__body { max-width: 520px; padding-top: 4vh; }
.info__block { margin-bottom: 44px; }
.info__lead { font-size: clamp(19px, 2.4vw, 26px); line-height: 1.35; letter-spacing: 0.005em; }
.info__based { margin-top: 18px; font-size: var(--fs-nav); letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.7; }
.info__label { font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; opacity: 0.5; margin-bottom: 16px; font-weight: 500; }
.info__para { font-size: clamp(15px, 1.15vw, 17px); line-height: 1.6; opacity: 0.82; }
.info__para + .info__para { margin-top: 15px; }
.info__list li {
    font-size: 14px; letter-spacing: 0.04em; text-transform: uppercase;
    padding: 7px 0; border-bottom: 1px solid color-mix(in srgb, var(--fg) 14%, transparent);
}
.info__list--muted li { opacity: 0.8; }
/* Service rows drive the image on hover/focus — dim the others slightly,
   keep the separator lines (opacity lives on the inner span, not the row). */
.info__list li[data-img] { cursor: pointer; outline: none; }
.info__list li[data-img] span { display: inline-block; transition: opacity 0.45s var(--ease); }
.info__list:hover li[data-img] span { opacity: 0.5; }
.info__list li[data-img]:hover span,
.info__list li[data-img]:focus-visible span { opacity: 1; }
.info__list li[data-img]:focus-visible { text-underline-offset: 3px; }
.info__contact a { position: relative; }
.info__contact a::after {
    content: ""; position: absolute; left: 0; bottom: 6px; width: 100%; height: 1px;
    background: currentColor; transform: scaleX(0); transform-origin: left; transition: transform 0.5s var(--ease);
}
.info__contact a:hover::after { transform: scaleX(1); }
.info__avail { opacity: 0.55; }
.info__book {
    display: inline-flex; gap: 10px; margin-top: 12px;
    font-size: var(--fs-nav); letter-spacing: 0.14em; text-transform: uppercase;
    padding-bottom: 3px; border-bottom: 1px solid currentColor;
}
.info__book span { transition: transform 0.5s var(--ease); }
.info__book:hover span { transform: translateX(6px); }

/* Information page — sparse editorial directory layout. */
@media (min-width: 769px) {
    .info { min-height: 100svh; padding-top: calc(var(--header-h) + 4vh); padding-bottom: 4vh; }
    .info__grid {
        grid-template-columns: repeat(12, minmax(0, 1fr));
        grid-template-rows: minmax(280px, 39vh) auto;
        gap: 6vh var(--gutter); align-items: start;
    }
    .info__body { display: contents; }
    .info__portrait {
        grid-column: 9 / span 2; grid-row: 1; position: relative; top: auto;
        width: 100%; max-width: 225px; justify-self: start; margin-top: 1vh;
        aspect-ratio: 2 / 3;
    }
    .info__block { margin: 0; max-width: none; }
    .info__block--lead { grid-column: 1 / span 7; grid-row: 1; align-self: start; }
    .info__block--about { grid-column: 1 / span 4; grid-row: 2; }
    /* Right-side directory: contact and services form one column; selected
       clients remains a separate, uninterrupted column beside it. Nudged one
       column right so the whole right cluster sits tighter to the edge. */
    .info__block--contact { grid-column: 9 / span 2; grid-row: 2; }
    .info__block--services { grid-column: 9 / span 2; grid-row: 2; align-self: start; margin-top: 168px; }
    .info__block--clients { grid-column: 11 / span 2; grid-row: 2 / span 2; }
    .info__book { display: none; }
    .info__lead { font-size: clamp(31px, 3vw, 52px); line-height: 0.98; letter-spacing: -0.045em; }
    .info__based { margin-top: 22px; }
    .info__para { font-size: 13px; line-height: 1.28; }
    .info__para + .info__para { margin-top: 9px; }
    .info__label { margin-bottom: 11px; }
    .info__list li {
        font-size: 12px; line-height: 1.18; letter-spacing: 0.015em;
        padding: 4px 0; border: 0; overflow-wrap: anywhere;
    }
    .info__meta { left: 12px; bottom: 12px; }
    .info__meta { display: none; }
}

/* ======================================================================
   BOOK
   ====================================================================== */
.book { padding-top: calc(var(--header-h) + 8vh); padding-bottom: 9vh; }
.book__grid { padding: 0 var(--pad); max-width: 860px; margin: 0 auto; }
.book__intro { margin-bottom: 6vh; }
.book__title { font-size: clamp(30px, 5vw, 60px); font-weight: 400; letter-spacing: 0.02em; text-transform: uppercase; }
.book__note { margin-top: 14px; font-size: 14px; opacity: 0.7; max-width: 40ch; }

.book__form { display: grid; grid-template-columns: 1fr 1fr; gap: 30px 32px; }
.field { display: flex; flex-direction: column; }
.field--half { grid-column: span 1; }
.field--full, .field--submit { grid-column: 1 / -1; }
.field--hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.field label { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.55; margin-bottom: 10px; }
.field input, .field select, .field textarea {
    background: transparent; border: 0; border-bottom: 1px solid color-mix(in srgb, var(--fg) 30%, transparent);
    color: var(--fg); font-family: inherit; font-size: 15px; letter-spacing: 0.02em;
    padding: 8px 0; border-radius: 0; transition: border-color 0.4s var(--ease);
    -webkit-appearance: none; appearance: none;
}
.field textarea { resize: vertical; min-height: 70px; }
.field select { text-transform: uppercase; font-size: 13px; letter-spacing: 0.08em; cursor: pointer;
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: right 2px center, right -3px center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--fg); outline: none; }
.field input::placeholder, .field textarea::placeholder { color: color-mix(in srgb, var(--fg) 45%, transparent); }
.field.has-error input, .field.has-error select { border-color: #9c3a3a; }
.field__error { font-size: 11px; letter-spacing: 0.04em; color: #9c3a3a; margin-top: 6px; min-height: 1em; }

.book__submit {
    align-self: flex-start; margin-top: 10px;
    font-size: var(--fs-nav); letter-spacing: 0.16em; text-transform: uppercase;
    padding: 14px 34px; border: 1px solid var(--fg);
    transition: background-color 0.5s var(--ease), color 0.5s var(--ease);
}
.book__submit:hover { background: var(--fg); color: var(--bg); }
.book__submit[disabled] { opacity: 0.5; cursor: default; }
.book__status { margin-top: 16px; font-size: 12px; letter-spacing: 0.04em; opacity: 0.8; }
.book__status.is-error { color: #9c3a3a; opacity: 1; }

.book__thanks {
    min-height: 40vh; display: grid; place-items: center; text-align: center;
    font-size: clamp(20px, 3.2vw, 34px); letter-spacing: 0.06em; text-transform: uppercase; line-height: 1.5;
    opacity: 0; transform: translateY(14px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.book__thanks[hidden] { display: none; } /* the `hidden` attr must win over display:grid */
.book__thanks.is-in { opacity: 1; transform: none; }

/* ======================================================================
   SERVICES
   ====================================================================== */
.services { padding-top: calc(var(--header-h) + 10vh); padding-bottom: 12vh; }
.services__intro {
    padding: 0 var(--pad); margin-bottom: 9vh;
    display: grid; grid-template-columns: minmax(0, 760px) minmax(220px, 300px);
    justify-content: space-between; align-items: start; gap: 40px 8vw;
}
.services__intro-sheet { padding-top: 2vh; justify-self: end; width: 100%; }

/* Sheets — photographs presented like the index cards: tilted, lifted off the
   ground, idly drifting. Same shadow/frame language as .card. */
.srv-sheet { display: block; margin: 0; transform: rotate(var(--rot, 0deg)); }
.srv-sheet__inner {
    display: block;
    animation: klima-float var(--fd, 12s) ease-in-out var(--fdelay, 0s) infinite;
    --fx: 4px; --fy: 8px; --fr: 0.8deg;
}
.srv-sheet__frame {
    display: block; overflow: hidden;
    background: color-mix(in srgb, var(--fg) 8%, transparent);
    box-shadow: 0 40px 80px -48px rgba(21, 24, 25, 0.5);
}
.srv-sheet .klima-img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Side sheets: a fixed layer in the page margins. Each pair belongs to one
   section (data-side-for ↔ data-side). The pair of the section you are reading
   lands on top; the previous pair doesn't vanish — it recedes into a small pile
   behind (like sheets laid down one on another), and older ones drop out.
   Three transform layers, so they never fight:
     .srv-side          state (enter / behind / gone) — CSS transitions
     .srv-sheet__inner  live physics — scroll lean, cursor lean, drag (JS, no transition)
     .srv-sheet__frame  idle paper float — CSS animation */
.srv-sides { position: fixed; inset: 0; z-index: 5; pointer-events: none; }
.srv-side {
    position: absolute; top: 50%;
    width: clamp(150px, 13vw, 250px);
    --enter: 44px; --sc: 0.96; --stack: 0deg;
    opacity: 0; visibility: hidden;
    transform: translate3d(0, calc(-50% + var(--enter)), 0) rotate(calc(var(--rot, 0deg) + var(--stack))) scale(var(--sc));
    transition: opacity 0.9s var(--ease), transform 1.2s var(--ease), visibility 0s linear 0.9s;
}
.srv-side--l { left: calc(var(--pad) + 2vw); top: 44%; }
.srv-side--r { right: calc(var(--pad) + 2vw); top: 58%; }
/* Whisper-quiet by default — they read as texture in the margins, not as
   content; hover (or drag) brings the sheet fully into focus. */
.srv-side.is-active {
    --enter: 0px; --sc: 1;
    opacity: 0.3; visibility: visible; pointer-events: auto; cursor: none;
    transition: opacity 0.8s var(--ease) 0.12s, transform 1.2s cubic-bezier(.2,.9,.25,1) 0.12s, visibility 0s linear 0s;
}
.srv-side.is-active:hover, .srv-side.is-dragging { opacity: 1; transition: opacity 0.5s var(--ease), transform 1.2s cubic-bezier(.2,.9,.25,1); }
.srv-side.is-active:hover .srv-sheet__frame, .srv-side.is-dragging .srv-sheet__frame { filter: none; }
.srv-side.is-behind {
    --enter: -22px; --sc: 0.88; --stack: -5deg;
    opacity: 0.12; visibility: visible;
    transition: opacity 1s var(--ease), transform 1.2s var(--ease), visibility 0s linear 0s;
}
.srv-side--r.is-behind { --stack: 5deg; }
.srv-side.is-gone { --enter: -46px; --sc: 0.8; opacity: 0; }
.srv-side.is-active { z-index: 3; }
.srv-side.is-behind { z-index: 2; }
.srv-side.is-dragging { z-index: 4; }
.srv-side .srv-sheet__inner {
    animation: none;
    transform: translate3d(calc(var(--dragx, 0px) + var(--mx, 0px)), calc(var(--dragy, 0px) + var(--my, 0px) + var(--lift, 0px)), 0)
               rotate(var(--lean, 0deg));
    transition: transform 0.7s var(--ease); /* only felt on release/reset; JS writes vars every frame during drag */
    will-change: transform;
}
.srv-side.is-dragging .srv-sheet__inner { transition: none; }
.srv-side .srv-sheet__frame {
    animation: klima-float var(--fd, 12s) ease-in-out var(--fdelay, 0s) infinite;
    --fx: 3px; --fy: 7px; --fr: 0.7deg;
    filter: saturate(0.55) contrast(0.92); transition: filter 0.5s var(--ease);
    box-shadow: 0 30px 60px -44px rgba(21, 24, 25, 0.35);
    touch-action: none; user-select: none; -webkit-user-drag: none;
}
.srv-side .srv-sheet__frame .klima-img { pointer-events: none; }
.srv-side.is-dragging .srv-sheet__frame { box-shadow: 0 60px 100px -50px rgba(21, 24, 25, 0.6); animation-play-state: paused; }
/* The column is 900px wide; below ~1240px the margins can't hold a sheet. */
@media (max-width: 1240px) { .srv-sides { display: none; } }
@media (prefers-reduced-motion: reduce) {
    .srv-sheet__inner, .srv-side .srv-sheet__frame { animation: none; }
    .srv-side, .srv-side.is-active, .srv-side.is-behind { transition: opacity 0.3s linear; transform: translate3d(0, -50%, 0) rotate(var(--rot, 0deg)); }
    .srv-side.is-behind { opacity: 0; visibility: hidden; }
}
@media (max-width: 768px) {
    .services__intro { grid-template-columns: 1fr; gap: 36px; }
    .services__intro-sheet { justify-self: start; width: 64%; padding-top: 0; }
}
.services__title { font-size: clamp(30px, 5vw, 60px); font-weight: 400; letter-spacing: 0.02em; text-transform: uppercase; }
.services__title-ua { opacity: 0.4; font-size: 0.5em; letter-spacing: 0.04em; }
.services__lead { margin-top: 22px; font-size: clamp(17px, 2vw, 21px); line-height: 1.4; max-width: 60ch; }
.services__lead--ua { margin-top: 10px; font-size: 14px; opacity: 0.6; }

.services__block { padding: 0 var(--pad); max-width: 900px; margin: 0 auto 8vh; }
.services__label {
    font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; opacity: 0.5;
    margin-bottom: 22px; font-weight: 500;
}
.services__label span { opacity: 0.6; }

.srv-list { border-top: 1px solid color-mix(in srgb, var(--fg) 16%, transparent); }
.srv-row {
    display: flex; align-items: baseline; justify-content: space-between; gap: 24px;
    padding: 16px 0; border-bottom: 1px solid color-mix(in srgb, var(--fg) 14%, transparent);
}
/* English on top, Ukrainian beneath — the same stacked rhythm on every row and
   at every width (no inline wrapping). */
.srv-row__name { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; min-width: 0; }
.srv-row__en { font-size: 15px; letter-spacing: 0.04em; text-transform: uppercase; }
.srv-row__ua { font-size: 13px; opacity: 0.6; letter-spacing: 0.02em; }
.srv-row__note { display: flex; flex-direction: column; gap: 1px; margin-top: 3px; font-size: 11px; opacity: 0.4; letter-spacing: 0.04em; }
.srv-row__price { font-size: 15px; letter-spacing: 0.03em; font-variant-numeric: tabular-nums; white-space: nowrap; }

.services__note { margin-top: 16px; font-size: 12px; letter-spacing: 0.04em; opacity: 0.55; }
.services__note span { opacity: 0.8; }

/* ======================================================================
   LEGAL — Privacy Policy / Terms of Service
   ====================================================================== */
.legal { padding: calc(var(--header-h) + 8vh) 0 10vh; }
.legal__wrap { max-width: 720px; margin: 0 auto; padding: 0 var(--pad); }
.legal__head { margin-bottom: 7vh; }
.legal__title { font-size: clamp(34px, 5.5vw, 62px); font-weight: 400; letter-spacing: -0.02em; line-height: 1; }
.legal__lead { margin-top: 26px; font-size: clamp(16px, 1.5vw, 19px); line-height: 1.5; opacity: 0.82; max-width: 60ch; }
.legal__updated { margin-top: 20px; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.5; }
.legal__section { padding: 30px 0; border-top: 1px solid color-mix(in srgb, var(--fg) 14%, transparent); }
.legal__section:first-child { border-top: 0; }
.legal__h { font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; opacity: 0.6; margin-bottom: 16px; }
.legal__p { font-size: 15px; line-height: 1.62; opacity: 0.86; max-width: 66ch; }
.legal__p + .legal__p { margin-top: 13px; }
.legal__nav {
    display: flex; flex-wrap: wrap; gap: 26px; margin-top: 8vh;
    padding-top: 28px; border-top: 1px solid color-mix(in srgb, var(--fg) 14%, transparent);
    font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
}
.legal__nav a { opacity: 0.6; transition: opacity 0.3s var(--ease); }
.legal__nav a:hover { opacity: 1; }
.legal__nav a.is-active { opacity: 1; border-bottom: 1px solid currentColor; padding-bottom: 2px; }

.services__details { padding: 4vh var(--pad) 0; max-width: 900px; margin: 0 auto; }
.srv-detail {
    padding: 5vh 0; border-top: 1px solid color-mix(in srgb, var(--fg) 14%, transparent);
}
/* Title (with the Ukrainian name beneath it) on the left, price on the right;
   on mobile the price drops below instead (see the media query). */
.srv-detail__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px 24px; flex-wrap: wrap; margin-bottom: 16px; }
.srv-detail__title { font-size: clamp(20px, 2.6vw, 30px); font-weight: 400; letter-spacing: 0.01em; text-transform: uppercase; line-height: 1.05; }
.srv-detail__ua { display: block; margin-top: 3px; font-size: 13px; letter-spacing: 0.04em; opacity: 0.45; }
@media (max-width: 768px) {
    .srv-detail__head { flex-direction: column; align-items: flex-start; gap: 6px; }
}
.srv-detail__meta { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.55; white-space: nowrap; }
.srv-detail__en { font-size: 16px; line-height: 1.45; max-width: 62ch; margin-bottom: 18px; }
.srv-detail__ua-body { max-width: 66ch; }
.srv-detail__ua-body p { font-size: 14px; line-height: 1.55; opacity: 0.72; margin-bottom: 14px; }

.services__book {
    display: inline-flex; gap: 10px; margin: 6vh 0 0; margin-left: var(--pad);
    font-size: var(--fs-nav); letter-spacing: 0.14em; text-transform: uppercase;
    padding-bottom: 3px; border-bottom: 1px solid currentColor;
}
.services__book span { transition: transform 0.5s var(--ease); }
.services__book:hover span { transform: translateX(6px); }

/* ======================================================================
   LIGHTBOX — gallery of all Index works
   ====================================================================== */
.lightbox {
    position: fixed; inset: 0; z-index: 200;
    display: flex; align-items: center; justify-content: center;
    opacity: 0; visibility: hidden;
    transition: opacity 0.5s var(--ease), visibility 0s linear 0.5s;
}
.lightbox.is-open { opacity: 1; visibility: visible; transition: opacity 0.5s var(--ease); }
.lightbox__backdrop {
    position: absolute; inset: 0;
    background: color-mix(in srgb, var(--c-fog) 90%, transparent);
    -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px);
}
.lightbox__stage {
    position: relative; z-index: 2;
    display: flex; align-items: center; justify-content: center;
    max-width: min(88vw, 920px); max-height: 88vh;
}
.lightbox__img {
    max-width: 100%; max-height: 88vh; width: auto; height: auto;
    object-fit: contain; display: block;
    box-shadow: 0 60px 120px -54px rgba(21, 24, 25, 0.55);
    will-change: transform, opacity;
}
.lightbox__nav, .lightbox__close, .lightbox__count {
    position: absolute; z-index: 3;
    color: #fff; mix-blend-mode: difference;
    font-size: var(--fs-nav); letter-spacing: 0.16em; text-transform: uppercase;
}
.lightbox__nav { top: 50%; transform: translateY(-50%); font-size: 22px; padding: 20px; }
.lightbox__prev { left: 6px; }
.lightbox__next { right: 6px; }
.lightbox__close { top: 26px; right: var(--pad); }
.lightbox__count { bottom: 26px; left: var(--pad); font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
body.lb-open { overflow: hidden; }
@media (hover: none), (pointer: coarse) {
    .lightbox__nav { font-size: 26px; padding: 14px; }
}

/* ======================================================================
   FOOTER
   ====================================================================== */
.site-footer { padding: 40px var(--pad) 34px; margin-top: 4vh; }
.site-footer__inner {
    display: flex; justify-content: space-between; align-items: center; gap: 20px; flex-wrap: wrap;
    border-top: 1px solid color-mix(in srgb, var(--fg) 16%, transparent); padding-top: 26px;
    font-size: var(--fs-meta); letter-spacing: 0.12em; text-transform: uppercase;
}
.site-footer__links { display: flex; gap: 26px; }
.site-footer__links a { opacity: 0.8; transition: opacity 0.4s var(--ease); }
.site-footer__links a:hover { opacity: 1; }
.site-footer__note { opacity: 0.6; }

/* Fallback page */
.fallback { min-height: 70vh; display: grid; place-content: center; text-align: center; gap: 16px; padding: var(--pad); }
.fallback__label { letter-spacing: 0.4em; }
.fallback__lead a { border-bottom: 1px solid currentColor; }

/* ======================================================================
   RESPONSIVE
   ====================================================================== */
/* The INFO layout above owns the large-screen composition. */

@media (max-width: 1024px) {
    :root { --pad: 22px; --header-h: 66px; }
    .shot--col { grid-column: span 6; }
    .shot--wide { grid-column: 1 / -1; }
}

@media (max-width: 768px) {
    :root { --pad: 16px; --gutter: 10px; --header-h: 58px; }

    .brand { font-size: 14px; letter-spacing: 0.16em; }
    /* Mobile: the inline nav is hidden and MENU+ opens the full-screen editorial
       menu (.klima-menu) instead. */
    .nav-inline { display: none; }
    .menu-toggle { position: static; transform: none; opacity: 1 !important; pointer-events: auto !important; }

    .klima-menu {
        display: flex; flex-direction: column;
        position: fixed; inset: 0; z-index: 1100;
        padding: 22px var(--pad) calc(var(--pad) + 10px + env(safe-area-inset-bottom, 0px));
        background: var(--c-fog); color: var(--c-ink);
        mix-blend-mode: normal;
        overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
        /* No `visibility` transition — it delays hit-testing so a quick tap on a
           link right after opening was ignored. pointer-events flips instantly. */
        opacity: 0; pointer-events: none;
        transition: opacity 0.4s var(--ease);
    }
    /* No overflow:hidden on body while the menu is open: on the infinite
       index it collapses the scroll range to one viewport and the page snaps
       to the top (then stays there after CLOSE). Background scroll is locked
       by the touchmove guard in menuToggle() instead. */
    body.menu-open { overscroll-behavior: contain; }
    body.menu-open .klima-menu { opacity: 1; pointer-events: auto; }

    /* Top bar mirrors the site header: tracked brand, quiet uppercase action. */
    .klima-menu__top { display: flex; align-items: center; justify-content: space-between; }
    .klima-menu__brand { font-size: 14px; font-weight: 500; letter-spacing: 0.16em; }
    .klima-menu__close { font-size: var(--fs-nav); font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.7; }

    /* Stacked index — numbered, tracked uppercase; the current page in ink. */
    .klima-menu__nav { display: flex; flex-direction: column; margin-top: 8vh; }
    .klima-menu__link {
        position: relative; display: block; padding: 12px 0;
        font-size: clamp(30px, 9.6vw, 46px); font-weight: 500; line-height: 1.08;
        letter-spacing: 0.06em;
        color: var(--c-muted);
        border-bottom: 1px solid rgba(37, 43, 46, 0.12);
        transform: translateY(14px); opacity: 0;
        transition: color 0.3s var(--ease), transform 0.55s var(--ease), opacity 0.55s var(--ease);
    }
    .klima-menu__link:first-child { border-top: 1px solid rgba(37, 43, 46, 0.12); }
    .klima-menu__num {
        font-size: 10px; font-weight: 500; letter-spacing: 0.18em;
        vertical-align: top; margin-right: 14px; top: 4px; position: relative;
        color: var(--c-muted); font-variant-numeric: tabular-nums;
    }
    .klima-menu__link.is-active { color: var(--c-ink); }
    .klima-menu__link.is-active .klima-menu__num { color: var(--c-ink); }
    body.menu-open .klima-menu__link { transform: none; opacity: 1; }
    body.menu-open .klima-menu__link:nth-child(1) { transition-delay: 0.06s; }
    body.menu-open .klima-menu__link:nth-child(2) { transition-delay: 0.12s; }
    body.menu-open .klima-menu__link:nth-child(3) { transition-delay: 0.18s; }
    body.menu-open .klima-menu__link:nth-child(4) { transition-delay: 0.24s; }

    /* Contact rows — the Info-page list language: hairlines, tracked caps,
       muted handles on the right. */
    .klima-menu__foot { margin-top: auto; }
    .klima-menu__label {
        display: block; font-size: 10px; font-weight: 500; letter-spacing: 0.18em;
        text-transform: uppercase; color: var(--c-muted); margin-bottom: 4px;
    }
    .klima-menu__list li { border-bottom: 1px solid rgba(37, 43, 46, 0.12); }
    .klima-menu__list a {
        display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
        padding: 13px 0;
        font-size: 12px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
    }
    .klima-menu__list em {
        font-style: normal; font-size: 11px; letter-spacing: 0.1em;
        color: var(--c-muted);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .klima-menu__office { margin-top: 22px; }
    .klima-menu__addr { font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase; opacity: 0.8; }

    /* Index → single-column with a 2-up run for the narrow series */
    .index { padding-top: calc(var(--header-h) + 4vh); }
    .index__grid { grid-template-columns: repeat(2, 1fr); gap: 4vh var(--gutter); }
    .work { grid-column: 1 / -1 !important; margin-top: 0 !important; }
    .work--series { grid-column: span 1 !important; }
    .work__frame { aspect-ratio: 3 / 4; }
    .work--series .work__frame { aspect-ratio: 2 / 3; }
    .closing { margin-top: 8vh; }
    .closing__frame { aspect-ratio: 4 / 5; }

    /* Floating field on mobile: the desktop percent-scatter (--x/--w) makes wide
       sheets fly off the right and leaves the left empty, so re-anchor every
       sheet to the viewport centre and derive a gentle horizontal jitter from
       the scatter value. Loop math (--y) is untouched. */
    .card {
        --mw: clamp(220px, 62vw, 288px);
        width: var(--mw) !important;
        left: 50% !important;
        margin-left: calc(var(--mw) / -2 + (var(--x) - 47%) * 0.42) !important;
        opacity: calc(0.78 + var(--depth, 1) * 0.22);
    }
    .card__frame { box-shadow: 0 24px 48px -34px rgba(21, 24, 25, 0.5); }

    /* Project */
    .project__gallery { grid-template-columns: 1fr; }
    .shot--col, .shot--wide, .shot--full { grid-column: 1 / -1; }
    .project__gallery .shot { margin-top: 0 !important; }
    .project__credits { grid-template-columns: 1fr 1fr; }

    /* Info */
    .info { padding-top: calc(var(--header-h) + 2vh); } /* lift the photo up */
    .info__grid { grid-template-columns: 1fr; gap: 5vh; }
    /* relative (not static): the absolutely-positioned shots must anchor to
       this frame, otherwise they escape and cover the whole page. */
    .info__portrait { position: relative; top: auto; left: auto; width: auto; aspect-ratio: 4 / 5; max-height: 78vh; }
    .info__body { padding-top: 0; max-width: none; }

    /* Book */
    .book__form { grid-template-columns: 1fr; gap: 26px; }
    .field--half { grid-column: 1 / -1; }
    .book__submit { width: 100%; text-align: center; }
}

/* ======================================================================
   REDUCED MOTION
   ====================================================================== */
@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
    .klima-img { --reveal-y: 0% !important; --par-y: 0px !important; --img-scale: 1 !important; }
    [data-reveal-item] { opacity: 1 !important; transform: none !important; }
    .work__caption { opacity: 0.9 !important; transform: none !important; }
    .preloader { display: none; }
    .cursor { display: none; }
    body.is-loading { overflow: auto; }
}
