/* ============================================================================
   denisnekrasov.ru — light-first design system.

   Every surface, hairline and shadow goes through a token, so the whole site
   is one palette swap away from its dark counterpart at the bottom of this
   block. Light is the default and the theme the site is designed in; dark is
   opt-in through the toggle in the topbar.

   Two colour families are deliberately kept apart:
     --tint- and --line- : surfaces and hairlines. They flip with the theme.
     --on-photo-         : text and controls sitting on a photograph. Photos
                           are dark in both themes, so these do not flip.
   ========================================================================= */

:root {
  color-scheme: light;

  /* ---- canvas and surfaces ---- */
  --bg: #F4F4F7;
  --bg-deep: #ECECF2;
  --card: #FFFFFF;
  --card-alt: #FAFAFD;
  --row-hover: #F5F5F9;

  /* ---- ink ---- */
  --text: #13131A;
  --text-dim: #43434E;
  --text-mute: #5A5A67;
  --text-faint: #6E6E7B;
  --text-body: #33333D;

  /* ---- hairlines and surface tints ---- */
  --line: rgba(18, 18, 32, .10);
  --line-soft: rgba(18, 18, 32, .062);
  --line-mid: rgba(18, 18, 32, .14);
  --line-strong: rgba(18, 18, 32, .22);
  --tint-1: rgba(18, 18, 32, .024);
  --tint-2: rgba(18, 18, 32, .05);
  --tint-3: rgba(18, 18, 32, .08);
  --tint-4: rgba(18, 18, 32, .13);

  /* ---- brand ----
     Every accent is picked to clear 4.5:1 on white, because these same
     values are used as label text, not only as dots and fills. The `-soft`
     pair is the original neon, kept for glows where contrast does not apply. */
  --pink: #D6106D;
  --pink-soft: #FF3D8B;
  --purple: #5B45E8;
  --purple-soft: #7C6BFF;
  --magenta: #A32EB8;
  --green: #0E8F57;
  --blue: #1560C4;
  --gradient: linear-gradient(135deg, var(--pink), var(--purple));
  --on-accent: #FFFFFF;

  /* ---- accent washes ---- */
  --pink-wash-1: rgba(214, 16, 109, .045);
  --pink-wash-2: rgba(214, 16, 109, .085);
  --pink-line: rgba(214, 16, 109, .3);
  --pink-line-strong: rgba(214, 16, 109, .5);
  --purple-wash: rgba(91, 69, 232, .07);
  --purple-glow: rgba(124, 107, 255, .2);
  --pink-glow: rgba(255, 61, 139, .16);

  /* ---- book covers and the portrait bezel ---- */
  --book-shadow: rgba(20, 20, 45, .22);
  --bezel-sheen: inset 0 1px 0 rgba(255, 255, 255, .9);
  --screen-inset: rgba(18, 18, 32, .10);

  /* ---- glass chrome ---- */
  --glass: rgba(255, 255, 255, .7);
  --glass-strong: rgba(255, 255, 255, .88);
  --glass-line: rgba(18, 18, 32, .09);

  /* ---- texture ---- */
  --grid-dot: rgba(18, 18, 32, .085);
  --grid-line: rgba(18, 18, 32, .055);
  --grain-blend: multiply;
  --grain-opacity: .038;
  --canvas-opacity: .8;

  /* ---- overlays on photography (do not flip with the theme) ---- */
  --scrim: rgba(9, 9, 16, .62);
  --photo-fade: rgba(9, 9, 16, .88);
  --on-photo: #FFFFFF;
  --on-photo-dim: rgba(255, 255, 255, .8);
  --on-photo-veil: rgba(255, 255, 255, .3);
  --on-photo-panel: rgba(12, 12, 20, .55);

  /* ---- elevation ---- */
  --shadow-sm: 0 1px 2px rgba(20, 20, 45, .05);
  --shadow-md: 0 1px 2px rgba(20, 20, 45, .04), 0 12px 28px -16px rgba(20, 20, 45, .22);
  --shadow-lift: 0 2px 4px rgba(20, 20, 45, .05), 0 22px 44px -22px rgba(20, 20, 45, .3);
  --shadow-lg: 0 30px 70px -30px rgba(20, 20, 45, .34);
  --shadow-nav: 0 12px 36px -14px rgba(20, 20, 45, .26);
  --shadow-accent: 0 10px 26px -12px rgba(214, 16, 109, .5);

  /* ---- hero neural canvas (rgb triplets, alpha applied in JS) ---- */
  --net-line: 91, 69, 232;
  --net-dot: 91, 69, 232;
  --net-dot-hot: 214, 16, 109;
  --net-line-alpha: .28;
  --net-dot-alpha: .38;
}

