
/* =========================================================================
   ANIMA — light theme. Centered title cluster (ANIMA + 4 numbers) that
   parallaxes on scroll and is covered by the project photos below.
   Motion -> CONFIG (JS). Content -> PROJECTS / PRESS / TEAM / AB_GALLERY (JS).
   ========================================================================= */
:root{
  --paper:#ffffff;            /* page background (white) */
  --ink:#0d0d0d;              /* text */
  --mute:#8a8a85;
  --line:rgba(13,13,13,.14);
  --pad: clamp(16px, 2.6vw, 40px);
  --font: "Arimo", "Helvetica Neue", Arial, system-ui, sans-serif;
  --wordmark: clamp(2.7rem, 11.5vw, 11rem);
  /* It's a text site: every label reads exactly like MENU, and MENU reads
     like the reference — one face, 10px at every width (--meta), no extra
     tracking (--lbl-track), a 14px line (--lbl-lh). That goes for the header
     and ANIMA in it, the MENU panel, the section names, the project captions
     on the home page, the loading screen and the footer. */
  --meta: 10px;
  --lbl-track: normal;
  --lbl-lh: 14px;
  --hpad: 15px;               /* the reference's side margin: header, MENU panel, captions */
  /* The one exception, by the user's own screenshot: ANIMA and the four
     numbers on the first screen (and the splash that repeats it) in Geist
     Bold — all five one size, 17px on a 1920px screen, pure black. */
  --num: clamp(.8rem, .888vw, 1.6rem);
  --hero-font: "Geist", "Arimo", "Helvetica Neue", Arial, sans-serif;
}
*{ margin:0; padding:0; box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; }
body{
  background:var(--paper); color:var(--ink);
  font-family:var(--font); font-weight:400; letter-spacing:.01em;
  overflow-x:hidden; -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
@media (hover:none),(pointer:coarse){ body{ cursor:auto; } }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:none; cursor:pointer; }
::selection{ background:var(--ink); color:var(--paper); }
.meta{ font-size:var(--meta); letter-spacing:var(--lbl-track); text-transform:uppercase; color:var(--mute); }

/* ---------- preloader ---------- */
#preloader{ position:fixed; inset:0; z-index:100; background:var(--paper); color:var(--ink);
  display:flex; align-items:flex-end; justify-content:space-between; padding:var(--pad); }
#preloader .p-word,#preloader .p-count{ font-size:var(--meta); letter-spacing:var(--lbl-track); line-height:1.2; text-transform:uppercase; }
#preloader .p-word{ transform:translateY(110%); }
#preloader .p-count{ font-variant-numeric:tabular-nums; }
.pl-bar{ position:fixed; left:0; bottom:0; height:2px; width:0%; background:var(--ink); z-index:101; }

/* ---------- cursor: default system cursor (custom cursor removed) ---------- */
#cursor, #cursor-ring{ display:none; }

/* ---------- header: one line, after the reference — MENU on the left, ANIMA
   in the centre, the tools and the language on the right, every word in the
   one label face; 34px tall (10px above and below a 14px line), 15px from the
   edges, 30px between words. While the panel is open MENU reads CLOSE.
   1fr auto 1fr keeps ANIMA truly centred however wide the two sides are. */
header{ position:fixed; top:0; left:0; width:100%; z-index:60; background:var(--paper); color:var(--ink); }
.hbar{ display:grid; grid-template-columns:1fr auto 1fr; align-items:center; column-gap:30px;
  padding:10px var(--hpad); border-bottom:1px solid var(--line);
  font-size:var(--meta); line-height:var(--lbl-lh); letter-spacing:var(--lbl-track); text-transform:uppercase; }
.hbar button, .hbar a{ letter-spacing:inherit; text-transform:inherit; white-space:nowrap; }
.menu-toggle{ justify-self:start; }
.brand{ justify-self:center; }
.h-tools{ justify-self:end; display:flex; gap:30px; }
.lang-toggle{ color:var(--mute); }
.lang-toggle:hover{ color:var(--ink); }
.menu-toggle .mt-close, .h-tools .lbl-short{ display:none; }
.menu-open .menu-toggle .mt-menu{ display:none; }
.menu-open .menu-toggle .mt-close{ display:inline; }
.menu-toggle:hover, .h-tools button:hover{ opacity:.55; }

/* MENU panel — after the reference: narrow ruled columns on the left, an
   eighth of the window each (150px at least), empty space to the right, about
   a third of the screen tall. Each column's name sits in a 34px cell
   underlined edge to edge; its links start 30px under that line, one every
   24px (a 14px line + 10px). Every word in the one label face — the names and
   the links alike. It's a min-height, so the panel grows with an opened
   sub-category instead of cutting it off. */
.mega{ position:absolute; top:100%; left:0; right:0; background:var(--paper); color:var(--ink);
  display:grid; grid-template-columns:repeat(5,max(150px,12.5vw)) 1fr;
  min-height:clamp(280px,36vh,420px); max-height:calc(100svh - var(--hdr,35px)); overflow-y:auto;
  border-bottom:1px solid var(--line);
  font-size:var(--meta); line-height:var(--lbl-lh); letter-spacing:var(--lbl-track); text-transform:uppercase;
  clip-path:inset(0 0 100% 0); visibility:hidden;
  /* visibility waits for the slide to finish, so closed links drop out of the tab order */
  transition:clip-path .6s cubic-bezier(.7,0,.2,1), visibility 0s linear .6s; }
.menu-open .mega{ clip-path:inset(0); visibility:visible;
  transition:clip-path .6s cubic-bezier(.7,0,.2,1), visibility 0s; }
.mega-col{ display:flex; flex-direction:column; min-width:0; border-right:1px solid var(--line); }
.mega-col > *{ opacity:0; transform:translateY(-6px); transition:opacity .2s, transform .2s; }
.menu-open .mega-col > *{ opacity:1; transform:none;
  transition:opacity .45s ease calc(.2s + var(--i,0) * .06s), transform .55s cubic-bezier(.2,.7,.2,1) calc(.2s + var(--i,0) * .06s); }
