/* Personal site v1 (2026-10-15). Same look as the Revea product page (white, Geist 300 display, v2 photo cards), but
   the small mono text is no longer decor: it appears only where it carries a value (live Reveal Progress, blur
   radius, case facts such as year and role). Layout: one long page (Works, Plug-ins, About); a project opens into a
   full-screen case view on top of it, addressed by #work-<id>.
   Light by default; dark follows the system or the theme button (data-theme on <html>, saved in localStorage
   "theme"; user 2026-10-15). Photo cards stay dark in both themes. */
:root {
  --paper: #ffffff;
  --shell: #ffffff;   /* hero card frame */
  --ink: #0e0e0f;     /* headings, CTA */
  --body: #4a4b4f;    /* running text */
  --muted: #8a8b90;   /* mono values, captions */
  --rule: #e6e6e8;
  --photo: #0c0a09;   /* ground under photos and the portrait */
  --on-dark: #ffffff; --on-dark-soft: rgba(255,255,255,.66);
  --shadow: none;   /* flat (user 2026-10-15): no shadows anywhere, nothing lifts */
  --revea: linear-gradient(100deg, #0d0d0e 4%, #123f42 17%, #2c9894 26%, #7fae9f 35%, #b8c9ad 44%, #f1e7cf 51%, #f3c193 60%, #cf6d24 71%, #5a2a14 82%, #151012 94%);
  --max: 1360px;     /* content column */
  --gutter: clamp(16px, 4vw, 56px);   /* page side padding, grows with the window */
  /* Type (2026-10-15): one grotesque on EN and RU (Geist Cyrillic was thin and uneven at 300), Geist Mono for values.
     Serif headings were tried and rejected. Display tracking is relaxed at the end of this file. */
  --sans: "Inter", "Segoe UI", system-ui, sans-serif;
  --display: "Inter Tight", "Inter", "Segoe UI", system-ui, sans-serif;
  --mono: "Geist Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
  color-scheme: light;
}
/* Dark: warm near-black from the portrait backdrop; ink and CTA flip to light. */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --paper: #0d0c0b; --shell: #1a1816; --ink: #f2f0ec; --body: #b3b0aa; --muted: #7d7a75; --rule: #2a2724; --photo: #000000; color-scheme: dark; } }
:root[data-theme="dark"] {
  --paper: #0d0c0b; --shell: #1a1816; --ink: #f2f0ec; --body: #b3b0aa; --muted: #7d7a75; --rule: #2a2724; --photo: #000000; color-scheme: dark; }
html { transition: background-color .3s ease; }
body { transition: color .3s ease; }
.theme { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; margin: -6px -6px -6px 4px; border: 0; border-radius: 9999px;
  background: transparent; color: var(--body); cursor: pointer; }
.theme:hover { color: var(--ink); background: var(--rule); }
.theme svg { width: 17px; height: 17px; }

html, body { min-height: 100%; overflow-x: clip; }
html { scroll-behavior: smooth; }
html { background: var(--paper); }
body { background: transparent; /* glyph field canvas (z-index -1) shows between html and body content */ color: var(--ink); font-family: var(--sans); font-size: 17px; padding-inline: var(--gutter); padding-block: 0 72px;
  box-sizing: border-box; -webkit-font-smoothing: antialiased; }
body.locked { overflow: hidden; }
.wrap { max-width: var(--max); margin: 0 auto; display: flex; flex-direction: column; gap: clamp(112px, 12vw, 176px); }
a { color: inherit; }
a:focus-visible, button:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }
.mono { font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); font-variant-numeric: tabular-nums; }

/* Top bar */
/* Solid bar: a translucent one left a pale band across the cards scrolling under it (user 2026-10-15). */
.topbar { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 20; background: var(--paper); margin-inline: calc(-1 * var(--gutter)); padding: 20px var(--gutter);
  box-shadow: 0 1px 0 var(--rule); }