[data-theme="dark"] {
  color-scheme: dark;

  --bg: #08080A;
  --bg-deep: #050507;
  --card: #0C0C0F;
  --card-alt: #0A0A0D;
  --row-hover: #131318;

  --text: #F2F2F4;
  --text-dim: #A6A6B0;
  --text-mute: #8A8A94;
  --text-faint: #82828E;
  --text-body: #D8D8DE;

  --line: rgba(255, 255, 255, .09);
  --line-soft: rgba(255, 255, 255, .07);
  --line-mid: rgba(255, 255, 255, .14);
  --line-strong: rgba(255, 255, 255, .22);
  --tint-1: rgba(255, 255, 255, .025);
  --tint-2: rgba(255, 255, 255, .055);
  --tint-3: rgba(255, 255, 255, .1);
  --tint-4: rgba(255, 255, 255, .18);

  --pink: #FF3D8B;
  --pink-soft: #FF3D8B;
  --purple: #7B69FF;
  --purple-soft: #7C6BFF;
  --magenta: #C24BC8;
  --green: #38E08A;
  --blue: #5FA8FF;

  --pink-wash-1: rgba(255, 61, 139, .06);
  --pink-wash-2: rgba(255, 61, 139, .1);
  --pink-line: rgba(255, 61, 139, .4);
  --pink-line-strong: rgba(255, 61, 139, .55);
  --purple-wash: rgba(110, 91, 255, .08);
  --purple-glow: rgba(110, 91, 255, .22);
  --pink-glow: rgba(255, 61, 139, .14);

  /* On a near-black card a drop shadow is invisible, so the cover is lifted
     by a faint light rim along its top edge instead. */
  --book-shadow: rgba(0, 0, 0, .55);
  --bezel-sheen: inset 0 1px 0 rgba(255, 255, 255, .07);
  --screen-inset: rgba(0, 0, 0, .5);

  --glass: rgba(10, 10, 14, .72);
  --glass-strong: rgba(14, 14, 19, .86);
  --glass-line: rgba(255, 255, 255, .1);

  --grid-dot: rgba(255, 255, 255, .06);
  --grid-line: rgba(255, 255, 255, .05);
  --grain-blend: screen;
  --grain-opacity: .03;
  --canvas-opacity: .5;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-md: 0 12px 28px -16px rgba(0, 0, 0, .8);
  --shadow-lift: 0 22px 44px -22px rgba(0, 0, 0, .85);
  --shadow-lg: 0 30px 70px -30px rgba(0, 0, 0, .9);
  --shadow-nav: 0 18px 44px rgba(0, 0, 0, .55);
  --shadow-accent: 0 10px 26px -12px rgba(255, 61, 139, .45);

  --net-line: 150, 140, 255;
  --net-dot: 210, 205, 255;
  --net-dot-hot: 255, 61, 139;
  --net-line-alpha: .3;
  --net-dot-alpha: .5;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

/* The dot grid is painted on the body rather than an overlay, so the opaque
   card surfaces sit on top of it without any stacking-context work. */
body {
  margin: 0;
  background-color: var(--bg);
  background-image: radial-gradient(circle at 1px 1px, var(--grid-dot) 1px, transparent 0);
  background-size: 28px 28px;
  color: var(--text);
  font-family: Onest, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* A film grain over everything below the chrome. It is what keeps a white
   page from reading as flat, and it costs one repeated 140px tile. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: var(--grain-blend);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

a { color: var(--text); text-decoration: none; }
a:hover { color: var(--pink); }
::selection { background: var(--pink-wash-2); color: var(--text); }
img { max-width: 100%; display: block; }
button { font-family: inherit; }

@keyframes dnPulse { 0%, 100% { opacity: .35 } 50% { opacity: 1 } }
@keyframes dnUp { from { opacity: 0; transform: translateY(14px) } to { opacity: 1; transform: none } }
@keyframes dnFloat {
  0%, 100% { transform: rotateY(-22deg) rotateX(6deg) translateY(0) }
  50% { transform: rotateY(-14deg) rotateX(3deg) translateY(-8px) }
}
@keyframes dnCaret { 0%, 100% { opacity: 1 } 50% { opacity: 0 } }

.page {
  background: transparent;
  min-height: 100vh;
  padding-bottom: 108px;
  overflow-x: hidden;
}
@supports (padding: env(safe-area-inset-bottom)) {
  .page { padding-bottom: calc(108px + env(safe-area-inset-bottom)); }
}

[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s ease, transform .6s ease;
}
[data-reveal].is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

.section-inner { max-width: 1180px; margin: 0 auto; }

/* ---------- Topbar ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 20px;
  padding-top: calc(14px + env(safe-area-inset-top));
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(180%);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  border-bottom: 1px solid var(--glass-line);
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark {
  width: 26px; height: 26px; border-radius: 9px;
  background: var(--gradient);
  display: grid; place-items: center;
  font: 500 11px/1 'JetBrains Mono', monospace;
  color: var(--on-accent);
  box-shadow: var(--shadow-accent);
}
.brand-name { font: 500 14px/1 Onest, sans-serif; letter-spacing: .01em; }
.topbar-right { display: flex; align-items: center; gap: 10px; }
.lang-switch {
  display: flex; align-items: center; gap: 2px; padding: 3px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--tint-1);
}
.lang {
  padding: 5px 9px; border-radius: 999px; color: var(--text-mute);
  font: 500 11px/1 'JetBrains Mono', monospace; letter-spacing: .06em;
  transition: background .15s ease, color .15s ease;
}
.lang:hover { color: var(--text); }
.lang-active { background: var(--tint-3); color: var(--text); }
.lang-active:hover { color: var(--text); }

/* ---------- Theme toggle ---------- */
.theme-toggle {
  display: grid; place-items: center; width: 32px; height: 32px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--tint-1); color: var(--text-mute); cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.theme-toggle:hover { color: var(--text); border-color: var(--line-mid); }
.theme-toggle-icon { width: 16px; height: 16px; }
/* One button, two glyphs: the one shown is the theme the click leads to. */
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 14px 22px; border-radius: 14px;
  font: 500 15px/1 Onest, sans-serif;
  cursor: pointer; border: 0;
  transition: filter .15s ease, background .15s ease, border-color .15s ease,
              box-shadow .15s ease, transform .15s ease;
}
.btn-sm { padding: 8px 14px; border-radius: 999px; font-size: 12px; margin-left: 8px; }
.btn-gradient { background: var(--gradient); color: var(--on-accent); box-shadow: var(--shadow-accent); }
.btn-gradient:hover { filter: brightness(1.08); color: var(--on-accent); transform: translateY(-1px); }
.btn-outline { border: 1px solid var(--line-mid); color: var(--text); background: var(--card); }
.btn-outline:hover { border-color: var(--text); color: var(--text); }
.btn-light { background: var(--text); color: var(--card); box-shadow: var(--shadow-sm); }
.btn-light:hover { background: var(--pink); color: var(--on-accent); }
.btn-soft { background: var(--tint-2); color: var(--text); font: 500 13px/1 Onest, sans-serif; padding: 12px 18px; border-radius: 12px; }
.btn-soft:hover { background: var(--tint-3); color: var(--text); }

/* ---------- Hero ---------- */
.hero { position: relative; padding: 0 20px; }
/* Two offset blobs rather than one centred glow: on a light canvas a single
   radial reads as a smudge, a pair reads as light falling across the page. */
.hero-glow {
  position: absolute; top: -160px; left: 50%; width: min(1240px, 130vw); height: 620px;
  transform: translateX(-50%);
  background:
    radial-gradient(38% 46% at 22% 34%, var(--pink-glow), transparent 70%),
    radial-gradient(42% 50% at 76% 22%, var(--purple-glow), transparent 72%),
    radial-gradient(34% 40% at 54% 68%, var(--pink-wash-2), transparent 70%);
  filter: blur(14px);
  pointer-events: none;
}
.hero-canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; opacity: var(--canvas-opacity); }
.hero-inner {
  position: relative; max-width: 1180px; margin: 0 auto;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 40px; align-items: center; padding: 56px 0 40px;
}
.hero-copy { display: flex; flex-direction: column; gap: 22px; animation: dnUp .5s ease both; }
.badge {
  display: inline-flex; align-items: center; gap: 8px; align-self: flex-start;
  padding: 7px 13px 7px 11px; border: 1px solid var(--line);
  border-radius: 999px; background: var(--glass-strong);
  box-shadow: var(--shadow-sm);
  font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-dim); letter-spacing: .04em;
}
.badge-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); animation: dnPulse 2.4s ease-in-out infinite; }
.hero-heading { display: flex; flex-direction: column; gap: 14px; }
.hero-heading h1 {
  margin: 0; font: 800 clamp(40px, 8vw, 78px)/0.98 Onest, sans-serif;
  letter-spacing: -.03em; text-wrap: balance;
}
.hero-lead {
  margin: 0; font: 400 clamp(16px, 2.2vw, 20px)/1.5 Onest, sans-serif;
  color: var(--text-dim); max-width: 36ch; text-wrap: pretty;
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.stat-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: 1px;
  margin-top: 8px; background: var(--line); border: 1px solid var(--line); border-radius: 16px;
  overflow: hidden; box-shadow: var(--shadow-md);
}
.stat-cell { background: var(--card); padding: 15px 13px; display: flex; flex-direction: column; gap: 5px; }
.stat-value { font: 600 clamp(17px, 1.5vw, 19px)/1.15 Onest, sans-serif; }
.stat-label { font: 400 10.5px/1.35 'JetBrains Mono', monospace; color: var(--text-faint); }

