/* Portfolio of Anastasia Ovsyannikova. Swiss catalogue: white page, neutral greys, one Prussian-blue accent.
   Type roles: PT Serif Regular names things and is read (the artist's name, page titles, project titles, prose);
   PT Sans carries the structure (wordmark, nav, section labels, links, captions, dates) with a Regular/Bold contrast.
   One scale, ratio 1.5 on desktop (18 / 27 / 40 / 60), ~1.33 on phones (17 / 22 / 30 / 40).
   Works are always shown whole (contain, never cropped) and never tinted. */
@font-face { font-family: "Catalogue Serif"; src: url(/fonts/pt-serif-regular.woff2) format("woff2"); font-display: swap; }
@font-face { font-family: "Catalogue Serif"; font-style: italic; src: url(/fonts/pt-serif-italic.woff2) format("woff2"); font-display: swap; }
@font-face { font-family: "Catalogue Sans"; src: url(/fonts/pt-sans-regular.woff2) format("woff2"); font-display: swap; }
@font-face { font-family: "Catalogue Sans"; font-weight: 700; src: url(/fonts/pt-sans-bold.woff2) format("woff2"); font-display: swap; }

:root {
  --paper: #FFFFFF;          /* the same white in html, the header band, main.js PAPER and the GL layer */
  --ink: #111111;
  --ink-2: #666666;          /* secondary text, 5.7:1 on white */
  --rule: #d9d9d9;           /* hairlines */
  --field: #8c8c8c;          /* input borders, 3.4:1 on white */
  --cyan: #1f4e9e;           /* Prussian blue accent: hover and current page only */
  --err: #a3261b;
  --m: clamp(16px, 4vw, 64px);
  --max: 1280px;
  --gut: clamp(16px, 1.8vw, 24px);   /* grid gutter */
  --serif: "Catalogue Serif", "PT Serif", Georgia, serif;
  --sans: "Catalogue Sans", "PT Sans", "Helvetica Neue", Arial, sans-serif;
  /* the scale, fluid between 390 and 1376 px wide; every text is one of these four */
  --t-body: clamp(1.0625rem, 1.0375rem + 0.1vw, 1.125rem);      /* 17 → 18 */
  --t-lead: clamp(1.375rem, 1.25rem + 0.51vw, 1.6875rem);       /* 22 → 27 */
  --t-h1: clamp(1.875rem, 1.625rem + 1.01vw, 2.5rem);           /* 30 → 40 */
  --t-display: clamp(2.25rem, 2rem + 2.03vw, 3.75rem);          /* 40 → 60 */
  --gap: clamp(64px, 8vw, 128px);
  /* arrow for text links: PT ships no arrow glyphs, a fallback font would not match */
  --arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 8h13M9 3l5 5-5 5' fill='none' stroke='%23000' stroke-width='1.8'/%3E%3C/svg%3E");
}

* { box-sizing: border-box; }
html { background: var(--paper); -webkit-text-size-adjust: 100%; }
/* header band keeps the name and nav readable over scrolled content */
#head::before { content: ""; position: absolute; inset: 0 0 -2em; z-index: -1; pointer-events: none;
  background: linear-gradient(var(--paper) 62%, rgb(255 255 255 / 0)); }
body { margin: 0; color: var(--ink); font: 400 var(--t-body)/1.5 var(--sans); font-kerning: normal; -webkit-font-smoothing: antialiased; }
a { color: inherit; text-decoration: none; }
p, h1, h2, h3, ul, ol, figure { margin: 0; padding: 0; }
h1, h2, h3 { font-weight: 700; }
ul, ol { list-style: none; }
button, input, textarea { font: inherit; color: inherit; }
::selection { background: var(--cyan); color: #fff; }
:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }
.skip { position: fixed; left: var(--m); top: -100px; z-index: 30; background: var(--paper); color: var(--ink);
  min-height: 44px; display: inline-flex; align-items: center; padding: 0 14px; border: 2px solid var(--cyan); }