.topbar .in { max-width: var(--max); margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.name { font-size: 16px; font-weight: 500; letter-spacing: -.01em; text-decoration: none; }
nav { display: flex; align-items: center; gap: 32px; }
nav a { font-size: 16px; color: var(--body); text-decoration: none; }
nav a:hover { color: var(--ink); }

/* Intro */
.intro { display: flex; flex-direction: column; gap: 36px; padding-top: clamp(80px, 9vw, 140px); }
h1 { font-weight: 300; font-size: clamp(44px, 8vw, 112px); line-height: .96; letter-spacing: -.05em; margin: 0; text-wrap: balance; max-width: 12ch; }
.lede { margin: 0; color: var(--body); font-size: clamp(19px, 1.6vw, 22px); line-height: 1.55; max-width: 46ch; }

/* Section heads */
.sec { display: flex; flex-direction: column; gap: clamp(40px, 4.5vw, 64px); scroll-margin-top: 80px; }
.sh { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; border-top: 1px solid var(--ink); padding-top: 18px; }
h2 { font-weight: 300; font-size: clamp(34px, 4.6vw, 60px); letter-spacing: -.04em; line-height: 1; margin: 0; }
.sh p { margin: 0; color: var(--body); font-size: 17px; max-width: 38ch; text-align: right; }

/* Works board: masonry of clips (CSS columns), tiles keep each clip's own ratio */
.board { columns: 3; column-gap: clamp(14px, 1.6vw, 24px); }
.clip { position: relative; display: block; width: 100%; margin: 0 0 clamp(14px, 1.6vw, 24px); padding: 0; border: 0; border-radius: 18px; overflow: hidden;
  background: var(--photo); break-inside: avoid; cursor: pointer; isolation: isolate; font: inherit; }
.clip { background-size: cover; background-position: center; }
.clip video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity .3s; }
.clip video.on { opacity: 1; }
.clip .cap { position: absolute; z-index: 2; left: 14px; bottom: 12px; font-size: 14px; color: #fff; opacity: 0; transform: translateY(4px); transition: opacity .25s, transform .25s; pointer-events: none; text-shadow: 0 1px 8px rgba(0,0,0,.6); }
.clip:hover .cap, .clip:focus-visible .cap { opacity: 1; transform: none; }
.clip::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: 0; transition: opacity .25s; background: linear-gradient(0deg, rgba(0,0,0,.6) 0%, rgba(0,0,0,0) 45%); }
.clip:hover::after, .clip:focus-visible::after { opacity: 1; }
@media (max-width: 900px) { .board { columns: 2; } }
@media (hover: none) { .clip .cap { opacity: 1; transform: none; } }

/* Works grid (old case cards, unused) */
.works { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(20px, 2vw, 32px); }
.work { position: relative; display: block; aspect-ratio: 4 / 3; border-radius: 22px; overflow: hidden; background: var(--photo); color: var(--on-dark);
  text-decoration: none; box-shadow: var(--shadow); isolation: isolate; transition: transform .25s ease; cursor: pointer; border: 0; padding: 0; font: inherit; text-align: left; width: 100%; }
.work.wide { grid-column: 1 / -1; aspect-ratio: 21 / 9; }
.work:hover .cover { opacity: .86; }
.cover { position: absolute; inset: 0; }
.cover img, .cover video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Work placeholder (user 2026-10-15: tech minimal instead of the Revea gradient): fine drawing grid, a crosshair
   at the centre, corner ticks and a mono "In development" tag. */
.cover.ph { --g: rgba(255,255,255,.055); --g2: rgba(255,255,255,.11); background-color: #111113;
  background-image: linear-gradient(var(--g2) 1px, transparent 1px), linear-gradient(90deg, var(--g2) 1px, transparent 1px),
    linear-gradient(var(--g) 1px, transparent 1px), linear-gradient(90deg, var(--g) 1px, transparent 1px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px; background-position: center; }
.cover.ph::before { content: ""; position: absolute; inset: 14px; pointer-events: none;
  background: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)) 0 0 / 14px 1px no-repeat, linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)) 0 0 / 1px 14px no-repeat,
    linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)) 100% 0 / 14px 1px no-repeat, linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)) 100% 0 / 1px 14px no-repeat,
    linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)) 0 100% / 14px 1px no-repeat, linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)) 0 100% / 1px 14px no-repeat,
    linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)) 100% 100% / 14px 1px no-repeat, linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)) 100% 100% / 1px 14px no-repeat; }
.ph-x { position: absolute; left: 50%; top: 50%; width: 44px; height: 44px; translate: -50% -50%; border: 1px solid rgba(255,255,255,.35); border-radius: 50%; }
.ph-x::before, .ph-x::after { content: ""; position: absolute; background: rgba(255,255,255,.55); }
.ph-x::before { left: 50%; top: -14px; bottom: -14px; width: 1px; }
.ph-x::after { top: 50%; left: -14px; right: -14px; height: 1px; }
.ph-tag { position: absolute; top: 30px; left: 34px; display: inline-flex; align-items: center; gap: 10px; font-family: var(--mono); font-size: 11px;
  letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.72); }
.ph-tag::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #f3c193; animation: ph-blink 1.6s ease-in-out infinite; }
@keyframes ph-blink { 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .cover.ph::before { content: none; }   /* placeholder: plain drawing grid only (no tag, crosshair, corner ticks; user 2026-10-15) */ }
.work::after { content: ""; position: absolute; inset: 0; z-index: 1; background: linear-gradient(0deg, rgba(0,0,0,.82) 0%, rgba(0,0,0,.35) 32%, rgba(0,0,0,0) 60%); }
.work .cap { position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; padding: clamp(18px, 2.4vw, 28px); display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; }
.work h3 { font-weight: 400; font-size: clamp(24px, 2.6vw, 34px); line-height: 1.08; letter-spacing: -.025em; margin: 0; }
.work .cap p { margin: 8px 0 0; color: var(--on-dark-soft); font-size: 16px; }
.work .mono { color: var(--on-dark-soft); flex: none; }