.portrait-wrap { display: flex; justify-content: flex-end; }
/* The portrait reads as a display rather than a framed photo: the picture is
   inset in a bezel of the page's own surface, and the caption sits in that
   bezel as a status line. Nothing is laid over the photograph, so the studio
   white stays white — an overlay for caption contrast used to grey out its
   bottom half. */
.portrait {
  width: 100%; max-width: 400px;
  display: flex; flex-direction: column;
  padding: 10px 10px 0; border-radius: 24px;
  border: 1px solid var(--line); background: var(--card);
  box-shadow: var(--shadow-lg), var(--bezel-sheen);
}
.portrait-screen {
  position: relative; border-radius: 15px; overflow: hidden;
  aspect-ratio: 4 / 5; background: var(--bg-deep);
  box-shadow: inset 0 0 0 1px var(--line-soft), inset 0 2px 12px var(--screen-inset);
}
.portrait img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; display: block; }
/* A single raking highlight across the top corner, the way light falls on
   glass. soft-light keeps it from washing the picture out. */
.portrait-screen::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(116deg,
    rgba(255, 255, 255, .55) 0%, rgba(255, 255, 255, .07) 30%, rgba(255, 255, 255, 0) 47%);
  mix-blend-mode: soft-light;
}
.portrait-caption {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 12px 8px 11px;
  font: 400 11px/1.4 'JetBrains Mono', monospace; color: var(--text-faint);
}
.portrait-place { display: inline-flex; align-items: center; gap: 8px; color: var(--text-mute); }
.portrait-place::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: var(--pink); box-shadow: 0 0 0 3px var(--pink-wash-2);
}

/* ---------- Section heads ---------- */
.section { padding: 48px 20px; }
.stories-section { padding: 24px 20px 48px; }
.moments-section { padding: 48px 20px 64px; }
.section-head {
  padding: 0 0 18px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
}
.eyebrow-title { display: flex; flex-direction: column; gap: 6px; }
.eyebrow { font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-faint); letter-spacing: .08em; }
.section-head h2 { margin: 0; font: 600 clamp(22px, 3.4vw, 32px)/1.1 Onest, sans-serif; letter-spacing: -.02em; }
.hint { font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-faint); }
.section-head-col { display: flex; flex-direction: column; gap: 6px; margin-bottom: 28px; }
.section-head-col h2 {
  margin: 0; font: 600 clamp(24px, 4vw, 38px)/1.08 Onest, sans-serif; letter-spacing: -.02em; max-width: 22ch;
  text-wrap: balance;
}
.section-lead { margin: 6px 0 0; font: 400 16px/1.6 Onest, sans-serif; color: var(--text-dim); max-width: 62ch; text-wrap: pretty; }
.link-underline {
  font: 400 13px/1 Onest, sans-serif; color: var(--text-dim); padding-bottom: 4px;
  border-bottom: 1px solid var(--line-mid);
}
.link-underline:hover { color: var(--pink); }

/* ---------- Stories ---------- */
.stories-row { display: flex; gap: 16px; overflow-x: auto; padding: 4px 2px 10px; scrollbar-width: none; }
.stories-row::-webkit-scrollbar { width: 0; height: 0; display: none; }
.story-avatar {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 9px;
  background: none; border: 0; padding: 0; cursor: pointer; width: 86px;
}
.story-ring { width: 82px; height: 82px; border-radius: 50%; padding: 2.5px; background: var(--gradient); display: block; }
/* The inner ring is the page surface showing through, so it tracks the card
   colour rather than the canvas — the avatars sit on white panels too. */
.story-ring-inner { display: block; width: 100%; height: 100%; border-radius: 50%; padding: 2.5px; background: var(--bg); }
.story-ring-inner img, .story-ring-inner video { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.story-label { font: 400 11px/1.2 Onest, sans-serif; color: var(--text-dim); text-align: center; }

/* ---------- Ask / Assistant ---------- */
.ask-panel {
  border: 1px solid var(--line); border-radius: 24px; overflow: hidden;
  background: var(--card); box-shadow: var(--shadow-md);
}
.ask-topbar {
  display: flex; align-items: center; gap: 10px; padding: 14px 18px;
  border-bottom: 1px solid var(--line-soft); background: var(--tint-1);
  font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-mute); letter-spacing: .06em;
}
.ask-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--pink); }
.ask-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.ask-questions { padding: 26px; display: flex; flex-direction: column; gap: 16px; border-right: 1px solid var(--line-soft); }
.ask-questions h2 { margin: 0; font: 600 clamp(20px, 3vw, 28px)/1.15 Onest, sans-serif; letter-spacing: -.02em; text-wrap: balance; }
.muted { margin: 0; font: 400 14px/1.6 Onest, sans-serif; color: var(--text-mute); text-wrap: pretty; }
.prompt-list { display: flex; flex-direction: column; gap: 8px; }
.prompt-btn {
  text-align: left; padding: 13px 15px; border-radius: 13px; border: 1px solid var(--line);
  background: var(--tint-1); color: var(--text); font: 400 13px/1.4 Onest, sans-serif; cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.prompt-btn:hover { border-color: var(--pink-line); }
.prompt-btn.is-active { border-color: var(--pink-line-strong); background: var(--pink-wash-2); }
.ask-answer {
  padding: 26px; display: flex; flex-direction: column; gap: 14px; min-height: 250px;
  background: linear-gradient(180deg, var(--purple-wash), transparent);
}
.ask-answer-label { display: flex; align-items: center; gap: 8px; font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-faint); }
.ask-answer-icon { width: 22px; height: 22px; border-radius: 7px; background: var(--gradient); }
.answer-text { margin: 0; font: 400 15px/1.7 Onest, sans-serif; color: var(--text-body); text-wrap: pretty; }
.caret {
  display: inline-block; width: 8px; height: 17px; margin-left: 2px; vertical-align: -3px;
  background: var(--pink); animation: dnCaret 1s step-end infinite;
}
.ask-cta { margin-top: auto; align-self: flex-start; }

/* ---------- Digital transformation ---------- */
.steps-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 20px 24px; }
.step-item { display: flex; flex-direction: column; gap: 7px; }
.step-item-head { display: flex; align-items: center; gap: 10px; }
.step-n { font: 500 12px/1 'JetBrains Mono', monospace; color: var(--step-accent, var(--pink)); }
.step-line { flex: 1; height: 1px; background: linear-gradient(90deg, var(--step-accent, var(--pink)), transparent); opacity: .5; }
.step-item h3 { margin: 0; font: 600 16px/1.25 Onest, sans-serif; }
.step-item p { margin: 0; font: 400 13px/1.5 Onest, sans-serif; color: var(--text-mute); text-wrap: pretty; }
.step-time { font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-faint); margin-top: 2px; }

