/* Self-hosted (was Google Fonts): every page needs Inter, and a cross-origin
   stylesheet + font fetch on every single navigation added noticeable lag,
   worse on pages mixing Latin and Cyrillic text since that pulled two
   separate subset files. Same-origin local files remove that round trip. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/inter-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

:root {
  color-scheme: light;
  --bg: #ffffff;
  --bg-elevated: #ffffff;
  --ink: #111111;
  --ink-secondary: #111111;
  --hairline: rgba(17,17,17,.14);
  --accent: #111111;
  --accent-ink: #ffffff;
  --nav-w: 220px;
  --font-display: 'Inter', "Helvetica Neue", Helvetica, Arial, sans-serif;
}
@media (prefers-contrast: more) {
  :root { --hairline: currentColor; --ink-secondary: var(--ink); }
}

*, *::before, *::after { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { scroll-behavior: auto; }
html, body { background: var(--bg); margin: 0; }
body {
  font-family: var(--font-display);
  font-size: 17px;
  line-height: 1.6;
  letter-spacing: 0;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-kerning: normal;
}
::selection { background-color: var(--ink); color: #fff; }
a { color: inherit; text-decoration: none; }

.h-display {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: .92;
  font-size: clamp(3.25rem, 12vw, 9rem);
  color: var(--ink);
}
.side-nav-link {
  transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease, opacity 150ms ease, transform 150ms ease;
}

/* ---------- Side nav: persistent list of sections, always top-left ---------- */
.side-nav {
  position: fixed;
  top: 0; left: 0;
  width: var(--nav-w);
  padding: 24px 20px;
  display: flex;
  flex-direction: column;
  gap: 9px;
  z-index: 50;
  background: var(--bg);
}
.side-nav-link {
  font-family: var(--font-display); font-weight: 700;
  font-size: .85rem; letter-spacing: .01em;
  color: var(--ink);
  text-decoration: none;
  width: fit-content;
}
.side-nav-link:hover { opacity: .55; }
.side-nav-link.active { text-decoration: underline; text-underline-offset: 3px; }

.lang-toggle { display: flex; align-items: center; gap: .5rem; margin-top: 6px; }
.lang-btn {
  font-family: var(--font-display); font-size: .78rem; font-weight: 700; letter-spacing: .01em;
  color: var(--ink-secondary);
  appearance: none; -webkit-appearance: none;
  background: transparent; border: none; padding: 0; margin: 0;
  cursor: pointer;
}
.lang-btn.active { color: var(--ink); }

/* Page content sits to the right of the fixed side nav */
.content-with-nav { margin-left: var(--nav-w); padding: 28px 32px 96px; min-height: 100vh; }

@media (max-width: 720px) {
  /* A fixed 220px nav doesn't fit a ~390px phone screen the way it does
     desktop, so it can't stay fixed here without either eating most of the
     width or sitting on top of scrolled content and covering it. Instead
     the nav scrolls away normally at the top of the page, and the text
     block below starts where the longest nav label ends, not at the nav's
     own left edge. */
  .side-nav { position: static; width: auto; }
  .content-with-nav {
    margin-left: 0;
    padding: 24px 20px 60px 120px;
  }
}

/* ---------- Bio block (About / Skills pages): plain stacked lines, no cards ---------- */
.bio-block { max-width: 520px; margin-top: 6vh; margin-left: clamp(40px, 10vw, 140px); }
@media (max-width: 720px) {
  .bio-block { margin: 0; width: 100%; max-width: none; }
}
.bio-block p {
  margin: 0 0 20px;
  font-family: var(--font-display);
  font-size: .875rem;
  font-weight: 700;
  line-height: 20px;
  color: var(--ink);
}
.bio-block p:last-child { margin-bottom: 0; }
.bio-name-line { margin-bottom: 40px !important; }
.bio-name-line:not(:first-child) { margin-top: 40px; }
.skill-line { margin-bottom: 0 !important; }
.bio-langs { margin-bottom: 20px; }
.bio-langs:last-child { margin-bottom: 0; }
.bio-langs p { margin-bottom: 0; }
.bio-lang-label { margin-bottom: 4px !important; }

/* ---------- Case list (Cases page): click a title to reveal it ---------- */
.case-toggle {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font-family: var(--font-display);
  font-size: .875rem;
  font-weight: 700;
  line-height: 20px;
  color: var(--ink);
  cursor: pointer;
}
.case-item:not(:first-child) .case-toggle { margin-top: 20px; }
.case-toggle:hover { opacity: .6; }
.case-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .25s ease;
}
.case-item.open .case-panel { grid-template-rows: 1fr; }
.case-panel-inner { overflow: hidden; min-height: 0; padding-top: 20px; }
.case-item.open .case-panel-inner { padding-bottom: 20px; }
@media (prefers-reduced-motion: reduce) {
  .case-panel { transition: none; }
}
.case-star { font-size: .7em; margin-left: 1px; }
.bio-block a:hover { opacity: .6; }

/* ---------- Cross overlay: fixed crosshair, inverts text it crosses ----------
   Painted white and blended with mix-blend-mode:difference against the white
   page background, so it reads as solid black, and any black text caught
   underneath flips to white. Single element clipped into a plus shape so the
   arms never double-blend against each other. Always on screen, top to bottom
   of the viewport, unaffected by scroll position. */