.mega-h{ display:block; padding:10px var(--hpad); border-bottom:1px solid var(--line); }
.mega-list{ list-style:none; padding:30px var(--hpad) 75px; display:flex; flex-direction:column; gap:10px; }
/* a line spans the column, its count — (N), how many projects it opens — set
   right, as in the reference: NAME … (N) */
.mega-list a, .mm-toggle{ display:flex; justify-content:space-between; align-items:baseline; gap:12px; width:100%;
  letter-spacing:inherit; text-transform:inherit; text-align:left; }
.mm-n{ flex:none; }
.mega a:hover, .mm-toggle:hover{ opacity:.55; }
.mega-q{ margin-top:5px; }

/* Interiors / Buildings: the sub-categories slide out underneath. Animating
   grid rows 0fr→1fr gives a smooth open to the list's real height, which a
   max-height hack can't; each line then rises into place in turn. */
.mm-name{ display:inline-flex; align-items:center; gap:9px; }
.mm-plus{ position:relative; width:7px; height:7px; flex:none; }
.mm-plus::before, .mm-plus::after{ content:""; position:absolute; background:currentColor; }
.mm-plus::before{ left:0; right:0; top:3px; height:1px; }
.mm-plus::after{ top:0; bottom:0; left:3px; width:1px; transition:transform .35s cubic-bezier(.7,0,.2,1); }
.mm-parent.open .mm-plus::after{ transform:scaleY(0); }
.mm-sub{ display:grid; grid-template-rows:0fr; visibility:hidden;
  transition:grid-template-rows .5s cubic-bezier(.7,0,.2,1), visibility 0s linear .5s; }
.mm-parent.open .mm-sub{ grid-template-rows:1fr; visibility:visible;
  transition:grid-template-rows .5s cubic-bezier(.7,0,.2,1), visibility 0s; }
/* an 8px step in, so the longest Russian name («Медицинские учреждения»)
   still fits one line in a 192px column (a 1536px window) */
.mm-sub ul{ list-style:none; min-height:0; overflow:hidden; display:flex; flex-direction:column; gap:10px; padding-left:8px; }
.mm-sub li:first-child{ margin-top:10px; }
.mm-sub li{ opacity:0; transform:translateY(10px); transition:opacity .2s, transform .2s; }
.mm-parent.open .mm-sub li{ opacity:1; transform:none;
  transition:opacity .4s ease calc(.1s + var(--j,0) * .04s), transform .5s cubic-bezier(.2,.7,.2,1) calc(.1s + var(--j,0) * .04s); }

.mega-scrim{ position:fixed; inset:0; z-index:55; background:rgba(13,13,13,.28); opacity:0; pointer-events:none;
  transition:opacity .5s cubic-bezier(.7,0,.2,1); }
.menu-open .mega-scrim{ opacity:1; pointer-events:auto; }

/* PAGE TRANSITION — the reference splash: flat #fafafa, ANIMA dead centre, the
   years centred on 20% / 80% across and ⅓ / ⅔ down, in the same face and size
   as the first screen. Over the header (z 90), under the preloader (100).
   Each word is centred on its point (data-at, as fractions of the window) by
   the router just before the splash shows, on whole device pixels so the
   edges stay sharp; the vw / % / translate below are only the fallback.
   Across it's the whole window, so nothing moves when the scrollbar is taken
   away under it (body.page-lock, set by the router while the splash holds and
   while a page is open: the page scrolls itself, and the window under it no
   longer shows a second scrollbar).
   Timings come from CONFIG.pageTransition via --pt-in / --pt-out. */