/* Plug-ins: Revea product */
.prod { display: flex; flex-direction: column; gap: clamp(96px, 10vw, 160px); }
.prod .ph-head { margin-bottom: clamp(-72px, -4vw, -32px); }   /* the head stays close to its hero */
.ph-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 24px 48px; align-items: end; }
.ph-head h1 { font-weight: 300; font-size: clamp(64px, 11vw, 150px); line-height: .9; letter-spacing: -.06em; margin: 0; max-width: none; }
.ph-head h1 span { display: block; margin-top: 18px; font-size: clamp(26px, 3vw, 40px); line-height: 1.1; letter-spacing: -.03em; color: var(--body); text-wrap: balance; }

/* Plug-in page */
.page { gap: 64px; }
.crumb { display: flex; gap: 10px; padding-top: 48px; margin-bottom: -24px; font-size: 15px; color: var(--muted); }
.crumb a { color: var(--body); text-decoration: none; }
.crumb a:hover { color: var(--ink); }
nav a[aria-current] { color: var(--ink); }
.sh .more { font-size: 17px; color: var(--body); text-decoration: none; white-space: nowrap; }
.sh .more:hover { color: var(--ink); }

/* Plug-in bento: 6 columns; a tile spans 2-6 columns and 1-2 rows (size classes below). With one plug-in it is
   one large tile and the in-development tile; more plug-ins drop in as more tiles. */
.bento { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); grid-auto-rows: clamp(220px, 22vw, 340px); gap: clamp(20px, 2vw, 32px); }
.pl { position: relative; display: block; border-radius: 22px; overflow: hidden; background: var(--photo); color: var(--on-dark); text-decoration: none;
  box-shadow: var(--shadow); isolation: isolate; transition: transform .25s ease; }
a.pl:hover .media { opacity: .86; }
.pl-l { grid-column: span 4; grid-row: span 2; }
.pl-m { grid-column: span 3; grid-row: span 2; }
.pl-s { grid-column: span 2; grid-row: span 2; }
.pl-w { grid-column: span 6; grid-row: span 2; }
.pl-sq { grid-column: span 2; grid-row: span 1; }
.pl .media { position: absolute; inset: 0; }
.pl .media img, .pl .media video { width: 100%; height: 100%; object-fit: cover; display: block; }
.pl::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(0deg, rgba(0,0,0,.85) 0%, rgba(0,0,0,.4) 34%, rgba(0,0,0,0) 62%); }
.pl .cap { position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; padding: clamp(18px, 2.4vw, 28px); display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; }
.pl h3 { font-weight: 400; font-size: clamp(26px, 3vw, 40px); line-height: 1; letter-spacing: -.03em; margin: 0; }
.pl .cap p { margin: 10px 0 0; color: var(--on-dark-soft); font-size: 17px; max-width: 40ch; }
.pl .go { flex: none; display: inline-flex; align-items: center; height: 40px; padding: 0 18px; border-radius: 9999px; background: var(--on-dark); color: #0c0a09; font-size: 15px; font-weight: 500; }   /* fixed dark text: --ink is white in dark */
.pl.soon { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--rule); }
.pl.soon::after { content: none; }
.pl.soon .cap p { color: var(--body); }
.ph-head .lede { grid-column: 1; }
.acts { grid-column: 2; grid-row: 1 / span 2; display: flex; flex-direction: column; align-items: flex-end; gap: 12px; }
.pname { font-size: 15px; font-weight: 500; }
.cta { display: inline-flex; align-items: center; height: 44px; padding: 0 22px; border-radius: 9999px; background: var(--ink); color: var(--paper);
  font-weight: 500; font-size: 16px; text-decoration: none; white-space: nowrap; }
.cta.ghost { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 24%, transparent); }
.cta.off { color: var(--muted); cursor: default; }

.hero { position: relative; display: block; color: inherit; text-decoration: none; transition: transform .2s ease; background: var(--shell); border-radius: 32px; padding: 12px; box-shadow: var(--shadow); }
.hero:hover .tile { opacity: .92; }
.hero .tile { aspect-ratio: 16 / 9; border-radius: 24px; }
.hero .cap { position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; padding: clamp(18px, 3vw, 32px); }
.hero h4 { font-weight: 400; font-size: clamp(22px, 2.4vw, 30px); margin: 0; letter-spacing: -.02em; }
.hero .cap p { margin: 6px 0 0; color: var(--on-dark-soft); font-size: 16px; max-width: 52ch; }
.val { position: absolute; z-index: 3; right: clamp(18px, 3vw, 32px); top: clamp(16px, 2.6vw, 28px); color: var(--on-dark); font-family: var(--mono); font-size: 11px;
  letter-spacing: .06em; text-transform: uppercase; font-variant-numeric: tabular-nums; pointer-events: none; }