.skip:focus { top: 8px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* fixed stack: view (moved by the scroll engine) < header < canvas (multiply, only during a transition) < veil */
#view { position: fixed; inset: 0; overflow: hidden; z-index: 1; }
#main { position: absolute; inset: 0; outline: none; }
#spacer { width: 1px; pointer-events: none; }
#head { position: fixed; left: 0; right: 0; top: 0; z-index: 5; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0 24px; padding: clamp(8px, 1.4vw, 20px) max(var(--m), calc((100% - var(--max)) / 2)) 4px; pointer-events: none; }
#head > * { pointer-events: auto; }
#gl { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 10; pointer-events: none; mix-blend-mode: multiply; display: none; }
html.gl #gl { display: block; }
#veil { position: fixed; inset: 0; z-index: 11; pointer-events: none; background: var(--cyan); opacity: 0; }
html.gl #veil { display: none; }

/* header: the name is the wordmark (Bold), the nav is the same size in Regular; on home the h1 is the name, so the wordmark steps back */
#name { font-weight: 700; line-height: 1.15; white-space: nowrap; min-height: 44px; display: inline-flex; align-items: center; }
html[data-page="home"] #name { display: none; }
#nav { display: flex; align-items: center; gap: clamp(16px, 2.2vw, 32px); margin-left: auto; }
#nav a { min-height: 44px; display: inline-flex; align-items: center; white-space: nowrap; }
#nav > a[aria-current] { text-decoration: underline 1px; text-underline-offset: 0.3em; }
#nav > a[aria-current="page"] { color: var(--cyan); }
#nav .lang { display: inline-flex; align-items: center; color: var(--ink-2); }
#nav .lang a { padding: 0 5px; }
#nav .lang a:last-child { padding-right: 0; }
#nav .lang a[aria-current] { color: var(--ink); text-decoration: underline 1px; text-underline-offset: 0.3em; }
#nav a:hover { color: var(--cyan); }

/* sections are absolutely placed and moved by js/timeline.js; each holds a centred column */
.sec { position: absolute; left: 0; right: 0; top: 0; will-change: transform; }
.page { position: absolute; inset: 0; }
.page.staged, .page.staged .sec { visibility: hidden; }
.wrap { width: min(100%, calc(var(--max) + 2 * var(--m))); margin-inline: auto; padding: var(--gap) var(--m) 0; }
.sec.first .wrap { padding-top: calc(var(--head-h, 72px) + clamp(24px, 4.5vw, 72px)); }
.sec.end { display: flex; flex-direction: column; justify-content: flex-end; }

/* type */
.h1 { font: 400 var(--t-h1)/1.12 var(--serif); letter-spacing: -0.005em; max-width: 22em; text-wrap: balance; margin-bottom: 0.7em; }
.kicker { color: var(--ink-2); margin-bottom: 8px; }
.kicker a { display: inline-flex; align-items: center; min-height: 44px; text-decoration: underline 1px; text-underline-offset: 0.3em; }
.kicker a:hover { color: var(--cyan); }
.label { font: 700 var(--t-body)/1.3 var(--sans); padding-top: 12px; border-top: 1px solid var(--ink); margin: clamp(48px, 6vw, 96px) 0 8px; }
.prose { max-width: 36em; font: 400 var(--t-body)/1.6 var(--serif); }
.prose p + p { margin-top: 1em; }
.prose .lead { font-size: var(--t-lead); line-height: 1.35; }
.prose .lead + p:not(.lead) { margin-top: 1.4em; }
.meta { color: var(--ink-2); margin: 0.2em 0 1.4em; }
.meta a { color: var(--ink); text-decoration: underline 1px; text-underline-offset: 0.3em; }
.meta a:hover { color: var(--cyan); }
.back { margin-bottom: 1em; }
.back a { min-height: 44px; display: inline-flex; align-items: center; gap: 0.5em; color: var(--ink-2); }
.back a::before { content: ""; width: 0.85em; height: 0.85em; background: currentColor; -webkit-mask: var(--arrow) center / contain no-repeat;
  mask: var(--arrow) center / contain no-repeat; transform: scaleX(-1); }
.back a:hover { color: var(--cyan); }
/* main transitions are text links with an arrow, not boxes */
.actions, .prose p.actions { display: flex; flex-wrap: wrap; gap: 0 40px; margin-top: clamp(32px, 4vw, 56px); font: 700 var(--t-body)/1.3 var(--sans); }
.go { display: inline-flex; align-items: center; gap: 0.5em; min-height: 44px; }
.go::after { content: ""; width: 0.85em; height: 0.85em; background: currentColor; -webkit-mask: var(--arrow) center / contain no-repeat;
  mask: var(--arrow) center / contain no-repeat; transition: transform 0.2s; }
.go:hover { color: var(--cyan); }
.go:hover::after { transform: translateX(4px); }
.btn { display: inline-flex; align-items: center; min-height: 48px; padding: 0 1.4em; border: 1px solid var(--ink); background: var(--ink); color: var(--paper);
  font: 700 var(--t-body)/1.2 var(--sans); cursor: pointer; }
.btn:hover { background: var(--cyan); border-color: var(--cyan); }

/* images: real size reserved before load, faded in once decoded; a failed image becomes a labelled plate */
img.art { display: block; width: 100%; height: auto; aspect-ratio: var(--ar); }
img.lazy { opacity: 0; transition: opacity 0.4s; }
img.lazy.in { opacity: 1; }
.art-missing { display: flex; align-items: center; justify-content: center; text-align: center; min-height: 160px; aspect-ratio: var(--ar, 4 / 3);
  padding: 1em; border: 1px dashed var(--rule); color: var(--ink-2); }

/* home: 12-column grid; the portrait holds columns 1–5, the name and the text hang on the column-7 axis */
.home { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gut); row-gap: clamp(28px, 3vw, 44px); align-items: start; }
.home .who { grid-column: 7 / -1; grid-row: 1; }
.home .who .h1 { font-size: var(--t-display); line-height: 1.04; letter-spacing: -0.012em; margin: -0.165em 0 0; max-width: none; }
.home .portrait { grid-column: 1 / span 5; grid-row: 1 / span 2; }
.home .txt { grid-column: 7 / -1; grid-row: 2; }