/* ---------- Cases ---------- */
.filter-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; }
.filter-chip {
  padding: 9px 15px; border-radius: 999px; border: 1px solid var(--line-mid);
  background: var(--card); color: var(--text-dim); font: 400 13px/1 Onest, sans-serif; cursor: pointer;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.filter-chip:hover { border-color: var(--line-strong); color: var(--text); }
.filter-chip.filter-chip-active { border-color: var(--text); background: var(--text); color: var(--card); }
.cases-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(285px, 1fr)); gap: 14px; }
.case-card {
  border: 1px solid var(--line); border-radius: 20px; padding: 22px; background: var(--card);
  display: flex; flex-direction: column; gap: 14px; box-shadow: var(--shadow-md);
  transition: border-color .15s ease, box-shadow .2s ease, transform .2s ease;
}
.case-card:hover {
  border-color: color-mix(in srgb, var(--case-accent) 45%, transparent);
  box-shadow: var(--shadow-lift); transform: translateY(-2px);
}
.case-tag { font: 400 11px/1 'JetBrains Mono', monospace; letter-spacing: .04em; }
.case-card h3 { margin: 0; font: 600 19px/1.25 Onest, sans-serif; text-wrap: balance; }
.case-card p { margin: 0; font: 400 14px/1.55 Onest, sans-serif; color: var(--text-mute); text-wrap: pretty; }
.case-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; }
.pill { padding: 5px 10px; border-radius: 8px; background: var(--tint-2); font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-dim); }
.case-card[hidden] { display: none; }

/* ---------- Consult ---------- */
.consult-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 14px; margin-bottom: 24px; }
.consult-card {
  border: 1px solid var(--line); border-radius: 22px; padding: 26px; background: var(--card);
  display: flex; flex-direction: column; gap: 16px; box-shadow: var(--shadow-md);
}
.consult-card-highlight {
  border-color: var(--pink-line);
  background: linear-gradient(180deg, var(--pink-wash-2), var(--card) 60%);
}
.consult-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.consult-card h3 { margin: 0; font: 600 21px/1.2 Onest, sans-serif; }
.consult-badge {
  font: 400 10px/1 'JetBrains Mono', monospace; color: var(--pink); padding: 6px 9px;
  border: 1px solid var(--pink-line); border-radius: 999px;
}
.consult-card p { margin: 0; font: 400 14px/1.6 Onest, sans-serif; color: var(--text-mute); text-wrap: pretty; }
.consult-card-highlight p { color: var(--text-dim); }
.consult-points { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.consult-points li { font: 400 13px/1.4 Onest, sans-serif; color: var(--text-dim); }
.consult-cta { margin-top: auto; padding: 13px 18px; border-radius: 13px; text-align: center; font: 500 14px/1 Onest, sans-serif; }
.also-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px; border: 1px dashed var(--line-mid);
  border-radius: 18px; padding: 18px 22px; font: 400 14px/1 Onest, sans-serif; color: var(--text-dim);
}
.also-label { font: 400 12px/1 'JetBrains Mono', monospace; color: var(--text-faint); }
.dot-sep { width: 4px; height: 4px; border-radius: 50%; background: var(--tint-4); display: inline-block; }

/* ---------- Books ---------- */
.books-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; }
.book-card {
  border: 1px solid var(--line); border-radius: 22px; overflow: hidden; background: var(--card);
  display: flex; flex-direction: column; box-shadow: var(--shadow-md);
}
.book-top { display: grid; grid-template-columns: 150px 1fr; gap: 20px; padding: 22px; align-items: start; }
/* The covers are photographed renders, already turned in space and already
   carrying their own shadow, so the card only floats them — the CSS book with
   a paper face and a hinged spine that stood in for them is gone. Both files
   are normalised onto one 3:4 canvas, so the two cards show books of the
   same height however differently each was rendered. */
.book-3d { aspect-ratio: 3 / 4; }
.book-3d-inner {
  width: 100%; height: 100%;
  animation-name: dnFloat; animation-timing-function: ease-in-out; animation-iteration-count: infinite;
}
.book-card:hover .book-3d-inner { animation-play-state: paused; }
.book-cover {
  width: 100%; height: 100%; display: block; object-fit: contain;
  filter: drop-shadow(0 18px 26px var(--book-shadow));
  transition: transform .4s ease;
}
.book-card:hover .book-cover { transform: translateY(-4px) scale(1.03); }
.book-info { display: flex; flex-direction: column; gap: 10px; }
.book-meta { font: 400 11px/1 'JetBrains Mono', monospace; }
.book-info h3 { margin: 0; font: 600 22px/1.15 Onest, sans-serif; }
.book-info p { margin: 0; font: 400 14px/1.55 Onest, sans-serif; color: var(--text-mute); text-wrap: pretty; }
.book-rating { display: flex; align-items: center; gap: 8px; margin-top: auto; }
.rating-value { font: 500 15px/1 Onest, sans-serif; }
.rating-note { font: 400 12px/1 'JetBrains Mono', monospace; color: var(--text-faint); }
.book-formats { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 22px 22px; }
.format-pill {
  padding: 9px 14px; border-radius: 10px; background: var(--tint-2);
  font: 400 12px/1 'JetBrains Mono', monospace; color: var(--text-dim);
}
/* The one link in the row, so it carries the accent the formats gave up. */
.format-cta {
  margin-left: auto; padding: 9px 16px; border-radius: 10px;
  border: 1px solid var(--format-accent); color: var(--format-accent);
  font: 500 12px/1 Onest, sans-serif; letter-spacing: .01em;
  transition: background .15s ease, color .15s ease;
}
.format-cta:hover { background: var(--format-accent); color: var(--on-accent); }

/* ---------- Blog ---------- */
/* auto-fit, not auto-fill: the hairline grid is the container's own
   background showing through the 1px gaps, so an unfilled track would read as
   an empty grey cell. The article page ends on three cards, not four. */
.blog-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: 20px; overflow: hidden;
  box-shadow: var(--shadow-md);
}
.blog-card { background: var(--card); padding: 24px; display: flex; flex-direction: column; gap: 12px; min-height: 210px; }
.blog-card:hover { background: var(--row-hover); }
.blog-meta { font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-faint); }
.blog-card h3 { margin: 0; font: 600 18px/1.3 Onest, sans-serif; text-wrap: balance; color: var(--text); }
.blog-read { margin-top: auto; font: 400 13px/1 Onest, sans-serif; color: var(--text-mute); }