.btn { flex: none; display: inline-flex; align-items: center; height: 48px; padding: 0 32px; border-radius: 14px; background: var(--on-dark); color: #0c0a09; font-size: 16px; font-weight: 500; }

.row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(20px, 2vw, 32px); }
.card { position: relative; aspect-ratio: 4 / 3; border-radius: 22px; overflow: hidden; background: var(--photo); color: var(--on-dark); box-shadow: var(--shadow); isolation: isolate; }
.tile { position: relative; overflow: hidden; background: var(--photo); color: var(--on-dark); isolation: isolate; touch-action: pan-y; }
.card .tile { position: absolute; inset: 0; }
.tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.tile canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.tile::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(0deg, rgba(0,0,0,.9) 0%, rgba(0,0,0,.5) 30%, rgba(0,0,0,0) 58%); }
.card .cap { position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; padding: 20px; pointer-events: none; }
.bh { display: flex; flex-direction: column; gap: 12px; margin-bottom: clamp(-96px, -5vw, -40px); }
.bh h2 { font-size: clamp(30px, 3.4vw, 48px); }
.bh p { margin: 0; color: var(--body); font-size: 18px; max-width: 46ch; }
.card h4 { font-weight: 400; font-size: clamp(26px, 2.4vw, 34px); line-height: 1.08; letter-spacing: -.025em; margin: 0; text-wrap: balance; }
.card .cap p { margin: 10px 0 0; color: var(--on-dark-soft); font-size: 16px; line-height: 1.45; max-width: 40ch; }
.label { position: absolute; z-index: 2; left: 20px; top: 18px; right: 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: 15px; font-weight: 500; pointer-events: none; }
.label .mono { color: var(--on-dark); font-size: 11px; text-transform: none; letter-spacing: .02em; }
.track { position: absolute; z-index: 3; left: 0; right: 0; bottom: 0; height: 2px; background: rgba(255,255,255,.12); }
.bar { height: 100%; width: 0; background: var(--on-dark); }
.split .top { clip-path: inset(0 0 0 var(--x, 50%)); }
.split .handle { position: absolute; z-index: 1; top: 0; bottom: 0; left: var(--x, 50%); width: 1px; background: rgba(255,255,255,.8); }
.lens .top { -webkit-mask: radial-gradient(circle at var(--lx, 50%) var(--ly, 40%), #000 0 var(--lr, 70px), transparent calc(var(--lr, 70px) + 1px));
  mask: radial-gradient(circle at var(--lx, 50%) var(--ly, 40%), #000 0 var(--lr, 70px), transparent calc(var(--lr, 70px) + 1px)); }
.blur .top { filter: blur(var(--b, 8px)); transform: scale(1.04); -webkit-mask: url("../media/far.f87ad300.jpg") center / cover; mask: url("../media/far.f87ad300.jpg") center / cover; -webkit-mask-mode: luminance; mask-mode: luminance; }
.smooth .top { opacity: var(--o, .5); }

/* Buy block: the only bordered object on the page (it is the place where money changes hands) */
.buy { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 40px clamp(48px, 6vw, 96px); border-radius: 32px; padding: clamp(28px, 5vw, 64px);
  box-shadow: inset 0 0 0 1px var(--rule); scroll-margin-top: 80px; }
.buy h4 { font-weight: 300; font-size: clamp(30px, 3.6vw, 48px); letter-spacing: -.04em; line-height: 1.05; margin: 0 0 20px; }
.buy p { margin: 0; color: var(--body); font-size: 18px; line-height: 1.6; max-width: 44ch; }
/* Buy (2026-10-15 calm pass): one big heading + one paragraph on the left; on the right one line item (licence ...
   price), a full-width button and a note. The price is body size, muted until Paddle fills it (.set). */
.buy-r { display: flex; flex-direction: column; justify-content: flex-end; gap: 16px; min-width: 0; }
.buy-line { display: flex; justify-content: space-between; align-items: baseline; gap: 4px 12px; flex-wrap: wrap; padding-bottom: 16px;
  border-bottom: 1px solid var(--rule); font-size: 17px; }
.price { color: var(--muted); font-variant-numeric: tabular-nums; }
.price.set { color: var(--ink); font-weight: 500; }
.buy .cta { width: 100%; justify-content: center; height: 48px; padding: 0 28px; border: 0; font-family: var(--sans); font-size: 16px; cursor: pointer; }
.buy .cta:disabled { background: transparent; color: var(--muted); box-shadow: inset 0 0 0 1px var(--rule); cursor: default; }
.note { color: var(--muted); font-size: 15px; line-height: 1.5; }

/* About */
.about { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 32px 64px; align-items: end; }
.portrait { margin: 0; border-radius: 22px; overflow: hidden; background: var(--photo); box-shadow: var(--shadow); aspect-ratio: 1; max-width: 100%; }
.portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bio { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.bio .big { font-weight: 300; font-size: clamp(26px, 3vw, 40px); line-height: 1.15; margin-bottom: 12px !important; letter-spacing: -.03em; margin: 0; text-wrap: balance; color: var(--ink); }
.bio p { margin: 0; color: var(--body); font-size: 18px; line-height: 1.6; max-width: 52ch; }
.facts { display: flex; flex-wrap: wrap; gap: 10px 28px; padding-top: 8px; }

footer { display: flex; justify-content: space-between; gap: 24px; border-top: 1px solid var(--rule); padding-top: 24px; color: var(--muted); font-size: 15px; }

/* Full-screen case view */
.case { position: fixed; inset: 0; z-index: 50; background: var(--paper); overflow-y: auto; overscroll-behavior: contain; transform: translateY(100%); visibility: hidden;
  transition: transform .55s cubic-bezier(.2,.7,.1,1), visibility 0s linear .55s; padding-inline: var(--gutter); }
.case.open { transform: none; visibility: visible; transition: transform .55s cubic-bezier(.2,.7,.1,1); }
.case-bar { position: sticky; top: 0; z-index: 3; display: flex; justify-content: flex-end; padding: calc(16px + env(safe-area-inset-top, 0px)) 0 0; pointer-events: none; }
.close { pointer-events: auto; height: 40px; padding: 0 18px; border-radius: 9999px; border: 0; background: var(--ink); color: var(--paper); font: 500 14px var(--sans); cursor: pointer; }
.case-in { max-width: var(--max); margin: -56px auto 0; display: flex; flex-direction: column; gap: clamp(64px, 7vw, 112px); padding-block: 0 120px; }
.case-hero { position: relative; margin-inline: calc(-1 * var(--gutter)); height: min(82vh, 760px); min-height: 360px; background: var(--photo); overflow: hidden; color: var(--on-dark); }
.case-hero .cover::after { content: ""; position: absolute; inset: 0; background: linear-gradient(0deg, rgba(0,0,0,.75), rgba(0,0,0,0) 55%); }
.case-hero .t { position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter) clamp(28px, 4vw, 56px); box-sizing: content-box; }
.case-hero h2 { font-size: clamp(44px, 8vw, 120px); letter-spacing: -.05em; line-height: .94; max-width: 14ch; text-wrap: balance; }
.case-hero .t p { margin: 14px 0 0; color: var(--on-dark-soft); font-size: 18px; max-width: 48ch; }
.meta { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px 24px; border-top: 1px solid var(--ink); padding-top: 16px; }
.meta div { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.meta b { font-weight: 400; font-size: 18px; }
.blk { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 16px 48px; }
.blk h3 { font-weight: 400; font-size: 24px; letter-spacing: -.02em; margin: 0; }
.blk p { margin: 0; color: var(--body); font-size: 20px; line-height: 1.6; max-width: 60ch; }
.gal { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.gal .m { position: relative; border-radius: 22px; overflow: hidden; aspect-ratio: 4 / 3; background: var(--photo); }
.gal .m.full { grid-column: 1 / -1; aspect-ratio: 16 / 9; }
.gal .m .mono { position: absolute; left: 18px; bottom: 16px; color: var(--on-dark-soft); }
.next { display: flex; justify-content: space-between; align-items: baseline; gap: 24px; border-top: 1px solid var(--ink); padding-top: 18px; background: none; border-left: 0; border-right: 0; border-bottom: 0;
  font: inherit; color: inherit; text-align: left; cursor: pointer; width: 100%; }
.next span:last-child { font-weight: 300; font-size: clamp(30px, 4vw, 52px); letter-spacing: -.04em; }

@media (max-width: 1024px) { .meta { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px) {
  .wrap { gap: 96px; }
  nav { gap: 18px; }
  .works, .gal, .about, .blk, .buy, .row { grid-template-columns: 1fr; }
  .work.wide, .work { aspect-ratio: 4 / 5; }
  .gal .m.full { aspect-ratio: 4 / 3; }
  .ph-head { grid-template-columns: 1fr; }
  .acts { grid-column: 1; grid-row: auto; flex-direction: row; flex-wrap: wrap; align-items: center; }
  .sh { flex-direction: column; align-items: flex-start; } .sh p { text-align: left; }
  .hero .tile { aspect-ratio: 4 / 5; }
  .hero .cap { flex-direction: column; align-items: stretch; }
  .btn { height: 44px; justify-content: center; }
}
@media (max-width: 760px) {
  .bento { grid-template-columns: 1fr; grid-auto-rows: auto; }
  .pl { grid-column: auto !important; grid-row: auto !important; aspect-ratio: 4 / 5; }
  .pl.soon { aspect-ratio: auto; min-height: 160px; }
  .pl .cap { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 520px) { .row { grid-template-columns: 1fr; } nav a.opt { display: none; }
  /* Phone top bar: one line; Works is dropped (the home page scrolls into it anyway). */
  .topbar .name, .topbar nav a { white-space: nowrap; font-size: 15px; } .topbar nav { gap: 14px; } .topbar .in { gap: 12px; }
  .topbar nav a:first-child { display: none; } }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } .hero, .work, .case, .case.open { transition: none; } }

/* Display face: Inter Tight for headings only; running text uses Inter (Tight was cramped at 17-18 px).
   Tracking relaxed for Inter Tight (already tight; Geist values above were -.04..-.06em). */
h1, h2, h3, h4, .big, .next span:last-child { font-family: var(--display); }
h1, .case-hero h2 { letter-spacing: -.035em; }
.ph-head h1 { letter-spacing: -.045em; }
h2, .buy h4, .next span:last-child { letter-spacing: -.028em; }
.ph-head h1 span, .bio .big, .pl h3 { letter-spacing: -.02em; }
.work h3, .card h4 { letter-spacing: -.015em; }

/* v3 flat technical (user 2026-10-15, after the grid redesign was rejected: "grids must not be a background").
   Technical, lightly brutalist, minimal: no shadows, no lifts, no white hero shell, no background grid. The technical
   feel comes from ink hairlines, "+" crop marks on section rules and small mono notes (index numbers, figure
   captions, counts); big medium-weight type carries the page. Photo cards keep the dark fade, original roundings stay. */
.hero { background: none; padding: 0; border-radius: 24px; }   /* original roundings kept (user 2026-10-15) */
.hero .tile { border-radius: 24px; }
.card .tile::before, .hero .tile::before { content: ""; position: absolute; inset: 0 0 auto; height: 40%; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,.45), rgba(0,0,0,0)); }   /* label legibility without text-shadow */
.cta.ghost, .pl.soon { box-shadow: inset 0 0 0 1px var(--ink); }
.buy { box-shadow: inset 0 0 0 1px var(--rule); align-items: end; }

/* Top bar: ink hairline, mono nav */
.topbar { box-shadow: none; border-bottom: 1px solid var(--ink); }
nav a { font-family: var(--mono); font-size: 12px; letter-spacing: .06em; text-transform: uppercase; }
.lang { font-family: var(--mono); }

/* Big type: medium weight, tight */
h1 { font-weight: 500; font-size: clamp(52px, 10.5vw, 196px); line-height: .88; letter-spacing: -.06em; max-width: 13ch; }
.ph-head h1 { --hs: clamp(104px, 23vw, 380px); font-weight: 500; font-size: var(--hs); line-height: .78; letter-spacing: -.075em; margin-left: calc(var(--hs) * -.05); }   /* optical: the R stem sits on the text edge */
.ph-head h1 span { margin: 28px 0 0 calc(var(--hs) * .05);   /* undo the h1 pull so the subline aligns with the lede */ font-weight: 400; font-size: clamp(22px, 2.4vw, 32px); letter-spacing: -.02em; color: var(--ink); }
h2, .case-hero h2 { font-weight: 500; letter-spacing: -.055em; line-height: .9; }
h2 { font-size: clamp(44px, 7.2vw, 128px); }
.bh h2 { font-size: clamp(36px, 5vw, 80px); }
.case-hero h2 { font-size: clamp(52px, 10vw, 180px); }
.buy h4, .bio .big, .next span:last-child { font-weight: 500; letter-spacing: -.04em; }
.work h3, .card h4, .pl h3, .hero h4 { font-weight: 500; letter-spacing: -.03em; }

/* Mono notes and headings stay clean: no rules or crop marks above headings (user 2026-10-15: they spoil the heading
   that follows). Technical detail comes from mono notes, figure captions and the dot-matrix meters below. */
.tick { display: flex; justify-content: space-between; gap: 16px; margin-bottom: clamp(8px, 2vw, 28px); }
.intro { gap: 32px; padding-top: clamp(56px, 7vw, 112px); }
.sh { border-top: 0; padding-top: 0; }
.fig { display: flex; justify-content: space-between; gap: 16px; margin-top: 12px; }
.work .no { position: absolute; z-index: 2; top: 26px; right: 30px; color: var(--on-dark-soft); }
.cover.ph::before { content: none; }   /* placeholder: plain drawing grid only (no tag, crosshair, corner ticks; user 2026-10-15) */
footer { border-top-color: var(--rule); padding-top: 12px; font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
@media (max-width: 760px) { .tick span:nth-child(2) { display: none; } }

/* Dot-matrix meter, Nothing OS style: columns of square dots on a faint dot field, heights stepped (never smooth).
   .vz = live "voice" strip (home intro); .vz[data-p] = Reveal Progress meter (Revea page, lit up to the value).
   Columns are drawn by the shared script in build_site.py; one dot cell = 6 px. */
.vz { --dot: var(--ink); --faint: color-mix(in srgb, var(--ink) 12%, transparent); display: flex; align-items: flex-end; overflow: hidden;
  height: calc(var(--rows, 9) * 6px); background: radial-gradient(circle, var(--faint) 0 1.6px, transparent 2px) 0 100% / 6px 6px; }
.vz i { flex: none; width: 6px; height: 6px; background: radial-gradient(circle, var(--dot) 0 2px, transparent 2.4px) 0 100% / 6px 6px; }
.vz i.off { background-image: radial-gradient(circle, color-mix(in srgb, var(--ink) 30%, transparent) 0 2px, transparent 2.4px); }
.intro .vz { margin-top: clamp(16px, 3vw, 40px); }
.hfig .vz { --rows: 5; margin-top: 14px; }
/* Shadow only as hover feedback on whole, content-filled, clickable elements (user 2026-10-15): work cards, plug-in
   tiles, the Revea hero link. Static elements, look cards and buttons stay flat. */
.work, a.pl, .hero { transition: box-shadow .35s ease; }
.work:hover, a.pl:hover, .hero:hover { box-shadow: 0 28px 56px -30px rgba(12,10,9,.45), 0 4px 12px -6px rgba(12,10,9,.12); }
:root[data-theme="dark"] :is(.work, a.pl, .hero):hover { box-shadow: 0 28px 56px -30px rgba(0,0,0,.9), 0 0 0 1px rgba(255,255,255,.08); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) :is(.work, a.pl, .hero):hover { box-shadow: 0 28px 56px -30px rgba(0,0,0,.9), 0 0 0 1px rgba(255,255,255,.08); } }
/* v4 calm (user 2026-10-15, ElevenLabs reference, docs/critique-home-2026-10-15.md): Onest display face for
   headings (Cyrillic + latin), short home hero at a moderate size, normal tracking, sans sentence-case nav,
   quieter dot meter. Overrides the v3 rules above. */
:root { --display: "Onest", "Inter", "Segoe UI", system-ui, sans-serif; }
h1 { font-weight: 500; font-size: clamp(40px, 6vw, 76px); line-height: 1.04; letter-spacing: -.025em; max-width: 16ch; }
h2, .case-hero h2 { font-weight: 500; letter-spacing: -.025em; line-height: 1.04; }
.bh h2 { font-size: clamp(32px, 4vw, 56px); }
/* Benefits (user 2026-10-15, marketing): three plain statements under the looks; no labels, no boxes. */
.why { display: flex; flex-direction: column; gap: 20px; }
.why h3 { margin: 0; font-weight: 500; font-size: clamp(24px, 2.2vw, 30px); letter-spacing: -.025em; line-height: 1.1; }
.why-row { display: flex; flex-direction: column; gap: 18px; }
.why-row h4 { font-weight: 500; font-size: 18px; letter-spacing: -.01em; margin: 0 0 4px; }
.why-row p { margin: 0; color: var(--body); font-size: 16px; max-width: 44ch; }
/* Revea bento (user 2026-10-15): big before / after on the left, banner + benefits stacked on the right. */
.bento2 { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: clamp(20px, 2.4vw, 36px); align-items: stretch; }
.ba-col { display: flex; }
.ba { flex: 1; min-height: 520px; border-radius: 24px; cursor: ew-resize; }
.ba .top { clip-path: inset(0 0 0 var(--x, 50%)); }
.ba .handle { position: absolute; z-index: 1; top: 0; bottom: 0; left: var(--x, 50%); width: 1px; background: rgba(255,255,255,.8); }
.ba .tag { position: absolute; z-index: 2; top: 16px; padding: 6px 12px; border-radius: 9999px; background: rgba(0,0,0,.42); color: #fff; font-size: 13px; }
.ba .tag.l { left: 16px; } .ba .tag.r { right: 16px; }
.ba .cap { position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; padding: clamp(18px, 2.4vw, 28px); pointer-events: none; }
.ba .cap h4 { font-weight: 500; font-size: clamp(22px, 2.4vw, 30px); margin: 0; letter-spacing: -.02em; }
.ba .cap p { margin: 8px 0 0; color: var(--on-dark-soft); font-size: 16px; max-width: 40ch; }
.side { display: flex; flex-direction: column; gap: clamp(24px, 3vw, 40px); min-width: 0; }
.side .hero .tile { aspect-ratio: 4 / 5; }
.side .hero .cap { flex-direction: row; align-items: center; gap: 14px; padding: 18px 20px; }
.side .hero .cap p { max-width: 34ch; }
@media (max-width: 900px) { .bento2 { grid-template-columns: 1fr; } .ba { min-height: 0; aspect-ratio: 4 / 5; } .ba-col { order: 2; } .side { order: 1; } }
.case-hero h2 { font-size: clamp(40px, 6vw, 84px); }
.ph-head h1 { letter-spacing: -.05em; }
.buy h4, .bio .big, .next span:last-child, .work h3, .card h4, .pl h3, .hero h4 { letter-spacing: -.015em; }
.intro { gap: 24px; padding-top: clamp(64px, 9vw, 136px); }
.lede { max-width: 40ch; }
nav a { font-family: var(--sans); font-size: 15px; letter-spacing: 0; text-transform: none; }
.lang { font-family: var(--sans); }
.intro .vz { --rows: 5; --dot: color-mix(in srgb, var(--ink) 38%, transparent); margin-top: clamp(24px, 4vw, 56px); }
.lede { text-wrap: pretty; }

/* Revea head over the intro film (user 2026-10-15): the silent 720p loop rv_intro_bg.mp4 plays behind the wordmark,
   a bottom-up shade keeps the text readable; "Watch the intro" opens the full film with sound in dialog.filmbox. */
.prod .ph-head.stage { margin-bottom: 0; }
.prod > .amb:first-child { margin-bottom: clamp(24px, 4vw, 64px); }   /* more air between the head film and the demo hero, so their glows do not meet (user 2026-10-15) */
.stage { position: relative; isolation: isolate; overflow: hidden; border-radius: 22px; background: #0c0a09; color: #fff;
  min-height: min(84svh, 860px); align-content: end; padding: clamp(24px, 4vw, 56px); }
.stage .bgv { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; }
.stage::before { content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top, rgba(0,0,0,.82), rgba(0,0,0,.35) 55%, rgba(0,0,0,.45)); }
.stage h1 { --hs: clamp(88px, 17vw, 280px); }
.stage h1, .stage h1 span { color: #fff; }
.stage .lede { color: rgba(255,255,255,.74); }
.stage .cta { background: #fff; color: #0c0a09; }
.stage .cta.ghost { background: rgba(0,0,0,.18); color: #fff; box-shadow: inset 0 0 0 1px rgba(255,255,255,.55); }
.stage .cta.ghost:hover { background: rgba(255,255,255,.12); }
/* Home head on the same stage (user 2026-10-15): the name is the wordmark (two words, so smaller than "Revea" and
   allowed to wrap); buttons sit in a row under the lede. */
.hstage { margin-top: clamp(16px, 3vw, 40px); grid-template-columns: 1fr; }
/* Full-bleed home stage (user 2026-10-15): spans the window minus a 12 px frame, keeps the rounded plate look.
   --sbw (scrollbar width) is set by glyphs.js so the plate stays centred. */
.hstage { --edge: clamp(8px, 1vw, 14px); box-sizing: border-box; width: calc(100vw - var(--sbw, 0px) - var(--edge) * 2);
  margin-inline: calc(50% - (100vw - var(--sbw, 0px)) / 2 + var(--edge)); border-radius: clamp(20px, 2.4vw, 32px);
  min-height: min(88svh, 940px); padding-inline: max(calc(var(--gutter) - var(--edge)), calc((100vw - var(--sbw, 0px) - var(--max)) / 2 - var(--edge))); }   /* text left edge = top bar logo */
.hstage h1 { --hs: clamp(64px, 11.5vw, 196px); line-height: .86; }
.hstage .acts { grid-column: 1; grid-row: auto; flex-direction: row; flex-wrap: wrap; align-items: center; }
#watch { font: inherit; font-size: 15px; cursor: pointer; border: 0; }
#watch .mono { color: rgba(255,255,255,.66); margin-left: 6px; }
.filmbox { padding: 0; border: 0; background: transparent; width: min(92vw, calc((100svh - 120px) * 16 / 9)); max-width: none; overflow: visible; }
.filmbox::backdrop { background: rgba(6,5,4,.9); }
#clipbox { width: min(92vw, calc((100svh - 120px) * var(--r, 1.7778))); }
.filmbox video { display: block; width: 100%; aspect-ratio: 16 / 9; border-radius: 16px; background: #000; }
.fb-close { position: fixed; top: 20px; right: 20px; height: 40px; padding: 0 18px; border-radius: 9999px; border: 0; background: #fff; color: #0c0a09; font: 500 14px var(--sans); cursor: pointer; }

/* Glyph field (user 2026-10-15, every page): canvas#glyphs behind the page draws mono characters on a grid in slow
   noise patches, lit by the cursor falloff and rare sweeping lines; it fades out softly around every element so it
   never crosses text, cards or the stage. Faint blue-grey; --glyph-max is the peak alpha. Script src/glyphs.js. */
#glyphs { position: fixed; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; }
:root { --glyph: #6f86a6; --glyph-max: .5; }
:root[data-theme="dark"] { --glyph: #8fa6c6; --glyph-max: .46; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --glyph: #8fa6c6; --glyph-max: .46; } }

/* Top bar (user 2026-10-15): no hard ink rule; tinted translucent paper + backdrop blur (user lifted the glass ban
   for the top bar only). */
.topbar { border-bottom: 0; box-shadow: none; background: color-mix(in srgb, var(--paper) 72%, transparent);
  -webkit-backdrop-filter: saturate(1.6) blur(18px); backdrop-filter: saturate(1.6) blur(18px); }

/* Ambient glow (user 2026-10-15): .amb wraps a key media block; canvas.glow behind it repeats the block's live
   colours, stretched past its edges and blurred wide and faint. Not on cards. html clips the overflow sideways. */
html { overflow-x: clip; }
/* Same recipe as the live demo's glow (user 2026-10-15): the 64x36 canvas covers the block, scaled up a little and
   blurred wide by CSS (smooth; in-canvas blur + upscale looked pixelated and cut off), blended onto the page:
   multiply on white, screen on dark. No isolation on .amb, so the blend reaches the page background. */
.amb { position: relative; }
.amb > .glow { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none;
  transform: scale(1.04); filter: blur(clamp(56px, 7vw, 96px)) saturate(1.6); opacity: .22; mix-blend-mode: multiply; }
:root[data-theme="dark"] .amb > .glow { opacity: .32; mix-blend-mode: screen; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .amb > .glow { opacity: .32; mix-blend-mode: screen; } }
.hfig .amb { display: block; }

/* Legal pages (terms / refund / privacy) and footer links. */
.legal article { max-width: 68ch; margin: 0 auto; padding: clamp(32px, 6vw, 80px) 0; }
.legal h1 { font-weight: 500; letter-spacing: -.03em; margin: 0 0 8px; }
.legal .meta { color: var(--muted); margin: 0 0 32px; }
.legal h2 { font-size: 20px; font-weight: 500; margin: 32px 0 8px; }
.legal p { color: var(--body); line-height: 1.65; margin: 0 0 12px; }
.legal a, .legal-links a { color: inherit; text-decoration: underline; text-decoration-color: var(--rule); text-underline-offset: 3px; }
.legal-links { display: flex; gap: 20px; }