/* catalogue and collection: a list of names like a catalogue's contents page, title in serif, kind in grey */
.plist { margin-top: clamp(24px, 3vw, 40px); border-top: 1px solid var(--ink); }
.plist .row { border-bottom: 1px solid var(--rule); }
.plist .row > a, .plist .row.pending { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 4px 24px;
  min-height: 44px; padding: 0.9em 0; }
.plist .ttl { font: 400 var(--t-lead)/1.25 var(--serif); }
.plist .kind { color: var(--ink-2); }
.plist .row > a:hover .ttl, .plist .row > a:focus-visible .ttl { color: var(--cyan); }
.plist .row > a:active .ttl { color: var(--ink-2); }
.plist .row.pending .ttl { color: var(--ink-2); }
.empty { color: var(--ink-2); margin-top: 1em; }

/* series */
.gallery { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(40px, 5vw, 80px) var(--gut); align-items: start;
  margin-top: clamp(20px, 2.4vw, 32px); }
.gallery figcaption { margin-top: 10px; color: var(--ink-2); line-height: 1.45; max-width: 36em; }
.gallery figcaption .wt { display: block; font: 400 var(--t-body)/1.35 var(--serif); color: var(--ink); margin-bottom: 2px; }
.gallery figcaption .ws { display: block; }   /* the series of a work shown in another project */
.gallery.one { grid-template-columns: minmax(0, 1fr); }
.gallery.one > li { max-width: min(100%, calc(78vh * var(--ar))); }   /* one work alone: whole on screen, not stretched */
/* a tall work (an object, a narrow panel) stays whole on one screen beside its neighbour */
.gallery figure > img.art { max-width: min(100%, calc(78vh * var(--ar))); }
/* other views of the same object: small, under the main view, before the caption */
.views { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; align-items: start; margin-top: 8px; max-width: 420px; }
.cdesc { margin-top: clamp(8px, 1vw, 16px); }
.draft-banner { max-width: 36em; margin: 0 0 1.4em; padding: 12px 16px; border: 1px solid var(--ink); }
.nextp .ttl { display: inline-block; min-height: 44px; font: 400 var(--t-h1)/1.12 var(--serif); letter-spacing: -0.005em; margin-bottom: 0.6em; }
.nextp .ttl:hover { color: var(--cyan); }