/* ---------- About ---------- */
.about-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 32px; align-items: center; }
/* Capped so the text stays readable if the video slot is empty and the
   column spans the full grid. */
.about-copy { display: flex; flex-direction: column; gap: 18px; max-width: 640px; }
.about-copy h2 { margin: 0; font: 600 clamp(24px, 4vw, 38px)/1.08 Onest, sans-serif; letter-spacing: -.02em; }
.about-text { display: flex; flex-direction: column; gap: 12px; }
.about-text p { margin: 0; font: 400 15px/1.65 Onest, sans-serif; color: var(--text-dim); text-wrap: pretty; }
.companies-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-top: 4px; }
.company-card {
  border: 1px solid var(--line); border-radius: 14px; padding: 14px; background: var(--card);
  display: flex; flex-direction: column; gap: 6px; box-shadow: var(--shadow-sm);
}
.company-name { font: 500 14px/1.2 Onest, sans-serif; }
.company-role { font: 400 11px/1.3 'JetBrains Mono', monospace; color: var(--text-faint); }
.about-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 4px; }

/* ---------- Moments ---------- */
/* Five per row on wide screens, so a feed of 5/10/15 photos fills whole rows. */
/* Fixed row height rather than square tiles: a portrait clip takes two rows
   and lands close to its own 9:16, a still or a landscape frame takes one.
   Dense packing then backfills the holes the tall tiles leave behind. */
.moments-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  grid-auto-rows: 112px; grid-auto-flow: dense; gap: 8px;
}
@media (min-width: 1000px) { .moments-grid { grid-template-columns: repeat(5, 1fr); grid-auto-rows: 160px; } }
.moment[hidden] { display: none; }
.moment {
  margin: 0; grid-row: span 1; overflow: hidden; border-radius: 12px;
  background: var(--card); box-shadow: var(--shadow-sm);
}
.moment.is-portrait { grid-row: span 2; }
.moment.is-wide { grid-column: span 2; }
/* Centred crop, biased a touch above the middle — in a portrait frame the
   subject sits higher than the geometric centre. */
.moment > img, .moment > video {
  display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 42%;
}
.moment.is-portrait > img, .moment.is-portrait > video { object-position: 50% 50%; }

/* ---------- Contact ---------- */
.contact-section { padding: 0 20px 56px; }
.contact-panel {
  border: 1px solid var(--line); border-radius: 26px; padding: clamp(26px, 5vw, 52px);
  background:
    radial-gradient(120% 140% at 0% 0%, var(--pink-glow), var(--purple-wash) 45%, var(--card) 75%),
    var(--card);
  display: flex; flex-direction: column; gap: 22px; box-shadow: var(--shadow-lift);
}
.contact-panel h2 { margin: 0; font: 800 clamp(26px, 5vw, 46px)/1.05 Onest, sans-serif; letter-spacing: -.03em; max-width: 24ch; text-wrap: balance; }
.contact-panel p { margin: 0; font: 400 16px/1.6 Onest, sans-serif; color: var(--text-dim); max-width: 54ch; text-wrap: pretty; }
.contact-actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* ---------- Footer ---------- */
.site-footer { padding: 0 20px 40px; }
.footer-grid {
  max-width: 1180px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 24px; padding-top: 28px; border-top: 1px solid var(--line-soft);
}
.footer-col { display: flex; flex-direction: column; gap: 8px; }
.footer-name { font: 500 13px/1 Onest, sans-serif; }
.footer-meta { font: 400 11px/1.5 'JetBrains Mono', monospace; color: var(--text-faint); }
.footer-heading { font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-faint); letter-spacing: .06em; }
.footer-col a { font: 400 13px/1.6 Onest, sans-serif; color: var(--text-dim); }
.footer-address { font: 400 13px/1.6 Onest, sans-serif; color: var(--text-dim); }

/* ---------- Bottom nav ---------- */
.bottom-nav {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 70;
  display: flex; align-items: center; gap: 4px; padding: 7px; border-radius: 999px;
  background: var(--glass-strong);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid var(--glass-line);
  box-shadow: var(--shadow-nav); max-width: calc(100vw - 32px); overflow-x: auto;
  scrollbar-width: none; -ms-overflow-style: none;
}
.bottom-nav::-webkit-scrollbar { width: 0; height: 0; display: none; }
.bottom-nav a {
  padding: 10px 15px; border-radius: 999px; font: 500 12px/1 Onest, sans-serif; color: var(--text-dim); white-space: nowrap;
}
.bottom-nav a:hover { background: var(--tint-2); color: var(--text-dim); }
.bottom-nav-cta {
  padding: 10px 16px !important; background: var(--gradient); color: var(--on-accent) !important;
}
.bottom-nav-cta:hover { background: var(--gradient) !important; }

/* ---------- Story modal ----------
   The viewer stays dark in both themes: it is a full-bleed photo surface,
   and every top-of-market story viewer keeps it that way. */
.story-modal {
  position: fixed; inset: 0; z-index: 100; background: rgba(6, 6, 10, .96);
  display: flex; align-items: center; justify-content: center;
}
.story-modal[hidden] { display: none; }
.story-frame {
  position: relative; width: 100%; height: 100%; max-width: 460px; max-height: 92vh;
  background: #0A0A0F; overflow: hidden;
}
/* A blurred, over-scaled copy of the still fills whatever the slide itself
   does not cover, so 9:16 and 4:3 material both sit centred in one frame. */
.story-bg {
  position: absolute; inset: 0; background-size: cover; background-position: center;
  transform: scale(1.15); filter: blur(26px) saturate(125%); opacity: .68;
}
.story-stage { position: absolute; inset: 0; display: grid; place-items: center; }
.story-media { max-width: 100%; max-height: 100%; width: 100%; height: 100%; object-fit: contain; }
.story-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(6, 6, 10, .75) 0%, transparent 28%, transparent 55%, rgba(6, 6, 10, .85) 100%);
}
.story-bars { position: absolute; top: 12px; left: 12px; right: 12px; display: flex; gap: 4px; }
.story-bar { flex: 1; height: 3px; border-radius: 2px; background: var(--on-photo-veil); overflow: hidden; }
.story-bar-fill { display: block; height: 100%; width: 0%; background: var(--on-photo); }
.story-header {
  position: absolute; top: 28px; left: 14px; right: 14px; display: flex; align-items: center;
  justify-content: space-between; gap: 12px;
}
.story-title { font: 500 13px/1 Onest, sans-serif; color: var(--on-photo); text-shadow: 0 1px 8px rgba(0, 0, 0, .6); }
.story-close {
  width: 34px; height: 34px; border-radius: 50%; border: 0; background: rgba(255, 255, 255, .16);
  color: var(--on-photo); font: 400 16px/1 Onest, sans-serif; cursor: pointer;
}
.story-zone { position: absolute; top: 60px; bottom: 90px; background: none; border: 0; cursor: pointer; }
.story-zone-prev { left: 0; width: 32%; }
.story-zone-next { right: 0; width: 68%; }
.story-footer { position: absolute; left: 18px; right: 18px; bottom: 22px; display: flex; flex-direction: column; gap: 14px; }
.story-caption {
  margin: 0; font: 500 clamp(18px, 5vw, 24px)/1.25 Onest, sans-serif; color: var(--on-photo);
  text-shadow: 0 2px 14px rgba(0, 0, 0, .5); text-wrap: pretty;
}
/* The page's light button is an inverted, near-black pill. Inside the viewer
   that would sink into the photograph, so the CTA keeps the bright pill the
   dark surface asks for, in both themes. */