body.page-lock{ overflow:hidden; }
.pt{ position:fixed; inset:0; z-index:90; background:#fafafa; opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity var(--pt-out,.45s) ease, visibility 0s linear var(--pt-out,.45s); }
.pt.on{ opacity:1; visibility:visible; pointer-events:auto; transition:opacity var(--pt-in,.25s) ease, visibility 0s; }
/* on the way into a dark page (About): black, the words white */
.pt.dark{ background:#000; }
.pt.dark .pt-item{ color:#fff; }
.pt-item{ position:absolute; transform:translate(-50%,-50%); white-space:nowrap;
  font-family:var(--hero-font); font-size:var(--num); font-weight:700; line-height:1; letter-spacing:.03em;
  font-variant-numeric:tabular-nums; text-transform:uppercase; color:#000; }
@supports (width: round(1.5px, 1px)){ .pt-item{ font-size:round(var(--num), 1px); } }
.pt-tl{ left:20vw; top:33.333%; }  .pt-tr{ left:80vw; top:33.333%; }
.pt-c { left:50vw; top:50%; }
.pt-bl{ left:20vw; top:66.667%; }  .pt-br{ left:80vw; top:66.667%; }

/* FEEDBACK PANEL — measured off the reference: a white sheet in the bottom-right
   corner, 56.2% of the screen wide and 46.6% tall, sliding up over whatever page
   is open. Inside, the label column starts at 18.25% of its width, the fields at
   38.5%, rows every ~38px, and a 225×45 outlined button. A min-height rather than
   a height, so on shorter screens the sheet grows instead of cutting the form. */
.fb-panel{ position:fixed; right:0; bottom:0; z-index:58; width:56.2vw; min-height:46.6vh; max-height:calc(100svh - 80px);
  overflow-y:auto; background:var(--paper); color:var(--ink);
  font-size:clamp(.72rem,.66vw,.8rem); line-height:1.38;
  transform:translateY(101%); visibility:hidden;
  transition:transform .6s cubic-bezier(.7,0,.2,1), visibility 0s linear .6s; }
.fb-open .fb-panel{ transform:none; visibility:visible; transition:transform .6s cubic-bezier(.7,0,.2,1), visibility 0s; }
.fb-panel:focus{ outline:none; }
.fbp-top{ display:flex; justify-content:space-between; align-items:baseline; padding:20px 18px 0 20px; }
.fbp-close, .fbp-title, .fbp-row > span, .fbp-send{ text-transform:uppercase; letter-spacing:.02em; }
.fbp-close:hover{ opacity:.55; }
.fbp-body{ padding:0 6.1% 32px 18.25%; }
.fbp-intro{ max-width:236px; margin-top:clamp(40px,7.2vh,96px); }
.fbp-form{ margin-top:clamp(26px,3.8vh,52px); }
/* 27% of this column = where the fields start in the reference (38.5% of the sheet) */
.fbp-row{ display:grid; grid-template-columns:27% 1fr; align-items:baseline; margin-bottom:16px; }
.fbp-row input, .fbp-row textarea{ font:inherit; color:inherit; background:transparent; border:0; border-radius:0;
  border-bottom:1px solid var(--line); padding:0 0 4px; width:100%; outline:none; }
.fbp-row textarea{ resize:none; height:4.3em; }
.fbp-row input:focus-visible, .fbp-row textarea:focus-visible{ border-bottom-color:var(--ink); }
.fbp-actions{ margin:clamp(24px,3.3vh,44px) 0 0 calc(27% + 11px); }
.fbp-send{ width:min(225px,100%); height:45px; border:1px solid var(--ink); transition:background .25s, color .25s; }
.fbp-send:hover{ background:var(--ink); color:var(--paper); }
.fbp-note{ margin-top:14px; min-height:1.4em; color:var(--mute); }
/* phones: the sheet takes the full width; on the narrowest, labels go above the fields */
@media (max-width:760px){
  /* left:0 rather than width:100vw — vw counts the scrollbar, which pushed
     the sheet's left edge off-screen by its width */
  .fb-panel{ left:0; width:auto; min-height:62svh; font-size:.8rem; }
  .fbp-body{ padding:0 var(--pad) 28px; }
  .fbp-row{ grid-template-columns:31% 1fr; }
  .fbp-actions{ margin-left:31%; }
}
@media (max-width:420px){
  .fbp-row{ grid-template-columns:1fr; row-gap:6px; }
  .fbp-actions{ margin-left:0; }
}
/* centered hero copy (campaign line + CTAs), placeholders you can rename */
.hero-copy{ position:absolute; inset:0; z-index:2; pointer-events:none; }
.hero-copy > *{ position:absolute; left:50%; transform:translateX(-50%); pointer-events:auto;
  font-size:var(--meta); letter-spacing:var(--lbl-track); text-transform:uppercase; color:var(--ink); opacity:.72;
  text-align:center; white-space:nowrap; }
.hero-cta{ top:63%; }
.hero-more{ bottom:8%; }
.hero-copy a:hover, .hero-copy button:hover{ opacity:1; }
/* The header stays one line at every width: the gaps tighten first, then
   Feedback shortens to «Связь», and on a phone — as in the reference, where
   it's MENU · the name · (0) — only MENU, ANIMA, «Связь», (0) and the language
   are left (About is in the MENU panel, Search does nothing yet).
   Below ~960px five ruled columns no longer fit side by side, so the panel
   stacks its sections, each name still underlined. */
@media (max-width:1100px){ .hbar{ column-gap:20px; } .h-tools{ gap:20px; } }
@media (max-width:960px){
  .mega{ grid-template-columns:1fr; min-height:0; border-bottom:none; }
  .mega-col{ border-right:none; }
  .mega-rest{ display:none; }
  .mega-list{ padding:20px var(--hpad) 24px; gap:12px; border-bottom:1px solid var(--line); }
}
@media (max-width:820px){
  .h-tools{ gap:14px; }
  .h-tools .lbl-full{ display:none; }
  .h-tools .lbl-short{ display:inline; }
}
@media (max-width:640px){
  .hbar{ column-gap:12px; }
  .h-tools{ gap:12px; }
  .h-search, #universeBtn, .h-cart-w{ display:none; }
}

/* =========================================================================
   HERO TITLE — fixed, centered cluster. The home photos (in #home, higher
   z-index, opaque) rise and cover it; it shows through the caption strips.
   ========================================================================= */
.hero-title{ position:relative; width:100%; height:100svh; z-index:1; display:flex; align-items:center; justify-content:center;
  pointer-events:none; background:var(--paper); }
.hero-bg{ position:absolute; inset:0; z-index:-1; background-size:cover; background-position:center; }
.title-inner{ position:fixed; inset:0; z-index:30; display:flex; align-items:center; justify-content:center;
  pointer-events:none; }
.cluster{
  display:grid;
  grid-template-columns:auto auto auto;
  grid-template-rows:auto auto auto;
  column-gap:clamp(120px, 30vw, 560px);
  row-gap:clamp(70px, 16vh, 240px);
  align-items:center;
  justify-items:center;
}
/* Plain pure-black text — no outline, no shadow, and the page's normal text
   rendering. Deliberately no will-change anywhere in this block: a promoted
   layer has its text rasterised once and then slid by fractional pixels as
   it follows the mouse, which is exactly what makes small text go soft. */
.cluster .wordmark{ grid-column:2; grid-row:2; text-align:center; white-space:nowrap;
  font-family:var(--hero-font); font-size:var(--num); line-height:1; letter-spacing:.03em; font-weight:700; text-transform:uppercase;
  color:#000; }
.cluster .wordmark .char{ display:inline-block; }
.cluster .num{ font-family:var(--hero-font); font-size:var(--num); font-variant-numeric:tabular-nums; letter-spacing:.03em;
  line-height:1; font-weight:700; color:#000; }
/* a whole-pixel size where supported, so the glyph stems sit on the pixel grid */
@supports (width: round(1.5px, 1px)){
  .cluster .wordmark, .cluster .num{ font-size:round(var(--num), 1px); }
}
.n-tl{ grid-column:1; grid-row:1; justify-self:start; }
.n-tr{ grid-column:3; grid-row:1; justify-self:end; }
.n-bl{ grid-column:1; grid-row:3; justify-self:start; }
.n-br{ grid-column:3; grid-row:3; justify-self:end; }

/* first screen of scroll room; main scrolls up over the fixed title */
main{ position:relative; background:transparent; }

/* PAGES — each menu section opens as its own full-screen view over the hero */
#pages{ position:fixed; inset:0; z-index:40; background:var(--paper); color:var(--ink);
  overflow-y:auto; -webkit-overflow-scrolling:touch;
  opacity:0; visibility:hidden; transform:translateY(1.5vh);
  transition:opacity .5s cubic-bezier(.7,0,.2,1), transform .6s cubic-bezier(.7,0,.2,1), visibility .5s; }
#pages.open{ opacity:1; visibility:visible; transform:none; }
.page-view{ display:none; border-top:none; }
.page-view.active{ display:block; }
.page-view.section{ padding-top:clamp(96px,16vh,190px); }

/* =========================================================================
   PROJECT / CONTENT SECTIONS (the photos that cover the title)
   ========================================================================= */
.section{ padding:clamp(60px,10vh,140px) var(--pad); border-top:1px solid var(--line); }
.section:first-child{ border-top:none; }
.section-head{ display:flex; justify-content:space-between; align-items:flex-end; gap:20px;
  margin-bottom:clamp(30px,6vh,72px); flex-wrap:wrap; }
.section-head h2{ font-size:var(--meta); letter-spacing:var(--lbl-track); line-height:1.2; font-weight:400; text-transform:uppercase; }
.proj-filter{ margin:6px 0 30px; }
.pf-row{ display:flex; flex-wrap:wrap; gap:10px 22px; align-items:center; }
.pf-sub{ margin-top:12px; padding-top:12px; border-top:1px solid var(--line); }
.pf-btn{ font-size:var(--meta); letter-spacing:var(--lbl-track); text-transform:uppercase; color:var(--ink); opacity:.5; }
.pf-btn:hover{ opacity:.85; }
.pf-btn.on{ opacity:1; text-decoration:underline; text-underline-offset:5px; }
.pf-sub-btn{ opacity:.45; }
/* Projects — rows of varying shape; the shapes live in PBLOCKS (script.js),
   which feeds --cols / --span / --ratio / --off in as inline values. */
.p-block{ display:grid; grid-template-columns:repeat(var(--cols,12),1fr); align-items:start;
  column-gap:clamp(16px,2.6vw,44px); row-gap:clamp(40px,7vh,96px);
  margin-bottom:clamp(48px,9vh,132px);
  /* 75 works is a lot of tiles to keep painted at once on a phone; let the
     browser skip the ones nowhere near the viewport. The intrinsic size keeps
     the scrollbar from jumping as they come in and out of range. */
  content-visibility:auto; contain-intrinsic-height:auto 70vh; }
.p-block:last-child{ margin-bottom:0; }
/* pulled out by exactly the section's own padding, so the row meets both window edges */
.p-block.bleed{ margin-left:calc(var(--pad) * -1); margin-right:calc(var(--pad) * -1); column-gap:0; }
.p-item{ grid-column:span var(--span,1); margin-top:var(--off,0); }
.p-media{ position:relative; width:100%; aspect-ratio:var(--ratio,4/5); background:#e9e8e3; overflow:hidden; }
.p-media .media{ position:absolute; inset:0; background-size:cover; background-position:center;
  filter:grayscale(1) contrast(1.03); transform:scale(1.02); transition:transform 1.1s cubic-bezier(.7,0,.2,1); }
.p-item:hover .media{ transform:scale(1.06); }
/* the caption reads like the home page's and the reference's: type · year in
   capitals, then the name — the one label face, 10px under the photo, 3px apart */
.p-cap{ display:flex; flex-direction:column; gap:3px; margin-top:10px;
  font-size:var(--meta); line-height:var(--lbl-lh); letter-spacing:var(--lbl-track); color:var(--ink); }
.p-block.bleed .p-cap{ padding-inline:var(--hpad); }
.p-cat{ text-transform:uppercase; }
.p-cap.split{ flex-direction:row; align-items:baseline; gap:clamp(14px,2.4vw,44px); }
.p-cap.split .p-txt{ display:flex; flex-direction:column; gap:5px; }
.p-cap.split .p-cat{ font-size:var(--meta); letter-spacing:var(--lbl-track); text-transform:uppercase; }

.reveal{ overflow:hidden; }

/* smooth in-page navigation + offset so section titles clear the fixed header */
/* HOME landing — scrolls up over the fixed hero. It has no background of its
   own: the photos are opaque and cover ANIMA + the numbers, while the white
   caption strips between the rows are windows onto the cluster fixed behind
   (on the white page), so the logo surfaces between the photos as they pass,
   like the logo on an underlay in the reference shop grid. The big photo is
   white until it loads; the footer has its own background. */
#home{ position:relative; z-index:10; }
.home-photo{ width:100%; }
.home-photo-media{ width:100%; height:100svh; background-color:var(--paper); background-size:cover; background-position:center; }
@media (max-width:640px){ .home-photo-media{ height:100svh; } }
/* Every project under the photo, four to a row, after the reference shop
   grid: edge to edge across the window, a quarter wide each, no gaps; each a
   whole 3:4 photo (480×640 on a 1920px screen) with its caption underneath,
   where the shop has the product's name and price: type · year in capitals,
   then the project's name — both black, in the one label face. The caption
   strip — 75px at every width, the first line 10px under the photo, the
   second 3px under the first, 15px in from the photo's edge, all as measured
   on the reference — is all that parts one row from the next. Two a row on narrow screens; a short last row keeps the
   quarter widths. Static while scrolling; only the photo zooms on hover.
   75 noise tiles are a lot to paint at once on a phone, so rows nowhere near
   the screen are skipped. A skipped row stands in at its computed height —
   the photo (4/3 of a quarter of the list's width, in cqw so the scrollbar
   doesn't count) plus the strip — so nothing shifts as rows come into range. */
#homeProjects{ container-type:inline-size;
  --hp-fs:var(--meta); --hp-lh:var(--lbl-lh); --hp-band:75px; }
.hp-row{ display:grid; grid-template-columns:repeat(4,1fr); align-items:start;
  content-visibility:auto;
  contain-intrinsic-height:auto calc(33.333cqw + var(--hp-band)); }
.hp-item{ display:block; min-width:0; }
.hp-media{ position:relative; aspect-ratio:3/4; overflow:hidden; background:#e9e8e3; }
.hp-media .media{ position:absolute; inset:0; background-image:var(--img); background-size:cover; background-position:center;
  filter:grayscale(1) contrast(1.03); transform:scale(1.02); transition:transform 1.1s cubic-bezier(.7,0,.2,1); }
.hp-item:hover .media{ transform:scale(1.06); }
.hp-cap{ display:flex; flex-direction:column; gap:3px; min-height:var(--hp-band); color:var(--ink);
  padding:10px var(--hpad); }
.hp-cat{ font-size:var(--hp-fs); line-height:var(--hp-lh); letter-spacing:var(--lbl-track); text-transform:uppercase; }
.hp-title{ font-size:var(--hp-fs); line-height:var(--hp-lh); letter-spacing:var(--lbl-track); }
/* two pairs per row-block; names often wrap at this width, so a skipped
   row may stand in a little short and simply grow when drawn */
@media (max-width:820px){ .hp-row{ grid-template-columns:repeat(2,1fr);
    contain-intrinsic-height:auto calc(133.333cqw + 2 * var(--hp-band)); } }

/* PROJECT PAGE — after the reference's article pages, measured on
   heliotemil.com/blogs/universe/aw26-pre-cymatics in a 1536px window. The
   first screen is the cover across the window, 75px short of its foot; on
   its right half, a fifth in, the year, the name and (10px lower) the type,
   in white — or black, for a light cover (the panel's switch; a stand-in
   tile picks by its own tone).
   Then the rows renderProject builds from the project's blocks:
   · pj-full — a landscape photo or video across the window at its own
     proportions (never taller than the screen);
   · pj-pair — upright ones, two to a row, 4:5 each (a lone one keeps the left half);
   · pj-quad — four small ones to a row, 4:5;
   · pj-side — an upright photo on the left, its text beside it on the right,
     held under the header while the photo scrolls by (126px down);
   · pj-text — text alone: 51px above, 75px below.
   Text always runs in the same column — 60% across plus 15px, a quarter of
   the window wide — in the one label face, paragraphs 20px apart, and in
   the site's language only (both are in the page; html[lang] hides one).
   On a phone everything stacks, the caption goes under the cover in black,
   text starts a third in, and the small photos go two to a row. */
.prj{ background:var(--paper); }
.pj-hero{ position:relative; margin-top:var(--hdr,35px); height:calc(100svh - var(--hdr,35px) - 75px); min-height:360px; overflow:hidden; }
.pj-hero-m{ position:absolute; inset:0; background:#e9e8e3; }
.pj-hero .media, .pj-full .media, .pj-half .media, .pj-q .media{ position:absolute; inset:0;
  background-size:cover; background-position:center; filter:grayscale(1) contrast(1.03); }
.pj-cap{ position:absolute; top:0; left:50%; right:0; padding:166px var(--hpad) 0 calc(10% + var(--hpad));
  display:flex; flex-direction:column; align-items:flex-start; gap:3px; color:#fff; pointer-events:none;
  font-size:var(--meta); line-height:var(--lbl-lh); letter-spacing:var(--lbl-track); text-transform:uppercase; }
.pj-hero.cap-dark .pj-cap{ color:var(--ink); }
.pj-cap-t{ font:inherit; }
.pj-cap-c{ margin-top:7px; }
.pj-full, .pj-half, .pj-q{ position:relative; margin:0; overflow:hidden; background:#e9e8e3; }
.pj-full{ width:100%; aspect-ratio:var(--r,1.7778); max-height:calc(100svh - var(--hdr,35px)); }
.pj-pair, .pj-side{ display:grid; grid-template-columns:1fr 1fr; align-items:start; }
.pj-half, .pj-q{ aspect-ratio:4/5; }
.pj-quad{ display:grid; grid-template-columns:repeat(4,1fr); }
.pj-video, .pj-embed{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; border:0; background:#000; }
.pj-fade{ opacity:0; transition:opacity .9s ease; }
.pj-fade.pj-in{ opacity:1; }
.pj-text{ padding:51px 0 75px; }
.pj-txt{ margin-left:calc(60% + var(--hpad)); width:calc(25% - 2 * var(--hpad));
  font-size:var(--meta); line-height:var(--lbl-lh); letter-spacing:var(--lbl-track); }
.pj-txt p + p{ margin-top:20px; }
.pj-side-t{ position:sticky; top:var(--hdr,35px); padding:126px 0 75px; }
.pj-side .pj-txt{ margin-left:calc(20% + var(--hpad)); width:calc(50% - 2 * var(--hpad)); }
html:not([lang="en"]) .pj-txt .lang-en, html[lang="en"] .pj-txt .lang-ru{ display:none; }
/* the way on: numbered rows between hairlines on the right half, grey until
   hovered — then more projects in a strip of cards like the home page's */
.pj-nav{ margin-left:50%; padding-top:75px; }
.prj-acc{ list-style:none; border-bottom:1px solid var(--line);
  font-size:var(--meta); line-height:var(--lbl-lh); letter-spacing:var(--lbl-track); text-transform:uppercase; }
.prj-ai{ border-top:1px solid var(--line); }
.prj-ah{ display:grid; grid-template-columns:20% 1fr; width:100%; padding:10px 0; color:#c3c3c3; transition:color .35s ease; }
.prj-ah > span{ padding:0 var(--hpad); }
.prj-ah:hover{ color:var(--ink); }
.prj-more{ padding-top:60px; --hp-fs:var(--meta); --hp-lh:var(--lbl-lh); --hp-band:75px; }
.prj-more-h{ padding:10px var(--hpad); font-size:var(--meta); line-height:var(--lbl-lh); font-weight:400; text-transform:uppercase; }
.prj-strip{ display:grid; grid-auto-flow:column; grid-auto-columns:max(180px,14.65vw); overflow-x:auto; scrollbar-width:none; }
.prj-strip::-webkit-scrollbar{ display:none; }
@media (max-width:820px){
  .pj-hero{ height:auto; min-height:0; }
  .pj-hero-m{ position:relative; aspect-ratio:3/4; }
  .pj-cap, .pj-hero.cap-dark .pj-cap{ position:static; padding:10px var(--hpad) 24px; color:var(--ink); }
  .pj-full{ max-height:none; }
  .pj-pair, .pj-side{ grid-template-columns:1fr; }
  .pj-quad{ grid-template-columns:1fr 1fr; }
  .pj-text{ padding:24px 0 32px; }
  .pj-txt, .pj-side .pj-txt{ margin-left:33.333%; width:auto; margin-right:var(--hpad); }
  .pj-side-t{ position:static; padding:24px 0 32px; }
  .pj-nav{ margin-left:0; padding-top:40px; }
  .prj-ah{ grid-template-columns:33.333% 1fr; }
  .prj-strip{ grid-auto-columns:42vw; }
}

html{ scroll-behavior:smooth; }
.section{ scroll-margin-top:var(--hdr,35px); }

/* TEAM — after the reference: square portraits ten to a row, edge to edge,
   inside a 2.6vw margin as the reference has it (50px), so 180px squares on a
   1920px screen; an uppercase title above. A cell changing person fades out
   to white and back in (initTeam / CONFIG.team). Six to a row on tablets,
   three on a phone. */
#team{ padding-left:2.6vw; padding-right:2.6vw; }
.team-grid{ display:grid; grid-template-columns:repeat(10,1fr); }
.tm-cell{ position:relative; aspect-ratio:1; overflow:hidden; background:var(--paper); }
.tm-cell .media{ position:absolute; inset:0; background-size:cover; background-position:center; filter:grayscale(1);
  will-change:opacity; transition:opacity var(--tm-in,.55s) cubic-bezier(.45,0,.55,1); }
.tm-cell.out .media{ opacity:0; transition-duration:var(--tm-out,.53s); }
@media (max-width:1100px){ .team-grid{ grid-template-columns:repeat(6,1fr); } }
@media (max-width:640px){ #team{ padding-left:var(--pad); padding-right:var(--pad); }
  .team-grid{ grid-template-columns:repeat(3,1fr); } }

/* PRESS — after a reference terms page, measured at 1920px:
   the list holds the right half of the window, out to its edge; a small
   uppercase title over numbered hairline rows 43px tall. The number sits
   19px in, the title on a column 22% across (the page title lines up with
   it), CLOSE at the right of the open row. The open row's text slides out
   beneath it — 13px, a 440px measure, 62px above and 100px below — and while
   one row is open the others step back to grey. */
/* the section keeps its left padding but drops the right one, so the list
   starts at exactly half the window: half the content box less half a pad */
#press{ padding-right:0; }
.pr-wrap{ --pr-col:22.2%; --pr-fs:var(--meta); --pr-dim:#b5b5b5; line-height:var(--lbl-lh);
  margin-left:calc(50% - var(--pad) / 2); font-size:var(--pr-fs); }
.pr-head{ padding-left:var(--pr-col); margin-bottom:clamp(40px,3.4vw,66px);
  font-size:var(--meta); font-weight:400; line-height:1.3; letter-spacing:var(--lbl-track); text-transform:uppercase; }
.pr-list{ border-bottom:1px solid var(--line); }
.pr-item{ border-top:1px solid var(--line); }
.pr-h{ font-size:inherit; font-weight:inherit; }
/* no side padding on the row itself: its 22.2% must be the same 22.2% the
   title above and the text below are set on (the wrap's width) */
.pr-row{ width:100%; display:grid; grid-template-columns:var(--pr-col) 1fr auto; align-items:baseline;
  padding:10px 0; text-align:left; line-height:var(--lbl-lh); letter-spacing:var(--lbl-track); text-transform:uppercase;
  color:var(--ink); transition:color .35s ease; }
.pr-num{ padding-left:clamp(12px,1vw,20px); font-variant-numeric:tabular-nums; }
.pr-title{ padding-right:24px; }
.pr-close{ padding-right:10px; opacity:0; transition:opacity .35s ease; }
.pr-item.open .pr-close{ opacity:1; }
.pr-list.has-open .pr-item:not(.open) .pr-row{ color:var(--pr-dim); }
.pr-list.has-open .pr-item:not(.open) .pr-row:hover{ color:var(--ink); }
/* The slide: the body's one grid row grows from 0 to the text's own height,
   and the text is clipped to it — so it comes out from under its row with no
   height to measure. Hidden once shut, so its link leaves the tab order. */
/* The curve starts moving at once (no slow ease-in), so a click never reads as
   a pause before the text comes out. */
.pr-body{ display:grid; grid-template-rows:0fr; visibility:hidden;
  transition:grid-template-rows .65s cubic-bezier(.4,0,.2,1), visibility 0s linear .65s; }
.pr-item.open .pr-body{ grid-template-rows:1fr; visibility:visible;
  transition:grid-template-rows .65s cubic-bezier(.4,0,.2,1), visibility 0s; }
.pr-inner{ min-height:0; overflow:hidden; }
.pr-text{ border-top:1px solid var(--line);
  padding:clamp(32px,3.25vw,64px) 24px clamp(48px,5.1vw,100px) var(--pr-col); }
.pr-text p{ max-width:440px; line-height:var(--lbl-lh); }
.pr-text p + p{ margin-top:1.9em; }
.pr-text a{ text-decoration:underline; text-underline-offset:2px; }
@media (prefers-reduced-motion:reduce){ .pr-body, .pr-item.open .pr-body{ transition:none; } }
/* under ~1100px half the window is too narrow for the titles: full width */
@media (max-width:1100px){ #press{ padding-right:var(--pad); } .pr-wrap{ margin-left:0; }
  .pr-num, .pr-close{ padding:0; } }
@media (max-width:640px){ .pr-wrap{ --pr-col:44px; } .pr-title{ padding-right:16px; }
  .pr-text{ padding-right:0; } }

/* FEEDBACK form */
.fb-form{ max-width:640px; }
.fb-row{ display:flex; gap:clamp(12px,2vw,24px); }
.fb-form input, .fb-form textarea{ flex:1; width:100%; background:none; border:none; border-bottom:1px solid var(--line);
  color:var(--ink); font:inherit; font-size:1rem; letter-spacing:.02em; padding:12px 0; outline:none; resize:vertical; }
.fb-form input::placeholder, .fb-form textarea::placeholder{ color:var(--mute); }
.fb-form textarea{ margin-top:18px; }
.fb-form button{ margin-top:24px; font-size:var(--meta); letter-spacing:var(--lbl-track); text-transform:uppercase; }
.fb-note{ margin-top:16px; }
@media (max-width:560px){ .fb-row{ flex-direction:column; } }

/* DARK PAGES (data-theme="dark" — the About page). The colour variables are
   redefined, so whatever is built on them follows: the page itself, the page
   area behind it, the cloned footer and contacts, the team strip (its cells
   now fade to black), and — while such a page is open — the header and the
   menu. The router sets body/#pages .theme-dark and redraws the logo. */
.about-page, #pages.theme-dark, body.theme-dark header{
  --paper:#000; --ink:#fff; --mute:#8d8d8d; --line:rgba(255,255,255,.16); }
#pages.theme-dark{ color-scheme:dark; }
.about-page{ background:var(--paper); color:var(--ink); }
.about-page .ab-frame{ background:#141414; }          /* pictures fade in out of black, not out of a pale box */

/* ABOUT — the studio page, after an editorial reference: black and white,
   small type, big photos edge to edge, thin lines, lots of white. Text sits in
   a narrow column starting 61.4% across (the reference's), labels on the
   left; on a phone everything stacks. The first screen fills the window under
   the header (--hdr, measured by initAbout). Pictures fade in and settle
   inside their frames as they come into view — the frames themselves never
   move. */
.about-page{ --ab-k:.614; --ab-fs:clamp(.85rem,.78vw,1rem); --ab-cap:clamp(.66rem,.62vw,.78rem); }
.ab-hero{ position:relative; height:calc(100svh - var(--hdr,73px)); margin-top:var(--hdr,73px); min-height:420px; }
.ab-frame{ position:relative; overflow:hidden; background:#e9e8e3; }
.ab-hero .ab-frame{ position:absolute; inset:0; }
.ab-img{ position:absolute; inset:0; background-size:cover; background-position:center; filter:grayscale(1) contrast(1.03);
  opacity:0; transform:scale(1.04);
  transition:opacity 1.1s cubic-bezier(.4,0,.2,1), transform 1.8s cubic-bezier(.2,.7,.2,1); }
.ab-img.ab-in{ opacity:1; transform:none; }
.ab-fade{ opacity:0; transition:opacity 1s cubic-bezier(.4,0,.2,1); }
.ab-fade.ab-in{ opacity:1; }
#abHero{ background-image:url("assets/images/hero-02.jpg"); }
/* small captions over the pictures: white, uppercase, set off by difference
   so they read on light and dark photos alike */
/* the captions start where the text column does (61.4% of the content width) */
.ab-hero-cap{ position:absolute; left:calc(var(--pad) + var(--ab-k) * (100% - 2 * var(--pad))); top:clamp(24px,5vh,56px); display:flex; flex-direction:column; gap:4px;
  font-size:var(--ab-cap); letter-spacing:.08em; text-transform:uppercase; color:#fff; mix-blend-mode:difference; }
.ab-block{ display:grid; grid-template-columns:calc(var(--ab-k) * 100%) 1fr; align-items:start;
  padding:clamp(56px,10vh,128px) var(--pad); border-top:1px solid var(--line); }
.ab-gallery + .ab-block, .ab-hero + .ab-block{ border-top:none; }
.ab-label{ display:flex; gap:12px; font-size:var(--meta); font-weight:400; letter-spacing:var(--lbl-track); text-transform:uppercase; }
.ab-n{ color:var(--mute); }
.ab-copy{ max-width:470px; padding-right:var(--pad); }
.ab-copy p{ font-size:var(--ab-fs); line-height:1.55; }
.ab-copy p + p{ margin-top:1.2em; }
.ab-meta{ color:var(--mute); text-transform:uppercase; letter-spacing:.08em; font-size:var(--ab-cap) !important; }
.ab-more{ font-size:var(--ab-cap); letter-spacing:.08em; text-transform:uppercase; border-bottom:1px solid currentColor; padding-bottom:2px; }
/* the gallery: four columns, no gaps, full width; an item spans 4, 2 or 1 */
.ab-gallery{ display:grid; grid-template-columns:repeat(4,1fr); align-items:start; }   /* unequal neighbours keep their own heights */
.ab-g{ position:relative; display:block; grid-column:span var(--span,2); }
.ab-g .ab-frame{ aspect-ratio:var(--ratio,3/2); }
.ab-g-gap{ grid-column:span 2; }
.ab-g-cap{ position:absolute; left:clamp(12px,1vw,20px); bottom:clamp(10px,.9vw,18px); z-index:1;
  font-size:var(--ab-cap); letter-spacing:.08em; text-transform:uppercase; color:#fff; mix-blend-mode:difference; }
/* directions: numbered rows between thin lines, each opening its projects */
.ab-dirs{ border-top:1px solid var(--line); }
.ab-dir{ display:grid; grid-template-columns:48px 1fr auto; column-gap:8px; row-gap:6px; align-items:baseline;
  padding:16px 0; border-bottom:1px solid var(--line); font-size:var(--ab-fs); }
.ab-dir-n, .ab-dir-c{ color:var(--mute); font-variant-numeric:tabular-nums; }
.ab-dir-s{ grid-column:2 / -1; font-size:var(--ab-cap); color:var(--mute); line-height:1.5; }
a.ab-dir:hover .ab-dir-t{ text-decoration:underline; text-underline-offset:3px; }
/* the team strip: one row of the Team page's squares, no names */
.ab-block-team{ padding-bottom:clamp(28px,4vh,48px); }
.ab-team-grid{ grid-template-columns:repeat(10,1fr) !important; }
/* contacts: the Contacts page's columns, set as label / value rows */
.ab-contact .f-col{ display:grid; grid-template-columns:30% 1fr; padding:12px 0; border-bottom:1px solid var(--line); }
.ab-contact .f-col:first-child{ border-top:1px solid var(--line); }
.ab-contact .f-col .meta{ grid-row:1 / span 9; margin:0; }
.ab-contact .f-col a{ font-size:var(--ab-fs); line-height:normal; letter-spacing:normal; text-transform:none; margin-bottom:4px; color:var(--ink); }
@media (max-width:760px){
  .ab-hero-cap{ left:var(--pad); }
  .ab-block{ grid-template-columns:1fr; row-gap:20px; padding:56px var(--pad); }
  .ab-block-team{ padding-bottom:28px; }
  .ab-copy{ padding-right:0; }
  .ab-gallery{ grid-template-columns:repeat(2,1fr); }
  .ab-g{ grid-column:span 2; }
  .ab-g[style*="--span:1"]{ grid-column:span 1; }
  .ab-g-gap{ display:none; }
  .ab-team-grid{ grid-template-columns:repeat(5,1fr) !important; }
}
.newsletter{ text-align:center; }
.newsletter h2{ font-size:clamp(1.8rem,7vw,5.2rem); letter-spacing:-.04em; line-height:.98; font-weight:600; }
.nl-form{ margin:clamp(28px,5vh,56px) auto 0; max-width:520px; display:flex; align-items:center; gap:12px;
  border-bottom:1px solid var(--line); padding-bottom:14px; }
.nl-form input{ flex:1; background:none; border:none; outline:none; color:var(--ink); font:inherit; font-size:1rem; letter-spacing:.02em; }
.nl-form input::placeholder{ color:var(--mute); }
.nl-form button{ font-size:var(--meta); letter-spacing:var(--lbl-track); text-transform:uppercase; white-space:nowrap; }
.nl-note{ margin-top:16px; }
footer{ border-top:1px solid var(--line); padding:var(--pad); background:var(--paper); position:relative; z-index:10; }
.f-grid{ display:grid; grid-template-columns:2fr 1fr 1fr 1fr; gap:24px; }
.f-grid h3{ font-size:var(--meta); letter-spacing:var(--lbl-track); line-height:1.2; font-weight:400; text-transform:uppercase; }
.f-col .meta{ margin-bottom:14px; }
/* the values under them (footer, Contacts) in the one label face too, as in
   the reference's footer: 10px capitals, black, a line every 24px */
.f-col a{ display:block; font-size:var(--meta); line-height:var(--lbl-lh); letter-spacing:var(--lbl-track);
  text-transform:uppercase; margin-bottom:10px; color:var(--ink); transition:opacity .3s ease; }
.f-col a:hover{ opacity:.55; }
.f-base{ display:flex; justify-content:space-between; margin-top:clamp(40px,8vh,90px); flex-wrap:wrap; gap:12px; }

/* responsive */
@media (max-width:820px){
  /* Narrow screens fold each row of four into two rows of two. The heights
     stay, so neighbouring rows still differ; spans and offsets (if a block
     ever uses them) only read as composition at desktop widths.
     !important because those values arrive as inline custom properties. */
  .p-block{ --cols:2 !important; column-gap:clamp(10px,2vw,18px); row-gap:clamp(28px,5vh,56px);
    margin-bottom:clamp(36px,7vh,72px); }
  .p-item{ grid-column:span 1 !important; margin-top:0 !important; }
  .p-cap.split{ flex-direction:column; align-items:flex-start; gap:7px; }
  /* Stacked blocks are far taller than the desktop estimate; guessing per
     item keeps the scrollbar from lurching on the first scroll through. */
  .p-block{ contain-intrinsic-height:auto calc(var(--n,3) * 28vh); }
  .f-grid{ grid-template-columns:1fr 1fr; }
  .f-grid h3{ grid-column:1 / -1; }
}
@media (max-width:520px){ .f-grid{ grid-template-columns:1fr; }
  .p-block{ --cols:1 !important; contain-intrinsic-height:auto calc(var(--n,3) * 66vh); }
  /* one frame per row on a phone: one even height reads calmer than a jagged column */
  .p-media{ aspect-ratio:4/5 !important; } }

/* reduced motion */
/* Hero on small screens: keep all four numbers + ANIMA fully on-screen, a touch larger */
@media (max-width:640px){
  :root{ --num: clamp(1.1rem, 4.6vw, 1.6rem); }
  .cluster{ column-gap: clamp(72px, 30vw, 118px); row-gap: clamp(84px, 22vh, 168px); }
}
@media (max-width:760px){
  /* filter buttons: comfortable tap targets, horizontal scroll instead of wrap */
  .proj-filter{ margin:2px 0 22px; }
  .pf-row{ flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; gap:8px 16px;
    scrollbar-width:none; padding-bottom:2px; }
  .pf-row::-webkit-scrollbar{ display:none; }
  .pf-btn{ padding:9px 0; white-space:nowrap; }
  /* hero copy: allow wrapping, pull lines away from the corner numbers */
  .hero-copy > *{ white-space:normal; max-width:78vw; line-height:1.5; }
  .hero-cta{ top:70%; }
  .hero-more{ bottom:6%; }
}
/* Without GSAP (blocked CDN) or without JS, elements that are parked off-screen
   for their intro animation must still be visible. */
.no-gsap #preloader{ display:none !important; }
.no-gsap .p-word{ transform:none !important; }
.no-gsap .char{ transform:none !important; }
/* Visible keyboard focus (was missing entirely) */
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible{
  outline:2px solid currentColor; outline-offset:3px; border-radius:2px; }
/* Touch devices: :hover "sticks" after a tap, and hover-only affordances are
   unreachable — so neutralise the movement and reveal the label outright. */
@media (hover:none){
  .hp-item:hover .media{ transform:scale(1.02); }
  .menu-toggle:hover, .h-tools button:hover, .mega a:hover, .mm-toggle:hover, .pf-btn:hover{ opacity:inherit; }
}
@media (prefers-reduced-motion:reduce){ *{ transition:none !important; animation:none !important; } html{ scroll-behavior:auto; } }

/* ---------- images ---------- */
#heroBg{ background-image:url("assets/images/hero-01.jpg"); }
#homePhoto{ background-image:url("assets/images/hero-02.jpg"); }