/* video */
.film { margin-top: clamp(16px, 2vw, 28px); max-width: 1280px; }
.film.tall { max-width: min(100%, calc(78vh * var(--ar))); }   /* vertical clips fit the screen height */
.gallery .film { margin-top: 0; }   /* a clip in a gallery lines up with the photo beside it */
.film .media { position: relative; width: 100%; aspect-ratio: var(--ar); background: #000; }
.film video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; cursor: pointer; }
.verr { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  padding: 1em; text-align: center; color: #fff; background: rgb(0 0 0 / 0.72); }
.verr[hidden] { display: none; }
.verr .retry { min-height: 44px; padding: 0 1.2em; border: 1px solid #fff; background: none; color: #fff; cursor: pointer; }
.player { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 20px; margin-top: 8px; color: var(--ink-2); }
.player button { min-height: 44px; background: none; border: 0; padding: 0 2px; cursor: pointer; color: var(--ink); }
.player button:hover { color: var(--cyan); }
.player .bar { flex: 1 1 160px; position: relative; height: 44px; cursor: pointer; touch-action: none; }
.player .bar::before, .player .bar i { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 2px; margin-top: -1px; }
.player .bar::before { background: var(--rule); }
.player .bar i { background: var(--ink); transform-origin: 0 50%; transform: scaleX(0); }
.player .time { font-variant-numeric: tabular-nums; }
.player.off { opacity: 0.4; pointer-events: none; }

/* info */
.infonav ul { display: flex; flex-wrap: wrap; gap: 0 clamp(16px, 2vw, 28px); margin: 0 0 clamp(24px, 3vw, 48px); }
.infonav a { min-height: 44px; display: inline-flex; align-items: center; color: var(--ink-2); }
.infonav a:hover { color: var(--cyan); }
.infonav a[aria-current] { color: var(--ink); font-weight: 700; }
.infonav + .label, .infonav + .doc-body > .label:first-child { margin-top: 0; }   /* the section rule sits right under the menu */
.years { max-width: 56em; }
.years li { display: grid; grid-template-columns: 8.5em minmax(0, 1fr); gap: 4px var(--gut); padding: 0.7em 0; border-bottom: 1px solid var(--rule); }
.years .y { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.years a { text-decoration: underline; text-underline-offset: 0.2em; }
.years a:hover { color: var(--cyan); }
.lines { display: grid; gap: 16px; margin-top: 1.4em; }
.lines li { display: grid; gap: 0; }
.lines .k { color: var(--ink-2); }
.lines a { display: inline-flex; align-items: center; min-height: 44px; font: 400 var(--t-lead)/1.3 var(--sans); overflow-wrap: anywhere; justify-self: start; }
.lines a:hover { color: var(--cyan); }

/* lecture: the first slide, the facts, then the PDF */
.lecture { display: grid; gap: 20px; max-width: 40em; }
.lecture .cover { border: 1px solid var(--rule); }
.lecture .ttl { font: 400 var(--t-lead)/1.25 var(--serif); margin-bottom: 0.4em; }
.lecture .k { color: var(--ink-2); }
.lecture .actions { margin-top: 16px; }

/* contact form: opens the visitor's mail app (mailto); nothing is sent or stored by the site */
form.mail { display: grid; gap: 20px; max-width: 36em; margin-top: clamp(32px, 4vw, 56px); }
.field label { display: block; margin-bottom: 6px; }
.field .req { color: var(--ink-2); }
.field input, .field textarea { display: block; width: 100%; min-height: 48px; padding: 0.6em 0.75em; border: 1px solid var(--field); border-radius: 0;
  background: #fff; line-height: 1.4; font-size: max(16px, 1em); }
.field textarea { resize: vertical; }
.field input:focus-visible, .field textarea:focus-visible { outline: 2px solid var(--cyan); outline-offset: 0; border-color: var(--cyan); }
.field [aria-invalid="true"] { border-color: var(--err); }
.field .err { color: var(--err); margin-top: 4px; }
.field .err:empty { display: none; }
form.mail .note { color: var(--ink-2); }
form.mail .btn { justify-self: start; }
form.mail .opened:empty { display: none; }

/* footer */
.foot { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 24px; margin-top: var(--gap);
  padding: 16px 0 max(24px, env(safe-area-inset-bottom)); border-top: 1px solid var(--ink); color: var(--ink-2); }
.foot > span { min-height: 44px; display: inline-flex; align-items: center; }
.foot .links { display: flex; flex-wrap: wrap; gap: 0 24px; }
.foot a { min-height: 44px; display: inline-flex; align-items: center; overflow-wrap: anywhere; color: var(--ink); }
.foot a:hover { color: var(--cyan); }
.sec.end .wrap { padding-top: 0; }

/* content failed to load: plain document flow */
html.failed #view, html.failed #main { position: static; overflow: visible; }
html.failed #spacer { display: none; }
.fail { width: min(100%, calc(var(--max) + 2 * var(--m))); margin-inline: auto; padding: calc(var(--head-h, 72px) + 48px) var(--m) 64px; }
.fail .btn { margin: 1em 0; }

/* desktop text pages hang on the same column-7 axis as home: titles and section labels left, reading text right */
@media (min-width: 900px) {
  .intro .wrap { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: auto auto auto 1fr; column-gap: var(--gut); }
  .intro .wrap > * { grid-column: 1 / span 5; }
  .intro .wrap > .prose { grid-column: 7 / -1; grid-row: 3 / -1; padding-top: 0.35em; }
  .doc .wrap, .doc .doc-body { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gut); align-items: start; }
  .doc .wrap > *, .doc .doc-body { grid-column: 1 / -1; }
  .doc .label { grid-column: 1 / span 5; }
  .doc .wrap > .label ~ :not(.label), .doc .doc-body > :not(.label) { grid-column: 7 / -1; }
  .doc .label + * { margin-top: clamp(48px, 6vw, 96px); padding-top: 12px; border-top: 1px solid var(--ink); }
  .doc .infonav + .label + *, .doc .infonav + .doc-body > .label:first-child + * { margin-top: 0; }
  .doc .label + .years { padding-top: 0; }
}
/* tablet: the same grid, the axis moves to column 6 so the text keeps ~40 characters a line */
@media (min-width: 600px) and (max-width: 899px) {
  .home .who, .home .txt { grid-column: 6 / -1; }
}
@media (max-width: 599px) {
  .home { grid-template-columns: minmax(0, 1fr); }
  .home .who, .home .portrait, .home .txt { grid-column: 1; grid-row: auto; }
  .home .portrait { max-width: 560px; }
}
@media (max-width: 767px) {
  #name { white-space: normal; max-width: 7em; }   /* the wordmark stacks in two lines, so the nav stays on one row */
  .gallery { grid-template-columns: minmax(0, 1fr); }
  .years li { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  img.lazy, .go::after { transition: none; }
}