.story-footer .btn-light { background: var(--on-photo); color: #13131A; }
.story-footer .btn-light:hover { background: var(--pink-soft); color: var(--on-photo); }

/* ---------- Scale of the work ---------- */
.scale-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px; margin-bottom: 22px;
  background: var(--line); border: 1px solid var(--line); border-radius: 18px; overflow: hidden;
  box-shadow: var(--shadow-md);
}
.scale-item {
  background: linear-gradient(180deg, var(--pink-wash-1), transparent 70%), var(--card);
  padding: 18px 18px 16px; display: flex; flex-direction: column; gap: 6px;
}
.scale-value {
  font: 800 clamp(26px, 3vw, 32px)/1 Onest, sans-serif; letter-spacing: -.02em;
  background: var(--gradient); -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.scale-label { font: 400 12px/1.35 'JetBrains Mono', monospace; color: var(--text-faint); }

/* ---------- Show more ---------- */
.show-more {
  display: block; width: 100%; margin-top: 10px; padding: 13px 18px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--card);
  color: var(--text-dim); font: 500 13px/1 Onest, sans-serif; cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.show-more:hover { border-color: var(--line-strong); color: var(--text); }
.show-more[hidden] { display: none; }
.projects-list .show-more { margin: 0; border: 0; border-radius: 0; background: var(--card); }

/* ---------- About: video + photo ---------- */
/* The photo sits beside the text; the video closes the section as a band.
   It keeps its own 16:9 and is capped rather than cropped, so nothing in the
   frame is cut off. */
.about-photo {
  width: 100%; aspect-ratio: 16 / 9; object-fit: cover; object-position: 50% 35%;
  border-radius: 18px; border: 1px solid var(--line); box-shadow: var(--shadow-lift);
}
.about-video { position: relative; margin: 0 auto; max-width: 960px; }
.about-video video {
  width: 100%; display: block; border-radius: 20px; border: 1px solid var(--line);
  background: #000; aspect-ratio: 16 / 9; object-fit: cover; box-shadow: var(--shadow-lift);
}
.video-sound {
  position: absolute; right: 12px; bottom: 12px;
  display: grid; place-items: center; width: 36px; height: 36px;
  border: 1px solid rgba(255, 255, 255, .22); border-radius: 50%;
  background: var(--on-photo-panel); backdrop-filter: blur(10px);
  color: var(--on-photo); cursor: pointer; transition: background .15s ease, border-color .15s ease;
}
.video-sound:hover { background: rgba(12, 12, 20, .8); border-color: rgba(255, 255, 255, .4); }
.video-sound-icon { width: 17px; height: 17px; }
/* One band under both columns, so the section has no ragged edge. */
.about-strip { margin-top: 24px; }

/* ---------- Projects: toolbar ---------- */
.projects-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px; margin-bottom: 14px;
}
.view-toggle {
  display: inline-flex; gap: 3px; padding: 3px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--card);
  box-shadow: var(--shadow-sm);
}
.view-btn {
  display: inline-flex; align-items: center; gap: 7px; padding: 8px 15px;
  border: 0; border-radius: 999px; background: none; cursor: pointer;
  color: var(--text-mute); font: 500 13px/1 Onest, sans-serif;
  transition: background .15s ease, color .15s ease;
}
.view-btn:hover { color: var(--text); }
.view-btn.is-active { background: var(--tint-3); color: var(--text); }
.view-icon { width: 16px; height: 16px; }
.projects-count {
  display: flex; align-items: center; gap: 6px;
  font: 400 12px/1 'JetBrains Mono', monospace; color: var(--text-faint);
}
.projects-count b { color: var(--text-dim); font-weight: 500; }
.filter-row-projects { margin-bottom: 18px; }
.filter-row-projects .filter-chip { display: inline-flex; align-items: center; gap: 8px; }
.chip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--chip-accent); }
.filter-chip-active .chip-dot { background: var(--card); }
.filter-chip[style*="--chip-accent"].filter-chip-active {
  border-color: var(--chip-accent); background: var(--chip-accent); color: var(--on-accent);
}

/* ---------- Projects: neural map ---------- */
.projects-view[hidden] { display: none; }
.projects-view[data-view="map"]:not([hidden]) {
  display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 14px; align-items: stretch;
}
/* Blueprint grid behind the map: it reads as a plotting surface rather than
   an empty white box, which is what the nodes need to sit on. */
.map-shell {
  position: relative; border: 1px solid var(--line); border-radius: 22px; overflow: hidden;
  background:
    radial-gradient(90% 120% at 15% 0%, var(--purple-wash), transparent 60%),
    linear-gradient(var(--grid-line) 1px, transparent 1px) 0 0 / 100% 32px,
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px) 0 0 / 32px 100%,
    var(--card);
  padding: 6px; box-shadow: var(--shadow-md);
}
.project-map { display: block; width: 100%; height: auto; overflow: visible; }
.map-hint {
  position: absolute; right: 16px; top: 14px;
  font: 400 10px/1 'JetBrains Mono', monospace; color: var(--text-faint); letter-spacing: .04em;
}
.map-empty {
  position: absolute; inset: 0; margin: 0; display: grid; place-items: center;
  background: var(--glass-strong); font: 400 14px/1 Onest, sans-serif; color: var(--text-mute);
}
.map-empty[hidden] { display: none; }
.map-guides line { stroke: var(--grid-line); stroke-width: 1; }
.map-year { font: 400 10px/1 'JetBrains Mono', monospace; fill: var(--text-faint); }
.map-track { font: 400 10px/1 'JetBrains Mono', monospace; opacity: .75; letter-spacing: .04em; }
.map-link { fill: none; stroke-width: 1.3; stroke-linecap: round; opacity: .34; transition: opacity .2s ease; }
.map-link.is-dimmed { opacity: .07; }
.map-node { cursor: pointer; transition: opacity .2s ease; outline: none; }
.map-node.is-dimmed { opacity: .16; pointer-events: none; }
.map-halo { opacity: 0; transition: opacity .2s ease; }
.map-dot { transition: r .18s ease; }
.map-label { font: 400 11px/1 Onest, sans-serif; fill: var(--text-mute); transition: fill .2s ease; }
.map-node:hover .map-halo, .map-node.is-selected .map-halo { opacity: .2; }
.map-node:hover .map-dot, .map-node.is-selected .map-dot { r: 8.5; }
.map-node:hover .map-label, .map-node.is-selected .map-label { fill: var(--text); }
.map-node:focus-visible .map-halo { opacity: .34; }