.cross-bar {
  position: fixed;
  inset: 0;
  background: #fff;
  mix-blend-mode: difference;
  z-index: 60;
  pointer-events: none;
  clip-path: polygon(
    63% 0%, 76% 0%, 76% 53%, 100% 53%, 100% 63%, 76% 63%,
    76% 100%, 63% 100%, 63% 63%, 0% 63%, 0% 53%, 63% 53%
  );
}
@media (max-width: 720px) {
  /* The tall vertical arm dwarfs a phone-width viewport; on mobile the
     splash reads better as just the glitching wordmark, no crosshair. */
  .cross-bar { display: none; }
}

/* ---------- Splash / entry screen ---------- */
html.splash-html, body.splash {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}
body.splash {
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
}
.splash-link { text-decoration: none; }
.glitch {
  position: relative;
  display: inline-block;
  color: var(--ink);
}
.glitch::before, .glitch::after {
  content: attr(data-text);
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 100%;
  color: var(--ink);
  background: var(--bg);
  overflow: hidden;
  clip-path: inset(50% 0 50% 0);
}
.glitch::before { animation: glitch-before 5s infinite steps(1); }
.glitch::after { animation: glitch-after 5s infinite steps(1); animation-delay: .12s; }

@keyframes glitch-before {
  0%, 91%, 100% { clip-path: inset(50% 0 50% 0); transform: translate(0, 0); }
  92% { clip-path: inset(15% 0 62% 0); transform: translate(-2.5%, 0); }
  93% { clip-path: inset(58% 0 8% 0);  transform: translate(2.5%, 0); }
  94% { clip-path: inset(34% 0 48% 0); transform: translate(-1.5%, 0); }
  95% { clip-path: inset(4% 0 82% 0);  transform: translate(2%, 0); }
  96%, 100% { clip-path: inset(50% 0 50% 0); transform: translate(0, 0); }
}
@keyframes glitch-after {
  0%, 89%, 100% { clip-path: inset(50% 0 50% 0); transform: translate(0, 0); }
  90% { clip-path: inset(72% 0 4% 0);  transform: translate(2%, 0); }
  91% { clip-path: inset(18% 0 68% 0); transform: translate(-2.5%, 0); }
  92% { clip-path: inset(46% 0 28% 0); transform: translate(2.5%, 0); }
  93% { clip-path: inset(62% 0 12% 0); transform: translate(-1.5%, 0); }
  94%, 100% { clip-path: inset(50% 0 50% 0); transform: translate(0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .glitch::before, .glitch::after { animation: none; content: none; }
}

/* ---------- Flying "click" labels: splash screen only, drift around ---------- */
.flying-clicks {
  position: fixed;
  inset: 0;
  z-index: 55;
  pointer-events: none;
}
.flying-click {
  position: absolute;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: .78rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #000;
  will-change: transform, opacity;
}
.fc-1 { top: 14%; left: 12%; animation: fly1 17s ease-in-out infinite; }
.fc-2 { top: 22%; right: 14%; animation: fly2 21s ease-in-out infinite; animation-delay: -4s; }
.fc-3 { bottom: 20%; left: 18%; animation: fly3 19s ease-in-out infinite; animation-delay: -9s; }
.fc-4 { bottom: 16%; right: 20%; animation: fly4 23s ease-in-out infinite; animation-delay: -2s; }
.fc-5 { top: 48%; left: 6%; animation: fly5 25s ease-in-out infinite; animation-delay: -13s; }

@keyframes fly1 {
  0%, 100% { transform: translate(0, 0) rotate(0deg); opacity: .8; }
  25% { transform: translate(6vw, 4vh) rotate(6deg); opacity: 1; }
  50% { transform: translate(2vw, 9vh) rotate(-3deg); opacity: .6; }
  75% { transform: translate(-4vw, 3vh) rotate(3deg); opacity: 1; }
}
@keyframes fly2 {
  0%, 100% { transform: translate(0, 0) rotate(0deg); opacity: .7; }
  30% { transform: translate(-7vw, 5vh) rotate(-5deg); opacity: 1; }
  60% { transform: translate(-3vw, -6vh) rotate(4deg); opacity: .5; }
  85% { transform: translate(4vw, 2vh) rotate(-2deg); opacity: 1; }
}
@keyframes fly3 {
  0%, 100% { transform: translate(0, 0) rotate(0deg); opacity: .9; }
  20% { transform: translate(5vw, -6vh) rotate(4deg); opacity: .5; }
  55% { transform: translate(9vw, 2vh) rotate(-6deg); opacity: 1; }
  80% { transform: translate(2vw, 5vh) rotate(2deg); opacity: .7; }
}
@keyframes fly4 {
  0%, 100% { transform: translate(0, 0) rotate(0deg); opacity: .6; }
  35% { transform: translate(-6vw, -4vh) rotate(-4deg); opacity: 1; }
  65% { transform: translate(-2vw, -9vh) rotate(5deg); opacity: .8; }
  90% { transform: translate(3vw, -2vh) rotate(-2deg); opacity: 1; }
}
@keyframes fly5 {
  0%, 100% { transform: translate(0, 0) rotate(0deg); opacity: .7; }
  40% { transform: translate(8vw, 3vh) rotate(5deg); opacity: 1; }
  70% { transform: translate(4vw, 10vh) rotate(-4deg); opacity: .5; }
}

@media (prefers-reduced-motion: reduce) {
  .flying-click { animation: none !important; }
}