.map-detail {
  border: 1px solid var(--line); border-radius: 22px; padding: 22px; background: var(--card);
  display: flex; flex-direction: column; gap: 12px; box-shadow: var(--shadow-md);
  border-left: 2px solid var(--project-accent);
}
.map-detail-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.map-detail h3 { margin: 0; font: 600 17px/1.3 Onest, sans-serif; text-wrap: balance; }
.map-detail p { margin: 0; font: 400 14px/1.55 Onest, sans-serif; color: var(--text-mute); text-wrap: pretty; }
.map-detail .case-pills { margin-top: 0; }
.map-detail .project-link { margin-top: auto; }
.project-tag { font: 400 11px/1 'JetBrains Mono', monospace; letter-spacing: .04em; }
.project-year { font: 400 11px/1 'JetBrains Mono', monospace; color: var(--text-faint); }
.project-link {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  font: 500 12px/1 Onest, sans-serif; color: var(--project-accent);
}
.project-link:hover { color: var(--project-accent); filter: brightness(1.15); }
.project-link[hidden] { display: none; }
.project-link-icon { width: 15px; height: 15px; }

/* ---------- Projects: compact list ---------- */
.projects-list {
  display: flex; flex-direction: column; gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: 20px; overflow: hidden;
  box-shadow: var(--shadow-md);
}
.project-row {
  display: grid; grid-template-columns: 52px 8px minmax(0, 1fr) auto auto;
  align-items: center; gap: 14px; padding: 14px 20px; background: var(--card);
  transition: background .15s ease;
}
.project-row:hover { background: var(--row-hover); }
.project-row[hidden] { display: none; }
.project-row-year { font: 400 12px/1 'JetBrains Mono', monospace; color: var(--text-faint); }
.project-row-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--project-accent); opacity: .9;
}
.project-row-main { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.project-row h3 {
  margin: 0; flex: 0 0 auto; font: 600 15px/1.35 Onest, sans-serif; color: var(--text);
}
.project-row p {
  margin: 0; font: 400 13px/1.35 Onest, sans-serif; color: var(--text-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.project-row-tag {
  font: 400 11px/1 'JetBrains Mono', monospace; color: var(--project-accent); opacity: .9;
}
.project-row-link { display: grid; place-items: center; color: var(--text-mute); }
.project-row-link:hover { color: var(--project-accent); }

/* ---------- Blog list and article pages ---------- */
.subpage-head { padding-top: 40px; padding-bottom: 8px; }
.subpage-title { margin: 0; font: 800 clamp(30px, 6vw, 52px)/1.05 Onest, sans-serif; letter-spacing: -.03em; }
.back-link {
  display: inline-block; margin-bottom: 22px; font: 400 13px/1 Onest, sans-serif; color: var(--text-mute);
}
.back-link:hover { color: var(--pink); }
.blog-card { transition: background .15s ease; }
.blog-card:hover h3 { color: var(--post-accent, var(--pink)); }
.post-list {
  display: flex; flex-direction: column; gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: 22px; overflow: hidden;
  box-shadow: var(--shadow-md);
}
.post-row {
  background: var(--card); padding: 26px; display: flex; gap: 24px;
  align-items: flex-start; justify-content: space-between; transition: background .15s ease;
}
.post-row:hover { background: var(--row-hover); }
.post-row-main { display: flex; flex-direction: column; gap: 10px; }
.post-row h2 { margin: 0; font: 600 22px/1.25 Onest, sans-serif; color: var(--text); text-wrap: balance; }
.post-row:hover h2 { color: var(--post-accent, var(--pink)); }
.post-row p { margin: 0; font: 400 15px/1.6 Onest, sans-serif; color: var(--text-mute); max-width: 66ch; text-wrap: pretty; }
.post-row-read { flex: 0 0 auto; font: 400 13px/1 Onest, sans-serif; color: var(--text-mute); padding-top: 4px; }

.article-section { padding-top: 40px; }
.article-inner { max-width: 720px; margin: 0 auto; }
.article-head { display: flex; flex-direction: column; gap: 14px; margin-bottom: 34px; }
.article-head h1 {
  margin: 0; font: 800 clamp(28px, 5vw, 44px)/1.08 Onest, sans-serif;
  letter-spacing: -.03em; text-wrap: balance;
}
.article-lead {
  margin: 0; font: 400 clamp(16px, 2.2vw, 19px)/1.6 Onest, sans-serif;
  color: var(--text-dim); text-wrap: pretty;
}
.article-body { display: flex; flex-direction: column; gap: 20px; }
.article-body h2 {
  margin: 18px 0 0; font: 600 clamp(20px, 3vw, 26px)/1.25 Onest, sans-serif;
  letter-spacing: -.02em; text-wrap: balance;
}
.article-body p { margin: 0; font: 400 17px/1.75 Onest, sans-serif; color: var(--text-body); text-wrap: pretty; }
.article-body ul { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 10px; }
.article-body li { font: 400 16px/1.7 Onest, sans-serif; color: var(--text-dim); text-wrap: pretty; }
.article-body li::marker { color: var(--post-accent, var(--pink)); }
.article-body blockquote {
  margin: 8px 0; padding: 18px 22px; border-left: 2px solid var(--post-accent, var(--pink));
  background: var(--tint-1); border-radius: 0 14px 14px 0;
  font: 500 17px/1.6 Onest, sans-serif; color: var(--text); text-wrap: pretty;
}
.article-cta {
  margin-top: 46px; padding: 30px; border: 1px solid var(--line); border-radius: 22px;
  background:
    radial-gradient(120% 140% at 0% 0%, var(--pink-glow), var(--purple-wash) 45%, var(--card) 75%),
    var(--card);
  display: flex; flex-direction: column; gap: 14px; align-items: flex-start;
  box-shadow: var(--shadow-md);
}
.article-cta h3 { margin: 0; font: 600 22px/1.2 Onest, sans-serif; text-wrap: balance; }
.article-cta p { margin: 0; font: 400 15px/1.6 Onest, sans-serif; color: var(--text-dim); text-wrap: pretty; }

/* ---------- 404 ---------- */
.error-section { padding-top: 80px; }
.error-inner { display: flex; flex-direction: column; gap: 18px; align-items: flex-start; }
.error-inner h1 { margin: 0; font: 800 clamp(30px, 6vw, 54px)/1.06 Onest, sans-serif; letter-spacing: -.03em; }
.error-en { color: var(--text-faint); }

/* ---------- Bottom nav: active state ---------- */
.bottom-nav a.is-active { background: var(--tint-3); color: var(--text); }
.bottom-nav a:first-child { color: var(--text-dim); }
.bottom-nav-cta, .bottom-nav a.bottom-nav-cta.is-active { color: var(--on-accent) !important; }

/* ---------- Mobile app tab bar ---------- */
.tabbar {
  display: none;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
  grid-template-columns: repeat(5, 1fr); gap: 2px;
  padding: 7px 6px calc(7px + env(safe-area-inset-bottom));
  background: var(--glass-strong);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  border-top: 1px solid var(--glass-line);
  box-shadow: 0 -12px 30px -14px rgba(20, 20, 45, .3);
}
.tab {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 8px 2px 4px; border: 0; border-radius: 16px; background: none; cursor: pointer;
  color: var(--text-faint); font: 500 10px/1.1 Onest, sans-serif; text-align: center;
  -webkit-tap-highlight-color: transparent;
}
.tab:hover { color: var(--text-dim); }
.tab-icon { width: 22px; height: 22px; flex: 0 0 auto; }
.tab-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tab.is-active { color: var(--text); }
.tab.is-active .tab-icon { color: var(--pink); }
.tab.is-active::before {
  content: ''; position: absolute; top: -7px; width: 26px; height: 2px;
  border-radius: 0 0 3px 3px; background: var(--gradient);
}
.tab-cta { color: var(--text-dim); }
.tab-cta-icon {
  width: 40px; height: 24px; display: grid; place-items: center; border-radius: 999px;
  background: var(--gradient); color: var(--on-accent); box-shadow: var(--shadow-accent);
}
.tab-cta .tab-icon { width: 17px; height: 17px; }
.tab-cta.is-active::before { display: none; }

/* ---------- Mobile menu sheet ---------- */
.sheet { position: fixed; inset: 0; z-index: 90; display: flex; align-items: flex-end; }
.sheet[hidden] { display: none; }
.sheet-scrim { position: absolute; inset: 0; background: var(--scrim); backdrop-filter: blur(3px); }
.sheet-panel {
  position: relative; width: 100%; max-height: 88vh; overflow-y: auto;
  padding: 10px 18px calc(22px + env(safe-area-inset-bottom));
  background: var(--card); border-top: 1px solid var(--line);
  border-radius: 26px 26px 0 0; box-shadow: var(--shadow-lg);
  animation: dnSheet .22s ease both;
}
@keyframes dnSheet { from { transform: translateY(26px); opacity: .3 } to { transform: none; opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .sheet-panel { animation: none; } }
.sheet-grabber { width: 38px; height: 4px; border-radius: 3px; background: var(--tint-4); margin: 0 auto 16px; }
.sheet-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.sheet-title { font: 600 17px/1 Onest, sans-serif; }
.sheet-close {
  width: 34px; height: 34px; display: grid; place-items: center; border: 0; border-radius: 50%;
  background: var(--tint-2); color: var(--text-dim); cursor: pointer;
}
.sheet-close-icon { width: 17px; height: 17px; }
.sheet-links { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sheet-link {
  display: flex; align-items: center; gap: 11px; padding: 14px;
  border: 1px solid var(--line); border-radius: 15px; background: var(--tint-1);
  font: 500 14px/1.2 Onest, sans-serif; color: var(--text);
}
.sheet-link:hover { color: var(--text); border-color: var(--line-strong); }
.sheet-link-icon { color: var(--text-mute); display: grid; place-items: center; }
.sheet-lang {
  display: flex; align-items: center; gap: 8px; margin: 16px 0;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 15px;
}
.sheet-lang-label { color: var(--text-faint); display: grid; place-items: center; }
.sheet-lang-btn {
  padding: 8px 16px; border-radius: 999px; color: var(--text-mute);
  font: 500 12px/1 'JetBrains Mono', monospace; letter-spacing: .06em;
}
.sheet-lang-btn.is-active { background: var(--tint-3); color: var(--text); }
/* The theme switch shares the language row's shape, so the sheet keeps one
   rhythm of "setting rows" instead of growing a new control style. */
.sheet-theme {
  display: flex; align-items: center; gap: 8px; margin: 0 0 16px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 15px;
}
.sheet-theme-label { color: var(--text-faint); display: grid; place-items: center; }
.sheet-theme-btn {
  padding: 8px 16px; border: 0; border-radius: 999px; background: none; cursor: pointer;
  color: var(--text-mute); font: 500 12px/1 'JetBrains Mono', monospace; letter-spacing: .06em;
}
.sheet-theme-btn.is-active { background: var(--tint-3); color: var(--text); }
.sheet-contacts { display: flex; flex-direction: column; gap: 9px; }
.sheet-cta { width: 100%; }

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .bottom-nav { display: none; }
  .tabbar { display: grid; }
  .page { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
  body.sheet-open { overflow: hidden; }
}

@media (max-width: 860px) {
  .portrait-wrap { justify-content: flex-start; }
  .portrait { max-width: 340px; }
  .hero-inner { padding: 40px 0 32px; gap: 32px; }
}

@media (max-width: 900px) {
  .projects-view[data-view="map"]:not([hidden]) { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 760px) {
  .project-row {
    grid-template-columns: 44px 8px minmax(0, 1fr) auto;
    gap: 12px; padding: 13px 16px; cursor: pointer; align-items: center;
  }
  .project-row-main { flex-direction: column; gap: 5px; align-items: flex-start; }
  .project-row h3 { font-size: 14.5px; line-height: 1.3; }
  /* One tap-height row per project; the description unfolds on tap. */
  .project-row p { display: none; white-space: normal; font-size: 12.5px; line-height: 1.45; }
  .project-row.is-open p { display: block; }
  .project-row-tag { display: none; }
  .map-hint { display: none; }
  .about-strip { margin-top: 14px; }
  .about-video video { border-radius: 16px; }
  .map-shell { padding: 4px; }
  .map-year { font-size: 9px; }
  .map-detail { padding: 18px; }
  .scale-item { padding: 15px 16px 13px; }
}

@media (max-width: 560px) {
  /* The topbar has no room for a fourth control on a phone, and it does not
     need one: the menu sheet carries the theme row at these widths. */
  .theme-toggle { display: none; }
}

@media (max-width: 700px) {
  .section { padding: 40px 20px; }
  .stories-row { margin: 0 -20px; padding: 4px 20px 10px; }
  .story-avatar { width: 78px; }
  .story-ring { width: 74px; height: 74px; }
  .post-row { flex-direction: column; gap: 12px; padding: 22px; }
  .post-row-read { padding-top: 0; }
  .article-cta { padding: 24px; }
  /* Odd number of stats: let the last one span the row instead of leaving a hole. */
  .stat-cell:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .hero-actions .btn { flex: 1 1 auto; }
  .sheet-link { flex-direction: column; align-items: flex-start; gap: 8px; padding: 13px 12px; }
  .sheet-panel { padding-bottom: calc(18px + env(safe-area-inset-bottom)); }
}

@media (max-width: 640px) {
  .book-top { grid-template-columns: 110px 1fr; gap: 16px; }
}
