/* ============================================================
   AHMED BARRANI — CINEMATIC PORTFOLIO
   Dark editorial system · fluid type · motion-friendly
   ============================================================ */

:root {
  --bg-0: #0a0b0d;
  --bg-1: #0e1013;
  --bg-2: #121418;
  --bg-warm: #0d0c0b;
  --font-display: 'Manrope', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  --ink: #e8e6e1;
  --ink-dim: #9aa3ad;
  --ink-faint: #7d858f;
  --accent: #7ea8c9;
  --accent-dim: rgba(126, 168, 201, 0.35);
  --line: rgba(232, 230, 225, 0.09);
  --line-strong: rgba(232, 230, 225, 0.18);
  --max: 1440px;
  --gutter: clamp(1.25rem, 4vw, 4rem);
  --sec: clamp(5rem, 12vw, 11rem);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --font-sans: 'Manrope', 'Inter', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scrollbar-width: thin; scrollbar-color: #2a2e34 var(--bg-0); }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

body {
  background: var(--bg-0);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

::selection { background: var(--accent-dim); color: #fff; }

img, video, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------- TYPOGRAPHY ---------- */

.display {
  font-weight: 200;
  letter-spacing: -0.03em;
  line-height: 0.98;
  font-size: clamp(2.6rem, 8.5vw, 8.25rem);
  text-transform: uppercase;
}
.display .em { font-style: italic; font-weight: 300; color: var(--accent); }

.h2 {
  font-weight: 200;
  letter-spacing: -0.02em;
  line-height: 1.02;
  font-size: clamp(2rem, 5.5vw, 5rem);
  text-transform: uppercase;
}

.statement-lg {
  font-weight: 250;
  font-size: clamp(1.5rem, 3.4vw, 2.9rem);
  line-height: 1.28;
  letter-spacing: -0.01em;
}

.mono {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.mono--bright { color: var(--ink-dim); }
.mono--accent { color: var(--accent); }

.body-dim { color: var(--ink-dim); max-width: 62ch; }

/* ---------- LAYOUT ---------- */

.wrap { max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--sec); position: relative; }

.sec-head {
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
  margin-bottom: clamp(2rem, 5vw, 4rem);
}
.sec-head .rule {
  flex: 1; height: 1px; background: var(--line);
  align-self: center;
}
/* Section headings use the same visual language as the old mono labels,
   but they are real <h2> elements so screen readers can jump by section.
   Two levels inside: the chapter numeral is larger but quieter, the label
   keeps the accent — an index, not a decorated string. */
.sec-head__title {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
  flex-shrink: 0;
}
.sec-head__title.mono--bright { color: var(--ink-dim); }
.sec-head__num {
  font-size: 1.15rem;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  transition: color 0.5s var(--ease-out);
}
.sec-head__label { color: var(--accent); }
.sec-head:hover .sec-head__num { color: var(--ink-dim); }
/* The two labels outside a section head (the work opener's chapter, the
   direction line) share the numeral treatment so every chapter reads the
   same way across the page. */
.sec-label { display: inline-flex; align-items: baseline; gap: 0.6rem; }

/* ---------- TYPOGRAPHIC POLISH ----------
   Balance the big lines so no heading breaks awkwardly, let body copy
   avoid single-word widows, and hyphenate French — its long words
   otherwise push past the measure on narrow screens. */

h1, h2, h3, .statement-lg, .accent-lede, .future__sub, .contact__sub,
.pcard__title, .recognition__event { text-wrap: balance; }
p, li { text-wrap: pretty; }
.mono, .count, .stat__num { font-variant-numeric: tabular-nums; }
html[lang="fr"] p:not(.mono):not([class*="__num"]),
html[lang="fr"] li:not(.tags-item) { hyphens: auto; }

.chip {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.65rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  padding: 0.4rem 0.85rem;
  border-radius: 999px;
}
.chip .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #6fae8a;
  box-shadow: 0 0 8px rgba(111, 174, 138, 0.7);
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse { 50% { opacity: 0.45; } }

/* ---------- SKIP LINK ---------- */

.skip-link {
  position: fixed;
  top: 0; left: 50%;
  transform: translate(-50%, -120%);
  z-index: 400;
  background: var(--ink);
  color: var(--bg-0);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.8rem 1.5rem;
  border-radius: 0 0 6px 6px;
  transition: transform 0.25s var(--ease-out);
}
.skip-link:focus-visible,
.skip-link:focus {
  transform: translate(-50%, 0);
}

/* Screen-reader-only utility */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- NAVIGATION ---------- */

.nav {
  position: fixed; inset-inline: 0; top: 0; z-index: 93;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.1rem var(--gutter);
  transition: background 0.5s var(--ease-out), backdrop-filter 0.5s, border-color 0.5s;
  border-bottom: 1px solid transparent;
}
.nav.is-scrolled {
  background: rgba(10, 11, 13, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--line);
}
.nav__brand {
  font-family: var(--font-mono);
  font-size: 0.78rem; letter-spacing: 0.22em; font-weight: 600;
}
.nav__brand em { color: var(--accent); font-style: normal; }
.nav__links { display: flex; gap: clamp(1rem, 2.5vw, 2.25rem); list-style: none; align-items: center; }
.nav__link {
  font-family: var(--font-mono);
  font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-dim);
  position: relative;
  padding-block: 0.35rem;
  transition: color 0.3s;
}
.nav__link::after {
  content: '';
  position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--accent);
  transform: scaleX(0); transform-origin: right;
  transition: transform 0.45s var(--ease-out);
}
.nav__link:hover { color: var(--ink); }
.nav__link:hover::after { transform: scaleX(1); transform-origin: left; }
.nav__status { display: inline-flex; }
.nav__right { display: flex; align-items: center; gap: 1rem; }

/* Language switch — a quiet two-state pill, not a widget. */
.langswitch {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 2px;
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(10, 11, 13, 0.4);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.langswitch__btn {
  font-family: var(--font-mono);
  font-size: 0.6rem; letter-spacing: 0.12em;
  color: var(--ink-faint);
  padding: 0.3rem 0.55rem;
  border-radius: 999px;
  transition: color 0.35s, background 0.35s;
}
.langswitch__btn:hover { color: var(--ink); }
.langswitch__btn.is-active { color: var(--bg-0); background: var(--ink); }

.nav__link.is-active { color: var(--ink); }
.nav__link.is-active::after { transform: scaleX(1); transform-origin: left; }

/* CV gets a quiet outline so it reads as the one thing to click. */
.nav__link--cv {
  color: var(--ink);
  padding: 0.34rem 0.72rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  transition: color 0.35s, background 0.35s, border-color 0.35s;
}
.nav__link--cv::after { display: none; }
.nav__link--cv:hover { background: var(--ink); color: var(--bg-0); border-color: var(--ink); }

/* The Atlas: a gateway with a pulse. Same pill shape as the CV link,
   quieter colour — it is a second thing to explore, not the first. */
.nav__link--atlas {
  color: var(--ink);
  padding: 0.34rem 0.72rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  transition: color 0.35s, background 0.35s, border-color 0.35s;
}
.nav__link--atlas::after { display: none; }
.nav__link--atlas .atlas-keycap {
  font-size: 0.62em;
  color: var(--accent);
  animation: atlas-pulse 2.6s ease-in-out infinite;
}
.nav__link--atlas:hover {
  background: var(--ink);
  color: var(--bg-0);
  border-color: var(--ink);
}
.nav__link--atlas:hover .atlas-keycap { color: var(--ink); animation-duration: 1.2s; }

@media (max-width: 860px) {
  .nav__links--desktop { display: none; }
  .nav__status { display: none; }
  .nav__right { margin-left: auto; margin-right: 0.9rem; }
}

/* Mobile menu */
.burger {
  display: none;
  width: 40px; height: 40px;
  position: relative; z-index: 95;
}
.burger span {
  position: absolute; left: 9px; right: 9px; height: 1.5px;
  background: var(--ink);
  transition: transform 0.4s var(--ease-out), top 0.4s var(--ease-out), opacity 0.3s;
}
.burger span:nth-child(1) { top: 15px; }
.burger span:nth-child(2) { top: 24px; }
.burger.is-open span:nth-child(1) { top: 19.5px; transform: rotate(45deg); }
.burger.is-open span:nth-child(2) { top: 19.5px; transform: rotate(-45deg); }
@media (max-width: 860px) { .burger { display: block; } }

.mnav {
  position: fixed; inset: 0; z-index: 92;
  background: rgba(10, 11, 13, 0.985);
  display: flex; flex-direction: column; justify-content: center;
  padding: var(--gutter);
  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  transition: clip-path 0.55s var(--ease-out), visibility 0s 0.55s;
}
.mnav.is-open {
  clip-path: inset(0 0 0% 0);
  visibility: visible;
  transition: clip-path 0.55s var(--ease-out);
}
.mnav__list { list-style: none; }
.mnav__list li { overflow: hidden; border-bottom: 1px solid var(--line); }
.mnav__list a {
  display: block;
  padding: 1rem 0;
  font-size: clamp(1.8rem, 8vw, 2.6rem);
  font-weight: 200;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  transform: translateY(110%);
  transition: transform 0.55s var(--ease-out), color 0.3s;
}
.mnav.is-open .mnav__list a { transform: translateY(0); }
.mnav.is-open li:nth-child(2) a { transition-delay: 0.05s; }
.mnav.is-open li:nth-child(3) a { transition-delay: 0.1s; }
.mnav.is-open li:nth-child(4) a { transition-delay: 0.15s; }
.mnav.is-open li:nth-child(5) a { transition-delay: 0.2s; }
.mnav__foot { margin-top: 2.5rem; }
.mnav__cv {
  display: inline-flex; margin-top: 1.4rem;
  font-size: 0.68rem; letter-spacing: 0.18em;
  color: var(--accent);
  border-bottom: 1px solid currentColor; padding-bottom: 0.2rem;
}
.mnav__atlas {
  display: inline-flex; margin-top: 0.7rem;
  font-size: 0.68rem; letter-spacing: 0.18em;
  color: var(--ink-dim);
  border-bottom: 1px solid currentColor; padding-bottom: 0.2rem;
}

/* ---------- PROGRESS ---------- */

.progress {
  position: fixed; left: 0; top: 0; z-index: 91;
  width: 100%; height: 2px; pointer-events: none;
}
.progress__bar {
  height: 100%;
  background: var(--accent);
  transform-origin: left;
  transform: scaleX(0);
  opacity: 0.55;
}

/* ---------- CURSOR ---------- */

.cursor {
  position: fixed; top: 0; left: 0; z-index: 200;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: rgba(232, 230, 225, 0.85);
  pointer-events: none;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: width 0.32s var(--ease-out), height 0.32s var(--ease-out), opacity 0.3s, background 0.3s, mix-blend-mode 0.2s;
  mix-blend-mode: difference;
}
.cursor.is-active { opacity: 1; }
.cursor.is-hover {
  width: 44px; height: 44px;
  background: rgba(232, 230, 225, 0.18);
}
.cursor__label {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-family: var(--font-mono);
  font-size: 0.5rem; letter-spacing: 0.16em;
  color: var(--bg-0);
  opacity: 0;
  transition: opacity 0.2s;
  white-space: nowrap;
}
.cursor.is-labeled {
  width: 64px; height: 64px;
  background: rgba(232, 230, 225, 0.94);
  mix-blend-mode: normal;
}
.cursor.is-labeled .cursor__label { opacity: 1; }
@media (pointer: coarse) { .cursor { display: none; } }

/* ---------- HERO ---------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
.hero__media {
  position: absolute; inset: 0;
  overflow: hidden;
}
.hero__media video,
.hero__media canvas,
.hero__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0.42;
  filter: saturate(0.85) contrast(1.05);
}
.hero__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(10,11,13,0.97) 0%, rgba(10,11,13,0.45) 42%, rgba(10,11,13,0.72) 100%),
    radial-gradient(120% 90% at 50% 100%, rgba(10,11,13,0.5), transparent 60%);
}
/* A cool light that tracks the pointer — the frame feels lit, not painted. */
.hero__vignette {
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  background: radial-gradient(58% 52% at var(--mx, 50%) var(--my, 45%), rgba(126, 168, 201, 0.14), transparent 72%);
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 0.9s var(--ease-out);
}
.hero:hover .hero__vignette { opacity: 1; }

/* Slow, coarse film grain. Cheap: one tiled data-URI translated a few px. */
.hero__grain {
  position: absolute; inset: -10%; z-index: 1;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: heroGrain 1.4s steps(3) infinite;
  will-change: transform;
}
@keyframes heroGrain {
  0% { transform: translate3d(0, 0, 0); }
  33% { transform: translate3d(-1.5%, 1%, 0); }
  66% { transform: translate3d(1%, -1.5%, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* Editorial furniture that gives the top of the frame a job: a 12-column
   hairline grid, a ghosted monogram and a small technical rail. */
.hero__grid {
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  background-image: linear-gradient(90deg, rgba(232, 230, 225, 0.06) 1px, transparent 1px);
  background-size: 8.3333% 100%;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 18%, #000 82%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 18%, #000 82%, transparent 100%);
}
.hero__watermark {
  position: absolute; z-index: 1;
  left: 0; right: 0; top: clamp(7rem, 20vh, 15rem);
  text-align: center;
  font-family: var(--font-sans);
  font-size: clamp(6rem, 24vw, 22rem);
  font-weight: 200;
  line-height: 0.78;
  letter-spacing: 0.04em;
  white-space: nowrap;
  color: transparent;
  -webkit-text-stroke: 1px rgba(232, 230, 225, 0.9);
  opacity: 0.05;
  pointer-events: none;
  user-select: none;
}
.hero__rail {
  position: absolute; z-index: 3;
  top: clamp(5.2rem, 10vh, 7.4rem);
  left: 50%;
  transform: translateX(-50%);
  width: min(calc(100% - 2 * var(--gutter)), var(--max));
  display: flex; align-items: center; gap: clamp(0.8rem, 2vw, 1.5rem);
}
.hero__rail-item {
  font-size: 0.58rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}
.hero__rail-rule { flex: 1; height: 1px; background: var(--line); }
.hero__rail-clock { color: var(--ink-dim); display: inline-flex; align-items: baseline; gap: 0.5rem; }
.hero__rail-clock b {
  font-weight: 500; color: var(--ink); letter-spacing: 0.14em;
  font-variant-numeric: tabular-nums;
}
@media (max-width: 720px) {
  .hero__rail-item:nth-child(3) { display: none; }
  .hero__watermark { top: 20%; }
  .hero__grid { background-size: 25% 100%; }
}
.hero__inner {
  position: relative; z-index: 2;
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(3rem, 7vh, 5.5rem);
}
.hero__top {
  display: flex; justify-content: space-between; align-items: flex-start;
  margin-bottom: clamp(1.5rem, 4vh, 3rem);
}
.hero__title { text-transform: uppercase; }
.hero__title .line { display: block; overflow: hidden; }
.hero__title .line > span { display: block; }
.hero__meta {
  display: flex; flex-wrap: wrap; gap: 0.9rem 2.2rem;
  margin-top: clamp(1.5rem, 3.5vh, 2.5rem);
  align-items: baseline;
}
.hero__cv {
  font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink);
  padding-bottom: 0.22rem;
  border-bottom: 1px solid var(--line-strong);
  transition: color 0.3s, border-color 0.3s;
}
.hero__cv:hover { color: var(--accent); border-color: var(--accent); }
.hero__statement {
  margin-top: 1.25rem;
  max-width: 52ch;
  color: var(--ink-dim);
  font-size: clamp(0.95rem, 1.4vw, 1.1rem);
}
.scroll-hint {
  position: absolute; right: var(--gutter); bottom: clamp(3rem, 7vh, 5.5rem);
  display: flex; flex-direction: column; align-items: center; gap: 0.75rem;
  z-index: 2;
}
.scroll-hint .stem {
  width: 1px; height: 56px;
  background: linear-gradient(var(--accent), transparent);
  overflow: hidden;
  position: relative;
}
.scroll-hint .stem::after {
  content: '';
  position: absolute; inset: 0;
  background: var(--ink);
  animation: drip 2.2s var(--ease-out) infinite;
}
@keyframes drip { 0% { transform: translateY(-100%);} 60%,100% { transform: translateY(100%);} }
@media (max-width: 860px) { .scroll-hint { display: none; } }

/* ---------- STATEMENT ---------- */

.statement__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
}
@media (min-width: 900px) {
  .statement__grid { grid-template-columns: 1.5fr 1fr; align-items: end; }
}
.statement__aside { display: grid; gap: 1rem; justify-items: start; }

/* ---------- HORIZONTAL WORK ---------- */

.work { position: relative; }
.work__pin {
  height: 100svh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.work__head {
  padding: 0 var(--gutter);
  max-width: var(--max);
  margin-inline: auto;
  width: 100%;
  margin-bottom: clamp(1.5rem, 4vh, 3rem);
}
.work__track-wrap { overflow: hidden; width: 100%; }
/* The drag hint — a small affordance beside the SELECTED WORK heading
   telling the visitor the strip can actually be taken hold of. It is
   armed by JS only in grabbable mode (fine pointer, no reduced motion),
   shows once pinned, goes quiet while the hand is really down, and dims
   after the visitor's first successful grab: the message has landed. */
.work__drag-hint {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin-left: 0.4rem;
  color: var(--ink-dim);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  pointer-events: none;
  opacity: 0;
  translate: 0 3px;
  transition: opacity 0.7s var(--ease-out) 0.4s, translate 0.7s var(--ease-out) 0.4s, color 0.4s;
}
.work__drag-hint i {
  font-style: normal;
  display: inline-block;
  animation: drag-hint-drift 2.8s ease-in-out infinite;
}
@media (hover: hover) and (pointer: fine) {
  .work__pin.is-grabbable .work__drag-hint { opacity: 1; translate: 0 0; }
  .work__pin.has-dragged .work__drag-hint { opacity: 0.32; }
  body.work-dragging .work__drag-hint { opacity: 0 !important; transition-delay: 0s; }
}
@keyframes drag-hint-drift {
  0%, 100% { transform: translateX(0); }
  45%, 55% { transform: translateX(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .work__drag-hint i { animation: none; }
}
/* Mouse: the gallery is grabbable — pick it up and throw it. Touch keeps its
   native swipe; this only exists for a fine pointer. */
@media (hover: hover) and (pointer: fine) {
  .work__track { cursor: grab; }
  .work__track.is-dragging { cursor: grabbing; }
  body.work-dragging { user-select: none; -webkit-user-select: none; }
  body.work-dragging .work__track * { pointer-events: none; }
}
.work__track {
  display: flex;
  gap: clamp(1.5rem, 4vw, 4rem);
  padding-inline: var(--gutter);
  width: max-content;
  /* Cards size themselves to their own image ratio, so they are not all
     the same height — align them at the top rather than stretching. */
  align-items: flex-start;
}
.pcard {
  width: min(78vw, 880px);
  flex-shrink: 0;
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  will-change: transform;
  /* Tilt is written by GSAP into transform; hover lift and scale stay as
     their own properties so the two effects cannot overwrite each other. */
  transition:
    translate 0.55s var(--ease-out),
    scale 0.55s var(--ease-out),
    box-shadow 0.55s var(--ease-out);
}
/* A soft glare that follows the pointer across the card. On the active
   card only --gx/--gy are set by GSAP, so the glare stays dormant on the
   hovered-but-not-active cards instead of jumping to dead centers. */
.pcard::after {
  content: '';
  position: absolute; inset: 0; z-index: 4;
  pointer-events: none;
  background: radial-gradient(460px circle at var(--gx, 50%) var(--gy, 50%), rgba(255, 255, 255, 0.08), transparent 55%);
  opacity: 0;
  transition: opacity 0.4s var(--ease-out), background 0.4s;
}
.pcard:hover::after { opacity: 1; background: radial-gradient(480px circle at var(--gx, 50%) var(--gy, 50%), rgba(255, 255, 255, 0.14), transparent 55%); }
@media (hover: hover) and (pointer: fine) {
  .pcard:hover {
    translate: 0 calc(-7px - var(--hover-d, 0px));
    scale: calc(1.015 + var(--hover-sc, 0));
    box-shadow: 0 32px 60px -30px rgba(0, 0, 0, 0.9), 0 0 0 1px var(--accent);
  }
  .pcard__media {
    transition: box-shadow 0.55s var(--ease-out), border-color 0.4s;
    box-shadow: inset 0 0 0 1px transparent;
  }
  .pcard:hover .pcard__media {
    box-shadow: inset 0 0 0 1px rgba(126, 168, 201, 0.5);
  }
}
.pcard__media {
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  /* One shared box for every project card, so the track stays aligned.
     Sized to the screenshots' own ≈1.83:1 ratio: contain-fit covers stay
     uncropped and all three rectangles stay flush top and bottom. */
  aspect-ratio: 1.83;
  background: var(--bg-2);
}

/* Hover peek — a small second screenshot blooms in from the opposite
   corner as the pointer crosses the card, so the eye gets a second
   frame without losing the cover shot. The peek is the same source
   image, scaled down and clipped to a smaller ratio, then faded in and
   scaled from the corner opposite the pointer so it feels like it is
   being pushed out, not overlaid. It never blocks the cover, never
   fights the existing hover lift, and is disabled when there is no
   hover or when motion is reduced. */
.pcard__mirror {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  border-radius: 10px;
  overflow: hidden;
  opacity: 0;
  transform: scale(0.78);
  will-change: opacity, transform;
  /* Hard clip so the second screenshot never escapes its own box even
     when the cover's contain-fit leaves empty edges around it. */
  mask-image: linear-gradient(to bottom, #000 calc(100% - 2px), transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 2px), transparent 100%);
  transition:
    opacity 0.32s var(--ease-out),
    transform 0.36s var(--ease-out),
    inset 0.36s var(--ease-out);
  inset: auto 0 0 0;
}
.pcard__mirror.img-hidpi {
  /* Hi-res screenshots (e.g. 1600×1000 covers) are shrunk as contain-fit
     posters above a 1.83:1 canvas, so the mirror cannot use the same
     1.83:1 ratio or it would clip the subject. Let the mirror's own
     ratio follow the actual pixel aspect of the source instead, and keep
     it small enough that it reads as a thumbnail rather than a second
     cover. */
  aspect-ratio: attr(width) / attr(height);
}

/* The mirror lives in the same column as the cover, so it is sized on
   the same axes — it never exceeds the card's width, and on short cards
   it keeps a comfortable lower margin so it does not crowd the body text.
   The peek feels like a held breath: it appears only while the pointer
   is on the card, and settles back out the way it came. */
.pcard:hover .pcard__mirror {
  opacity: 0.84;
  transform: scale(1);
  /* Dock the peek to the bottom-right of the cover, where the pointer
     usually arrives last on a left-to-right reading, so the second frame
     feels discovered, not announced. */
  inset: auto 10px 10px auto;
  width: clamp(96px, 20vw, 156px);
  height: clamp(52px, 11vw, 86px);
}

.pcard__mirror-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.04);
  filter: saturate(1) contrast(1.04);
}

@media (hover: hover) and (pointer: fine) {
  .pcard:hover .pcard__mirror { opacity: 0.84; transform: scale(1); }
  .pcard:hover .pcard__mirror-img { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .pcard__mirror {
    transition: opacity 0.12s linear;
    transform: scale(0.96);
  }
  .pcard:hover .pcard__mirror {
    opacity: 0;
    transform: scale(0.92);
  }
}
.pcard__media img {
  width: 100%; height: 100%; object-fit: contain;
  transition: transform 0.9s var(--ease-out), filter 0.9s var(--ease-out);
  filter: saturate(0.9);
}
.pcard:hover .pcard__media img { transform: scale(1.045); filter: saturate(1); }
.pcard__num {
  position: absolute; top: 1.1rem; left: 1.2rem; z-index: 2;
  font-family: var(--font-mono);
  font-size: 0.72rem; letter-spacing: 0.2em;
  color: rgba(232,230,225,0.8);
  background: rgba(10,11,13,0.55);
  backdrop-filter: blur(6px);
  padding: 0.3rem 0.65rem;
  border-radius: 4px;
}
.pcard__body {
  display: flex; justify-content: space-between; gap: 2rem;
  padding-top: 1.2rem;
  align-items: flex-start;
}
.pcard__title {
  font-size: clamp(1.4rem, 2.6vw, 2.2rem);
  font-weight: 300; letter-spacing: -0.02em;
  transition: transform 0.55s var(--ease-out), color 0.4s;
}
.pcard:hover .pcard__title {
  transform: translateX(6px);
  color: var(--accent);
}
.pcard__cat { margin-top: 0.35rem; transition: color 0.4s, letter-spacing 0.4s; }
.pcard__desc {
  color: var(--ink-dim); font-size: 0.92rem; max-width: 42ch;
  margin-top: 0.6rem;
  transition: color 0.4s;
}
.pcard:hover .pcard__desc { color: var(--ink); }
.pcard__side { text-align: right; flex-shrink: 0; display: grid; gap: 0.5rem; justify-items: end; }
.pcard__cta {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.55rem 1.1rem;
  transition: background 0.4s, border-color 0.4s, color 0.4s, transform 0.4s var(--ease-out);
  background: transparent;
  will-change: transform;
}
.pcard:hover .pcard__cat { color: var(--accent); letter-spacing: 0.2em; }
.pcard:hover .pcard__desc { color: var(--ink); }
.pcard__stack {
  margin-top: 0.6rem;
  font-size: 0.56rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-faint);
  transition: color 0.4s;
}
.pcard__stack span { color: var(--accent); }
.pcard:hover .pcard__stack { color: var(--ink-dim); }
.pcard__cta:hover {
  background: var(--ink); color: var(--bg-0); border-color: var(--ink);
  transform: translateY(-1px) scale(1.02);
}
.pcard__cta .arr { transition: transform 0.4s var(--ease-out); }
.pcard__cta:hover .arr { transform: translateX(5px); }

.work__progress {
  display: flex; align-items: center; gap: 1.2rem;
  padding: 0 var(--gutter);
  max-width: var(--max);
  margin: clamp(1.5rem, 4vh, 3rem) auto 0;
  width: 100%;
}
.work__progress .track {
  flex: 1; height: 1px; background: var(--line-strong);
  position: relative; overflow: hidden;
}
.work__progress .fill {
  position: absolute; inset: 0;
  background: var(--accent);
  transform-origin: left;
  transform: scaleX(0.25);
}
.work__progress .count {
  font-family: var(--font-mono);
  font-size: 0.7rem; letter-spacing: 0.2em;
  color: var(--ink-dim);
}
/* The trailing label names the active project — allow it to truncate rather
   than shove the progress line off-screen on a phone. */
.work__progress [data-work-name] {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0; flex: 0 1 auto; text-align: right;
}

/* ---------- CASE STUDY ---------- */

.case {
  position: fixed; inset: 0; z-index: 110;
  background: radial-gradient(140% 120% at 50% 0%, rgba(20,24,30,0.78), rgba(10,11,13,0.97) 72%);
  overflow-y: auto;
  overscroll-behavior: contain;
  clip-path: inset(100% 0 0 0);
  visibility: hidden;
  transition: clip-path 0.7s var(--ease-out), visibility 0s 0.7s;
}
.case.is-open {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition: clip-path 0.7s var(--ease-out);
}
/* The picture that travels from the clicked card into the case study's
   hero. Fixed above the panel, invisible to the pointer, and removed the
   instant it lands — the real hero image is revealed at the same
   rectangle, so the handover is not perceptible. */
.case__flip {
  position: fixed; z-index: 130;
  object-fit: contain;
  pointer-events: none;
  background: var(--bg-1);
  will-change: transform, width, height, left, top;
  /* Ignore the card's existing hover lift so the flight is measured from
     the card's real resting geometry, not a hover-altered one. */
  translate: 0 0 !important;
  scale: 1 !important;
  /* A single soft vignette so the travelling picture does not read as a
     pasted crop floating in the void. */
  box-shadow:
    0 30px 90px -24px rgba(0,0,0,0.85),
    0 0 0 1px rgba(232,230,225,0.04);
  filter: saturate(1.02) contrast(1.02) brightness(1.01);
}
.case__flip.is-landing {
  filter: saturate(1) contrast(1) brightness(1);
  box-shadow: 0 0 0 0 rgba(0,0,0,0);
}
.case__close {
  position: fixed; top: 1.2rem; right: var(--gutter); z-index: 5;
  font-family: var(--font-mono);
  font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--ink-dim);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.6rem 1.2rem;
  background: rgba(10,11,13,0.6);
  backdrop-filter: blur(8px);
  transition: background 0.3s, color 0.3s;
}
.case__close:hover { background: var(--ink); color: var(--bg-0); }
.case__hero {
  position: relative;
  height: 62svh;
  min-height: 420px;
  overflow: hidden;
  background: var(--bg-1);
}
.case__hero img {
  width: 100%; height: 100%; object-fit: contain;
}
.case__hero::after {
  content: '';
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(14,16,19,0.05), rgba(10,11,13,0.28) 46%, rgba(10,11,13,0.9) 100%);
  transition: opacity 0.55s var(--ease-out);
}
.case__hero.is-landed::after {
  opacity: 0;
}
/* The hero box is viewport-shaped, not picture-shaped — contain the whole
   screenshot inside it instead of cropping into the UI. */
.case__hero img { width: 100%; height: 100%; object-fit: contain; background: var(--bg-1); }
.case__hero::after {
  content: '';
  position: absolute; inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(14,16,19,0.1), var(--bg-1) 96%);
}
.case__hero-text {
  position: absolute; inset-inline: 0; bottom: clamp(2rem, 6vh, 4rem);
  z-index: 2;
  padding-inline: var(--gutter);
  max-width: var(--max); margin-inline: auto;
}
.case__body { padding: clamp(2.5rem, 6vw, 5rem) var(--gutter); max-width: var(--max); margin-inline: auto; animation: case__body-in 0.7s var(--ease-out) 0.08s both; }
@keyframes case__body-in {
  from { opacity: 0; transform: translateY(10px); }
}
.case__source {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.6rem 1.2rem;
  margin-top: 1.4rem;
  background: rgba(10,11,13,0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background 0.4s var(--ease-out), color 0.4s, border-color 0.4s;
}
.case__source {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.6rem 1.2rem;
  margin-top: 1.4rem;
  background: rgba(10,11,13,0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background 0.4s var(--ease-out), color 0.4s, border-color 0.4s;
  animation: case__source-in 0.6s var(--ease-out) both;
}
@keyframes case__source-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.97);
  }
}
.case__source:hover { background: var(--ink); color: var(--bg-0); border-color: var(--ink); }
.case__source .arr { transition: transform 0.4s var(--ease-out); }
.case__source:hover .arr { transform: translate(3px, -3px); }

/* Live-site / source pills, side by side. */
.case__links { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.4rem; }
.case__links .case__source { margin-top: 0; }
.case__closing .case__links { justify-content: center; }
.case__closing .case__source { margin-top: 0; animation: case__source-in 0.6s var(--ease-out) 0.2s both; }
.case__closing .case__links { justify-content: center; }
.case__closing .case__source { margin-top: 0; }

/* ---------- LIGHTBOX ----------
   Click a screen figure in a case study to enlarge; ESC or click outside to close.
   Works on both phone and PC. */
.case__lightbox {
  position: fixed; inset: 0; z-index: 120;
  background: rgba(10,11,13,0.96);
  display: grid; place-items: center;
  opacity: 0; visibility: hidden;
  transition: opacity 0.4s var(--ease-out), visibility 0s 0.4s;
}
.case__lightbox.is-open {
  opacity: 1; visibility: visible;
}
.case__lightbox-img {
  max-width: min(90vw, 800px);
  max-height: min(85svh, 700px);
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 32px 96px rgba(0, 0, 0, 0.6);
  transition: transform 0.3s var(--ease-out);
}
.case__lightbox-img:hover {
  transform: scale(1.02);
}
.case__close-btn {
  position: fixed; top: 1rem; right: 1rem; z-index: 5;
  font-family: var(--font-mono);
  font-size: 1.5rem; color: var(--ink-dim);
  cursor: pointer;
  transition: color 0.3s;
}
.case__close-btn:hover { color: var(--ink); }
@media (pointer: coarse) {
  .case__close-btn { display: block; }
  .case__lightbox-img { max-width: min(95vw, 600px); max-height: min(90svh, 500px); }
}

.case__grid {
  display: grid; gap: clamp(2rem, 5vw, 4.5rem);
  grid-template-columns: 1fr;
  animation: case__grid-in 0.75s var(--ease-out) 0.25s both;
}
@keyframes case__grid-in {
  from { opacity: 0; transform: translateY(18px); }
}
@media (min-width: 900px) { .case__grid { grid-template-columns: 1fr 1fr; } }
.case__block { display: grid; gap: 1rem; align-content: start; }
.case__block p { color: var(--ink-dim); }
.arch {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: clamp(1.25rem, 3vw, 2.25rem);
  display: grid; gap: 0;
  background: var(--bg-2);
  animation: case__arch-in 0.75s var(--ease-out) 0.32s both;
}
@keyframes case__arch-in {
  from { opacity: 0; transform: translateY(12px); }
}

/* ---------- SYSTEM ARCHITECTURE DIAGRAM ----------
   The animated architecture map lives inside a case study's `.arch`
   block. It is a small, abstract, editorial diagram — not a generic
   network poster — and it only animates when the diagram is visible
   and motion is not reduced. */

.archviz {
  --av-line: rgba(126, 168, 201, 0.26);
  --av-line-strong: rgba(126, 168, 201, 0.5);
  --av-node-bg: var(--bg-1);
  --av-node-border: var(--line-strong);
  margin-top: clamp(1.5rem, 3.5vw, 2.5rem);
  border-top: 1px solid var(--line);
  padding-top: clamp(1.5rem, 3.5vw, 2.5rem);
}
.archviz__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: 1.6rem;
  flex-wrap: wrap;
}
.archviz__title {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}
.archviz__hint {
  font-family: var(--font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  transition: color 0.3s;
}
.archviz__hint:hover { color: var(--ink-dim); }

.archviz__stage {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: radial-gradient(120% 120% at 50% 40%, rgba(126, 168, 201, 0.05), transparent 70%), var(--bg-1);
  padding: clamp(1.1rem, 2.8vw, 2rem);
  min-height: 180px;
}
.archviz__rows {
  position: relative;
  display: grid;
  gap: clamp(0.9rem, 2.2vw, 1.6rem);
}
.archviz__band {
  position: relative;
  border-bottom: 1px dashed var(--line);
  padding-bottom: 0.8rem;
}
.archviz__band:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.archviz__band-label {
  font-family: var(--font-mono);
  font-size: 0.52rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.4rem;
}

.archviz__node {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--ink);
  background: var(--av-node-bg);
  border: 1px solid var(--av-node-border);
  border-left: 2px solid transparent;
  padding: 0.4rem 0.7rem 0.4rem 0.9rem;
  border-radius: 4px;
  cursor: pointer;
  transition:
    border-color 0.3s,
    background 0.3s,
    box-shadow 0.3s;
  outline: none;
}
.archviz__node:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-dim);
}
.archviz__node:hover,
.archviz__node.is-selected {
  border-left-color: var(--accent);
  border-color: rgba(126, 168, 201, 0.45);
  background: rgba(126, 168, 201, 0.06);
}
.archviz__node.is-active {
  border-left-color: var(--accent);
  background: rgba(126, 168, 201, 0.12);
  box-shadow: 0 0 0 1px rgba(126, 168, 201, 0.35);
}
.archviz__node__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.5;
  transition: opacity 0.3s;
}
.archviz__node.is-active .archviz__node__dot,
.archviz__node:hover .archviz__node__dot {
  opacity: 1;
}

.archviz__arrow {
  position: absolute;
  left: 50%;
  bottom: 100%;
  width: 1px;
  height: calc(var(--arrow-gap, 1rem) + 4px);
  background: var(--av-line);
  transform: translateX(-50%);
  pointer-events: none;
}
.archviz__arrow::after {
  content: '';
  position: absolute;
  left: 50%;
  top: -1px;
  width: 7px;
  height: 7px;
  border-left: 2px solid var(--av-line-strong);
  border-top: 2px solid var(--av-line-strong);
  transform: translate(-50%, -50%) rotate(-45deg);
  opacity: 0.7;
}

/* Packet animation — a small dot traveling along one arrow path. */
.archviz__packet {
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px rgba(126, 168, 201, 0.7);
  opacity: 0;
  pointer-events: none;
}
.archviz__packet.is-traveling {
  opacity: 1;
}

/* Detail panel — reveals what each node actually did in the build. */
.archviz__detail {
  margin-top: clamp(1.2rem, 2.6vw, 1.8rem);
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: 6px;
  padding: clamp(0.8rem, 1.8vw, 1.1rem) clamp(1rem, 2.4vw, 1.4rem);
  background: rgba(126, 168, 201, 0.04);
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition:
    max-height 0.45s var(--ease-out),
    opacity 0.4s var(--ease-out),
    margin-top 0.4s var(--ease-out);
  margin-top: 0;
}
.archviz__detail.is-open {
  max-height: 400px;
  opacity: 1;
  margin-top: clamp(1.2rem, 2.6vw, 1.8rem);
}
.archviz__detail__title {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.4rem;
}
.archviz__detail__body {
  font-size: 0.9rem;
  color: var(--ink-dim);
  line-height: 1.55;
}
.archviz__detail__body p + p {
  margin-top: 0.5rem;
}
.archviz__detail__body p {
  margin: 0;
  color: var(--ink-dim);
  line-height: 1.55;
}

@media (max-width: 640px) {
  .archviz__stage {
    padding: 1rem;
    min-height: 150px;
  }
  .archviz__node {
    font-size: 0.66rem;
    padding: 0.3rem 0.5rem 0.3rem 0.7rem;
  }
  .archviz__detail__body {
    font-size: 0.86rem;
  }
}
.arch__node {
  font-family: var(--font-mono);
  font-size: 0.78rem; letter-spacing: 0.12em;
  color: var(--ink);
  padding: 0.65rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg-1);
  text-align: center;
}
.arch__arrow {
  width: 1px; height: 1.4rem;
  background: var(--line-strong);
  margin-inline: auto;
  position: relative;
}
.arch__arrow::after {
  content: '';
  position: absolute; bottom: -1px; left: -3px;
  border-left: 3.5px solid transparent;
  border-right: 3.5px solid transparent;
  border-top: 6px solid var(--ink-faint);
}
.screens { display: grid; gap: 1.5rem; margin-top: clamp(2rem, 5vw, 4rem); animation: case__screens-in 0.75s var(--ease-out) 0.4s both; }
@keyframes case__screens-in {
  from { opacity: 0; transform: translateY(14px); }
}
@media (min-width: 760px) { .screens { grid-template-columns: 1fr 1fr; } }
.screens figure {
  overflow: hidden;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--bg-2);
  /* Screenshots are shown at their own aspect ratio (intrinsic width/height
     on the <img>), so nothing is cropped; only a gentle pointer response.
     NOTE: the case study's fade-up writes an inline `transform` on these
     figures, which would beat any :hover transform — so the lift uses the
     independent `translate` property, which composes with it. */
  transition: translate 0.55s var(--ease-out), box-shadow 0.55s var(--ease-out), border-color 0.4s;
}
.screens img {
  width: 100%;
  height: auto;
  object-fit: contain;
  transition: transform 0.7s var(--ease-out);
  will-change: transform;
}
@media (hover: hover) and (pointer: fine) {
  .screens figure:hover {
    translate: 0 -6px;
    border-color: var(--line-strong);
    box-shadow: 0 26px 50px -26px rgba(0, 0, 0, 0.8);
  }
  .screens figure:hover img { transform: scale(1.03); }
}
.screens figcaption { padding: 0.8rem 1rem; }
.tags { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.tags li {
  list-style: none;
  font-family: var(--font-mono);
  font-size: 0.65rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  padding: 0.4rem 0.8rem;
  border-radius: 999px;
}
.case__closing {
  padding: var(--sec) var(--gutter);
  text-align: center;
  animation: case__closing-in 0.9s var(--ease-out) 0.5s both;
}
@keyframes case__closing-in {
  from { opacity: 0; transform: translateY(14px); }
}

/* Scope at a glance — year, type and stack before the prose. */
.case__facts {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 2rem);
  margin: 0 0 clamp(2rem, 5vw, 3.5rem);
  padding-bottom: clamp(1.5rem, 4vw, 2.5rem);
  border-bottom: 1px solid var(--line);
  animation: case__facts-in 0.7s var(--ease-out) 0.12s both;
}
@keyframes case__facts-in {
  from { opacity: 0; transform: translateY(10px); }
}
.case__facts dt {
  font-size: 0.56rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--ink-faint); margin-bottom: 0.5rem;
}
.case__facts dd { margin: 0; color: var(--ink); font-size: 0.88rem; line-height: 1.55; }
@media (max-width: 700px) { .case__facts { grid-template-columns: 1fr; } }

/* Next project — keeps a recruiter reading instead of closing. */
.case__next {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: clamp(1rem, 2.5vw, 2rem);
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-top: clamp(1.2rem, 3vw, 2rem);
  border-top: 1px solid var(--line);
  animation: case__next-in 0.7s var(--ease-out) 0.4s both;
}
@keyframes case__next-in {
  from { opacity: 0; transform: translateY(10px); }
}
.case__next .mono {
  font-size: 0.58rem; letter-spacing: 0.2em;
  color: var(--ink-faint);
  transition: color 0.35s;
}
.case__next-title {
  font-family: var(--font-display); font-weight: 300;
  font-size: clamp(1.4rem, 3vw, 2.1rem); letter-spacing: -0.015em;
  transition: color 0.35s, transform 0.45s var(--ease-out);
}
.case__next-arrow { font-size: 1.35rem; transition: transform 0.45s var(--ease-out); }
.case__next:hover .case__next-title { color: var(--accent); transform: translateX(6px); }
.case__next:hover .mono { color: var(--ink); }
.case__next:hover .case__next-arrow { transform: translateX(6px); color: var(--accent); }
@media (max-width: 700px) {
  .case__next { grid-template-columns: 1fr auto; }
  .case__next .mono { grid-column: 1 / -1; }
}

/* ---------- CREATIVE GALLERY ---------- */

.creative { background: var(--bg-0); }
.creative__layout {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(1rem, 2.5vw, 2.5rem);
  align-items: start;
}
.citem { position: relative; cursor: pointer; }
.citem--wide { grid-column: span 12; }
.citem--tall { grid-column: span 6; }
.citem--square { grid-column: span 6; }
@media (max-width: 760px) { .citem--tall, .citem--square { grid-column: span 12; } }
.citem__media {
  overflow: hidden;
  border-radius: 10px;
  background: var(--bg-2);
}
.citem--wide .citem__media { aspect-ratio: 21/10; }
.citem--tall .citem__media { aspect-ratio: 4/5; }
.citem--square .citem__media { aspect-ratio: 1; }
.citem__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1s var(--ease-out);
  will-change: transform;
}
.citem__meta {
  display: flex; justify-content: space-between; align-items: baseline;
  padding-top: 0.85rem;
}
.citem__title { font-weight: 350; font-size: 1.05rem; }
/* The small caption that appears under the title in the expanded view. */
.citem__caption {
  margin-top: 0.6rem;
  font-size: clamp(0.98rem, 1.4vw, 1.18rem);
  font-weight: 300;
  color: var(--ink);
  max-width: 44ch;
  border-left: 2px solid var(--accent);
  padding-left: 0.9rem;
}
.citem__expanded {
  position: fixed; inset: 0; z-index: 110;
  background: rgba(8,9,11,0.97);
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 4rem);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s var(--ease-out), visibility 0s 0.5s;
}
.citem__expanded.is-open {
  opacity: 1; visibility: visible;
  transition: opacity 0.5s var(--ease-out);
}
.citem__expanded-inner {
  max-width: min(1100px, 92vw);
  width: 100%;
  transform: scale(0.92);
  transition: transform 0.6s var(--ease-out);
}
.citem__expanded.is-open .citem__expanded-inner { transform: scale(1); }
.citem__expanded img {
  width: 100%; max-height: 68svh; object-fit: contain;
  border-radius: 8px;
}
.citem__expanded-meta {
  display: flex; justify-content: space-between; gap: 2rem;
  padding-top: 1.2rem; align-items: flex-start;
}

/* ---------- TOOLKIT TILES ----------
   Live recreations of the tools named in profile.skills. No images,
   so there is nothing to crop and nothing to load — these stay sharp
   at any size and animate only while visible (see initTools). */
.citem__media { position: relative; }

.tool {
  position: absolute; inset: 0;
  overflow: hidden;
  background: #0c0e12;
  font-family: var(--font-mono);
  color: var(--ink-dim);
  user-select: none;
  --tool-line: rgba(232, 230, 225, 0.08);
  --tool-panel: rgba(232, 230, 225, 0.035);
}
/* ---- 3D TILES ----
   Each tile hosts a real WebGL object (src/js/logoTiles.js). The flat tile
   underneath is the no-JS / no-WebGL / pre-first-frame state, drawn from the
   same official artwork, so the upgrade changes depth and not identity.
   Sized in cqmin because the 3D camera frames the slab by the tile's
   SHORTER axis — the flat state has to match that or the swap would jump. */
.logo3d {
  position: absolute; inset: 0;
  container-type: size;
  --logo-bg: #001e36;
  background: radial-gradient(ellipse 62% 48% at 50% 46%, rgba(126, 168, 201, 0.09), transparent 70%);
}
.logo3d[data-logo3d="premierepro"] { --logo-bg: #2f2d8a; }
.logo3d[data-logo3d="lightroom"] { --logo-bg: #10314f; }
.logo3d[data-logo3d="terminal"] { --logo-bg: #141417; }

.logo3d__flat {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  transition: opacity 0.45s var(--ease-out);
}
.logo3d__flat img {
  width: 55.5cqmin;
  height: 55.5cqmin;
  background: var(--logo-bg);
  border-radius: 18%;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
}
.logo3d__canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  opacity: 0;
  transition: opacity 0.55s var(--ease-out);
}
.logo3d.is-ready .logo3d__canvas { opacity: 1; }
.logo3d.is-ready .logo3d__flat { opacity: 0; }

/* ---- expanded overlay ---- */
.citem__expanded .tool { position: relative; inset: auto; height: min(62svh, 560px); border-radius: 8px; border: 1px solid var(--line); }

/* ---- Recognition ---- */
.recognition__list { list-style: none; display: grid; gap: 1.4rem; max-width: 1120px; }
.recognition__item { border-top: 1px solid var(--line); padding-top: 1.2rem; }
.recognition__head { display: flex; justify-content: space-between; align-items: baseline; gap: 1.5rem; flex-wrap: wrap; }
.recognition__event { font-size: clamp(1.05rem, 2vw, 1.35rem); font-weight: 350; }
.recognition__place { color: var(--ink-faint); font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase; white-space: nowrap; }
.recognition__what { color: var(--ink-dim); margin-top: 0.5rem; max-width: 62ch; }
/* Optional proof link — only rendered when an entry has a URL. */
.recognition__proof {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.9rem;
  color: var(--accent);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
  transition: background 0.35s var(--ease-out), color 0.35s, border-color 0.35s;
}
.recognition__proof:hover { background: var(--ink); color: var(--bg-0); border-color: var(--ink); }
/* Proof media — a Facebook embed or a real photo, never both.
   On wide screens the proof sits BESIDE the text, so a 500px block never
   leaves half the row empty; on narrow screens it stacks underneath. */
.recognition__media { margin-top: 1.1rem; display: grid; gap: 0.9rem; justify-items: start; }
@media (min-width: 980px) {
  .recognition__item--media {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 500px;
    column-gap: clamp(2rem, 5vw, 4rem);
    /* Top-align both columns: the text stays one block at the top even
       when the proof beside it is much taller. */
    align-items: start;
  }
  .recognition__item--media .recognition__media { margin-top: 0; }
}
.recognition__embed {
  width: min(100%, 500px);
  height: var(--embed-h, 500px);
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--line);
  /* Dark until Facebook paints its own white document, so a slow or
     blocked embed is a quiet empty frame instead of a white void. */
  background: var(--bg-2);
}
.recognition__embed iframe { display: block; width: 100%; height: 100%; border: 0; }
.recognition__photo {
  width: min(100%, 500px);
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--line);
}
.recognition__photo img { display: block; width: 100%; height: auto; }
/* “View more photos” — reveals the rest of the set in a grid. */
.recognition__more {
  justify-self: start;
  color: var(--accent);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.45rem 1rem;
  background: transparent;
  cursor: pointer;
  transition: background 0.35s var(--ease-out), color 0.35s, border-color 0.35s;
}
.recognition__more:hover { background: var(--ink); color: var(--bg-0); border-color: var(--ink); }
.recognition__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
  width: 100%;
}
/* `display: grid` would otherwise beat the UA rule for [hidden]. */
.recognition__grid[hidden] { display: none; }
.recognition__thumb {
  margin: 0;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--line);
}
.recognition__thumb img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
.contact__offscreen { color: var(--ink-faint); margin-top: 1rem; letter-spacing: 0.06em; }

/* ---------- ABOUT ---------- */

.about__creativeline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1.5rem;
  padding-bottom: clamp(1.5rem, 3.5vw, 2.5rem);
  margin-bottom: clamp(1.5rem, 3.5vw, 2.5rem);
  border-bottom: 1px solid var(--line);
}
.about__grid {
  display: grid; gap: clamp(2.5rem, 6vw, 6rem);
  grid-template-columns: 1fr;
}
@media (min-width: 900px) { .about__grid { grid-template-columns: 1.2fr 1fr; } }
.about__text p + p { margin-top: 1.2rem; }
.about__text p { color: var(--ink-dim); max-width: 56ch; }
/* The education and interests entries reuse the experience card, but they
   sit in the narrow column — a single column keeps the heading on one line
   and the tags beneath it instead of squeezing both side by side. */
.about__grid .xp__item { grid-template-columns: 1fr; }
.big-words {
  display: flex; flex-wrap: wrap; gap: 0.4rem 1.4rem;
  margin-top: 2rem;
  font-size: clamp(1.6rem, 3.6vw, 3rem);
  font-weight: 200;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 1.15;
}
.big-words span { opacity: 0.25; transition: opacity 0.6s; }
.big-words span.on { opacity: 1; }

/* ---------- EXPERIENCE ---------- */

.xp { border-top: 1px solid var(--line); }
.xp__item {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.2rem 3rem;
  padding-block: clamp(1.75rem, 4vw, 3rem);
  border-bottom: 1px solid var(--line);
  cursor: default;
}
@media (min-width: 860px) { .xp__item { grid-template-columns: 1fr 1.6fr; } }
.xp__company { font-size: clamp(1.3rem, 2.4vw, 2rem); font-weight: 300; letter-spacing: -0.01em; }
.xp__period { margin-top: 0.5rem; }
.xp__role { font-weight: 500; margin-bottom: 0.9rem; }
.xp__list { list-style: none; display: grid; gap: 0.45rem; }
.xp__list li {
  color: var(--ink-dim);
  padding-left: 1.1rem;
  position: relative;
  font-size: 0.95rem;
  transition: color 0.3s;
}
.xp__list li::before {
  content: '—';
  position: absolute; left: 0; color: var(--ink-faint);
  transition: color 0.3s;
}

/* Hover is a warm shift, not a jump: the entry stays put, the copy comes
   forward. Kept to fine pointers so touch devices never latch the state. */
@media (hover: hover) and (pointer: fine) {
  .xp__item:hover .xp__company,
  .xp__item:hover .xp__period,
  .xp__item:hover .xp__role { color: var(--accent); }
  .xp__item:hover .xp__list li { color: var(--accent-dim); }
  .xp__item:hover .xp__list li::before { color: var(--accent); }
}

/* ---------- SKILLS ---------- */

.skills {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line);
}
.skill-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem 4rem;
  padding-block: clamp(1.5rem, 3.5vw, 2.5rem);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 860px) { .skill-row { grid-template-columns: 280px 1fr; } }
.skill-row h3 {
  font-family: var(--font-mono);
  font-size: 0.75rem; letter-spacing: 0.2em; font-weight: 500;
  color: var(--accent);
  text-transform: uppercase;
  padding-top: 0.35rem;
}
.skill-row ul {
  list-style: none;
  display: flex; flex-wrap: wrap; gap: 0.6rem;
}
.skill-row li {
  font-size: 0.92rem;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.45rem 1rem;
  transition: color 0.3s, border-color 0.3s, transform 0.3s;
}
.skill-row li:hover { color: var(--ink); border-color: var(--line-strong); transform: translateY(-2px); }

.langs {
  display: flex; flex-wrap: wrap; gap: clamp(1.5rem, 4vw, 4rem);
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
}
.lang { display: grid; gap: 0.3rem; }
.lang b { font-weight: 500; font-size: 1.05rem; letter-spacing: 0.02em; }

/* ---------- FUTURE ---------- */

.future {
  text-align: left;
  background:
    radial-gradient(90% 70% at 80% 20%, rgba(61, 90, 117, 0.13), transparent 60%),
    var(--bg-1);
}
.future .display { max-width: 14ch; }
.future__sub {
  margin-top: 2rem;
  color: var(--ink-dim);
  max-width: 46ch;
  font-size: clamp(1rem, 1.6vw, 1.2rem);
}

/* ---------- EXPERIENCE — credit note ----------
   A quiet line under an entry's bullets: smaller, dimmer, narrower than the
   list so it reads as attribution rather than another achievement. */
.xp__note {
  margin-top: 1.2rem;
  color: var(--ink-dim);
  opacity: 0.85;
  font-size: 0.88rem;
  line-height: 1.65;
  max-width: 56ch;
  padding-left: 1rem;
  border-left: 1px solid var(--line);
  transition: color 0.4s, border-color 0.4s, opacity 0.4s;
}
@media (hover: hover) and (pointer: fine) {
  .xp__item:hover .xp__note {
    opacity: 1;
    color: var(--accent-dim);
    border-left-color: var(--accent);
  }
}

/* ---------- ANTHEM LEDE ----------
   Ahmed’s tiny national anthem: a short, confident how-I-work line that sits
   right under the future heading. Plain phrasing, low volume, one accent when
   the reader leans in. */
.accent-lede {
  margin-top: 1.25rem;
  color: var(--ink-dim);
  font-size: clamp(0.98rem, 1.3vw, 1.1rem);
  line-height: 1.5;
  max-width: 46ch;
  padding: 1rem 1.1rem 1rem 1.3rem;
  border-left: 2px solid var(--ink-faint);
  background: rgba(232, 230, 225, 0.025);
  border-radius: 0 6px 6px 0;
  transition: color 0.4s var(--ease-out), border-color 0.4s, background 0.4s;
}
@media (hover: hover) and (pointer: fine) {
  .future:hover ~ .wrap .accent-lede,
  .accent-lede:hover {
    color: var(--ink);
    border-left-color: var(--accent);
    background: rgba(126, 168, 201, 0.06);
  }
}

/* ---------- how-i-work strapline ----------
   A compact monospace footer under the anthem: “a working tag” for Ahmed.
   Keep it quiet; let the pitch above carry the energy. */
.howline {
  margin-top: 0.8rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  transition: color 0.4s;
}

.anthem {
  margin-top: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: block;
  line-height: 1.7;
  max-width: 72ch;
}

@media (hover: hover) and (pointer: fine) {
  .future:hover ~ .wrap .howline,
  .howline:hover {
    color: var(--accent);
  }
  .future:hover ~ .wrap .anthem,
  .anthem:hover {
    color: var(--accent);
  }
}

/* ---------- CONTACT ---------- */

.contact {
  background: var(--bg-warm);
  min-height: 92svh;
  display: flex; align-items: flex-end;
}
.contact__inner {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding: var(--sec) var(--gutter) 3rem;
}
.contact__title { text-transform: uppercase; }
.contact__sub {
  margin-top: 1.5rem;
  color: var(--ink-dim);
  max-width: 48ch;
}
.contact__actions {
  display: flex; flex-wrap: wrap; gap: 0.9rem;
  margin-top: clamp(2rem, 5vw, 3.5rem);
}
.btn {
  display: inline-flex; align-items: center; gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.72rem; letter-spacing: 0.18em; text-transform: uppercase;
  padding: 0.95rem 1.7rem;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  transition: background 0.4s var(--ease-out), color 0.4s, border-color 0.4s;
  position: relative;
}
.btn { overflow: hidden; }
.btn::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(110deg, transparent 32%, rgba(255, 255, 255, 0.18) 50%, transparent 68%);
  transform: translateX(-130%);
  transition: transform 0.85s var(--ease-out);
  pointer-events: none;
}
.btn:hover::after { transform: translateX(130%); }
.btn--primary { background: var(--ink); color: var(--bg-0); border-color: var(--ink); }
.btn--primary:hover { background: var(--accent); border-color: var(--accent); color: #0a0b0d; }
.btn--ghost:hover { background: rgba(232,230,225,0.08); }
.btn .arr { transition: transform 0.4s var(--ease-out); }
.btn:hover .arr { transform: translateX(4px); }
.contact__meta {
  display: flex; flex-wrap: wrap; gap: 1rem 3rem;
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}
.copied-toast {
  position: fixed;
  left: 50%; bottom: 2rem;
  transform: translate(-50%, 20px);
  z-index: 130;
  font-family: var(--font-mono);
  font-size: 0.68rem; letter-spacing: 0.2em;
  background: var(--ink); color: var(--bg-0);
  padding: 0.6rem 1.2rem;
  border-radius: 999px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s, transform 0.35s var(--ease-out);
}
.copied-toast.is-show { opacity: 1; transform: translate(-50%, 0); }

.contact__meta > div { min-width: 120px; }
.contact__social-links { display: flex; flex-direction: column; gap: 0.35rem; margin-top: 0.4rem; }
.contact__social-links a {
  font-size: 0.95rem;
  color: var(--ink-dim);
  transition: color 0.3s;
  width: fit-content;
}
.contact__social-links a:hover { color: var(--accent); }
/* Phone reads as plain text but is a real tel: link, so a visitor on a
   phone can call without retyping the number. */
.contact__tel { display: inline-block; width: fit-content; transition: color 0.3s; }
.contact__tel:hover { color: var(--accent); }

/* ---------- FOOTER ---------- */

.footer {
  background: var(--bg-warm);
  padding: 2rem var(--gutter) 2.2rem;
  border-top: 1px solid var(--line);
}
.footer__inner {
  max-width: var(--max); margin-inline: auto;
  display: flex; flex-wrap: wrap; gap: 1rem 2.5rem;
  align-items: center; justify-content: space-between;
}
.footer__name { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.2em; }
.footer__links { display: flex; gap: 1.4rem; flex-wrap: wrap; }
.footer__links a {
  font-family: var(--font-mono); font-size: 0.65rem;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-faint);
  transition: color 0.3s;
}
.footer__links a:hover { color: var(--ink); }
.footer__copy { font-family: var(--font-mono); font-size: 0.6rem; color: var(--ink-faint); letter-spacing: 0.14em; }

/* signpost: the exact paths a recruiter can be sent straight to */
.footer__share { flex-basis: 100%; }
.footer__share-label {
  font-size: 0.58rem; letter-spacing: 0.22em;
  color: var(--ink-faint);
  margin: 0 0 0.55rem;
}
.footer__share-list {
  list-style: none;
  display: flex; flex-wrap: wrap; gap: 0.4rem 1.6rem;
  padding: 0; margin: 0;
}
.footer__share-list a {
  font-family: var(--font-mono); font-size: 0.68rem;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
  text-decoration: none;
  transition: color 0.3s;
}
.footer__share-list a:hover,
.footer__share-list a:focus-visible {
  color: var(--ink);
}
.footer__share-list a span { color: var(--ink-faint); }

/* ---------- PRELOADER ---------- */

.preloader {
  position: fixed; inset: 0; z-index: 300;
  background: var(--bg-0);
  display: grid; place-items: center;
  transition: opacity 0.6s var(--ease-out), visibility 0s 0.6s;
  /* Decorative: it lingers in the DOM while fading out — never eat a click. */
  pointer-events: none;
}
.preloader.is-done { opacity: 0; visibility: hidden; }
.preloader__inner { display: grid; gap: 1.1rem; justify-items: center; }
.preloader__bar {
  width: 120px; height: 1px; background: var(--line-strong);
  overflow: hidden;
}
.preloader__bar::after {
  content: '';
  display: block; height: 100%;
  background: var(--accent);
  transform-origin: left;
  animation: preload 1.1s var(--ease-out) forwards;
}
@keyframes preload { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---------- FILM GRAIN ---------- */

body::after {
  content: '';
  position: fixed; inset: 0; z-index: 200;
  pointer-events: none;
  opacity: 0.026;
  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='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- SMALL HOVERS ---------- */

.chip { transition: color 0.4s, border-color 0.4s; }
.chip:hover { color: var(--ink); border-color: var(--line-strong); }
.tags li {
  transition: color 0.3s, border-color 0.3s, background 0.3s, transform 0.3s;
}
.tags li:hover {
  color: var(--ink);
  border-color: var(--line-strong);
  background: rgba(232, 230, 225, 0.04);
  transform: translateY(-2px);
}

/* ---------- STATS BAND ----------
   Proof at a glance: four numbers, hairline-separated, right under the hero. */

.stats {
  position: relative;
  background: var(--bg-1);
  border-block: 1px solid var(--line);
}
.stats__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.4rem, 3vw, 2.5rem);
  padding-block: clamp(2rem, 4.5vw, 3.2rem);
}
.stat { position: relative; }
.stat + .stat {
  border-left: 1px solid var(--line);
  padding-left: clamp(1rem, 3vw, 2.2rem);
}
.stat__num {
  font-size: clamp(2.3rem, 5.5vw, 4rem);
  font-weight: 200;
  letter-spacing: -0.03em;
  line-height: 0.95;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.stat__suffix { color: var(--accent); font-size: 0.5em; margin-left: 0.08em; vertical-align: top; }
.stat__label {
  margin-top: 0.75rem;
  font-size: 0.62rem;
  color: var(--ink-faint);
  max-width: 22ch;
}
@media (max-width: 760px) {
  .stats__grid { grid-template-columns: repeat(2, 1fr); gap: 1.8rem 0; }
  .stat + .stat { border-left: 0; padding-left: 0; }
  .stat:nth-child(2n) { border-left: 1px solid var(--line); padding-left: 1.2rem; }
  .stat:nth-child(n + 3) { border-top: 1px solid var(--line); padding-top: 1.6rem; }
}

/* ---------- SECTION TRANSITIONS ----------
   A clipped light-sweep that crosses each chapter once as it arrives. */

.contact { position: relative; }
.sec-wipe {
  position: absolute; inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 3;
}
.sec-wipe__band {
  position: absolute; left: -8%; right: -8%; top: -40%; height: 68%;
  display: block;
  background: linear-gradient(180deg, transparent, rgba(240, 238, 232, 0.055) 50%, transparent);
}

/* ---------- ZOOMABLE GALLERIES ----------
   Milestone photos behave like buttons: pointer or keyboard opens the
   shared lightbox, hover previews the crop. */

button.recognition__thumb,
button.recognition__photo {
  display: block; width: 100%;
  padding: 0; background: none; font: inherit; text-align: left;
  cursor: zoom-in;
  transition: border-color 0.35s var(--ease-out), transform 0.4s var(--ease-out);
}
.recognition__photo { cursor: zoom-in; }
button.recognition__thumb img,
.recognition__photo img {
  transition: transform 0.6s var(--ease-out), filter 0.6s var(--ease-out);
}
button.recognition__thumb:hover,
button.recognition__photo:hover { border-color: var(--line-strong); transform: translateY(-3px); }
button.recognition__thumb:hover img,
.recognition__photo:hover img { transform: scale(1.05); filter: brightness(1.05); }
button.recognition__thumb:focus-visible,
button.recognition__photo:focus-visible,
.screen-figure:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.screen-figure { cursor: zoom-in; }

/* ---------- AMBIENT SOUND TOGGLE ----------
   Deliberately small, but it has to read as a control rather than as a
   line of dust in the footer: its own pill, a real border, and a meter
   that visibly moves once the sound is on. */

.sound-toggle {
  display: inline-flex; align-items: center; gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.63rem; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--ink-dim);
  background: var(--bg-1);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.45rem 0.95rem;
  min-height: 34px;
  cursor: pointer;
  transition: color 0.3s, border-color 0.3s, background 0.3s;
}
.sound-toggle:hover,
.sound-toggle:focus-visible {
  color: var(--ink);
  border-color: var(--ink-dim);
  background: var(--bg-2);
  outline: none;
}
.sound-toggle:focus-visible { box-shadow: 0 0 0 2px var(--accent-dim); }
.sound-toggle__bars { display: inline-flex; align-items: flex-end; gap: 2px; height: 12px; }
.sound-toggle__bars i {
  display: block; width: 2px; height: 4px;
  background: currentColor; border-radius: 1px;
  opacity: 0.6;
  transition: opacity 0.3s;
}
.sound-toggle[aria-pressed="true"] {
  color: var(--accent);
  border-color: var(--accent-dim);
  background: var(--bg-2);
}
.sound-toggle[aria-pressed="true"] .sound-toggle__bars i { opacity: 1; animation: eq 0.9s ease-in-out infinite alternate; }
.sound-toggle[aria-pressed="true"] .sound-toggle__bars i:nth-child(2) { animation-delay: 0.18s; }
.sound-toggle[aria-pressed="true"] .sound-toggle__bars i:nth-child(3) { animation-delay: 0.36s; }
@keyframes eq { from { height: 4px; } to { height: 12px; } }

/* ---------- SOUND DOCK — the pinned control ----------
   A dot at rest, a label on hover or focus. Built and toggled by
   ambient.js; it stays hidden until the hero is out of the way, and sits
   below the nav (93), the mobile menu (92) and every overlay, so it can
   never fight them for the same corner. */

.sound-dock {
  position: fixed;
  left: clamp(1rem, 3vw, 2rem);
  bottom: calc(clamp(1rem, 3vw, 2rem) + env(safe-area-inset-bottom, 0px));
  z-index: 90;
  height: 40px;
  min-width: 40px;
  padding: 0;
  gap: 0;
  justify-content: center;
  border-radius: 999px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.34);
  opacity: 0;
  translate: 0 10px;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.5s var(--ease-out),
    translate 0.5s var(--ease-out),
    padding 0.35s var(--ease-out),
    gap 0.35s var(--ease-out),
    color 0.3s,
    border-color 0.3s,
    background 0.3s,
    visibility 0s linear 0.5s;
}
.sound-dock.is-visible {
  opacity: 1;
  translate: 0 0;
  visibility: visible;
  pointer-events: auto;
  transition-delay: 0s;
}

/* The label is collapsed by max-width, so the pill grows out of the dot
   instead of the layout jumping. */
.sound-dock__label {
  max-width: 0;
  opacity: 0;
  overflow: hidden;
  white-space: nowrap;
  transition: max-width 0.4s var(--ease-out), opacity 0.25s var(--ease-out);
}
.sound-dock:hover,
.sound-dock:focus-visible {
  padding: 0 0.95rem;
  gap: 0.55rem;
}
.sound-dock:hover .sound-dock__label,
.sound-dock:focus-visible .sound-dock__label {
  max-width: 12ch;
  opacity: 1;
}

/* No hover on touch: the label stays out so the control is readable. */
@media (hover: none) {
  .sound-dock {
    padding: 0 0.95rem;
    gap: 0.55rem;
  }
  .sound-dock__label {
    max-width: 12ch;
    opacity: 1;
  }
}

/* One quiet cue the first time the toggle is actually on screen: four
   alternating cycles (an even count, so the bars land back at rest), with
   the voices staggered like they are when the sound is on. Added and
   removed by ambient.js; nothing here runs on its own. */
.sound-toggle--hint .sound-toggle__bars i {
  animation: eq 0.5s ease-in-out 4 alternate;
}
.sound-toggle--hint .sound-toggle__bars i:nth-child(2) { animation-delay: 0.1s; }
.sound-toggle--hint .sound-toggle__bars i:nth-child(3) { animation-delay: 0.2s; }
@media (prefers-reduced-motion: reduce) {
  .sound-toggle--hint .sound-toggle__bars i { animation: none; }
}


/* ---------- FAVICON OVERRIDES
   Light-mode browsers that lock the address bar to the 32px variant. */

:root.theme-light {
  --bg-0: #ffffff;
  --bg-1: #f4f4f6;
  --bg-2: #ececf0;
  --bg-warm: #f9f9fb;
  --ink: #111114;
  --ink-dim: #3a3a42;
  --ink-faint: #7a7a84;
  --accent: #0a3d5c;
  --line: rgba(17, 17, 20, 0.11);
  --line-strong: rgba(17, 17, 20, 0.22);
}

/* ---------- REDUCED MOTION ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal-line > span { transform: none !important; }
  .reveal-fade { opacity: 1 !important; transform: none !important; }
  .cursor, .scroll-hint { display: none; }
  .hero__media video, .hero__media canvas, .hero__media img { opacity: 0.5; }
  .btn::after { display: none; }
  body::after { display: none; }
}

/* ---------- RESUME / CV PAGE ----------
   Bilingual, print-ready document. The purpose-built hero carries
   your credentials; the real content starts there, not at the top. */

.cv { background: var(--bg-0); min-height: 100vh; color: var(--ink); }
.cv__toolbar {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.5rem 1.25rem; position: sticky; top: 0; z-index: 60;
  background: var(--bg-1); border-block: 1px solid var(--line);
}
.cv__logo {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink-faint);
}
.cv__logo b { color: var(--ink); }
.cv__logo .em { color: var(--accent); font-style: normal; }
.cv__toolbar-right { margin-left: auto; display: flex; align-items: center; gap: 0.6rem; }
.cv__lang {
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--ink-faint);
  background: transparent; border: 1px solid var(--line-strong); border-radius: 999px;
  padding: 0.3rem 0.6rem; cursor: pointer; transition: color 0.3s, border-color 0.3s, background 0.3s;
}
.cv__lang[aria-pressed="true"] { color: var(--ink); border-color: var(--ink); background: rgba(232,230,225,0.04); }
.cv__print {
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--ink-faint);
  background: transparent; border: 1px solid var(--line-strong); border-radius: 999px;
  padding: 0.3rem 0.6rem; cursor: pointer; transition: color 0.3s, border-color 0.3s, background 0.3s;
}
.cv__print:hover { color: var(--ink); border-color: var(--ink); background: rgba(232,230,225,0.04); }
.cv__toolbar-rules { display: flex; gap: 0.5rem; align-items: center; }
.cv__toolbar-rule {
  height: 11px; width: 1px; background: var(--line-strong);
  border-radius: 1px;
}

.cv__hero {
  position: relative; overflow: hidden;
  padding: clamp(3rem, 8vw, 6rem) var(--gutter) clamp(2.5rem, 5vw, 4rem);
  border-block: 1px solid var(--line);
}
.cv__grid {
  position: absolute; inset: 0; display: grid;
  grid-template-columns: repeat(12, 1fr);
  pointer-events: none;
}
.cv__grid::before {
  content: ''; grid-column: 1 / -1;
  background-image: linear-gradient(to right, var(--line) 1px, transparent 1px);
  background-size: 100% 8.33%;
}

.cv__head {
  position: relative; z-index: 2;
  max-width: 780px; margin-inline: auto;
}
.cv__brand {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.22em;
  text-transform: uppercase; margin-bottom: 2rem;
}
.cv__brand .hash { color: var(--ink-faint); }
.cv__name {
  font-family: var(--font-display); font-size: clamp(3rem, 6.5vw, 5.2rem);
  font-weight: 300; letter-spacing: -0.02em; line-height: 0.95; color: var(--ink);
}
.cv__name .alt { color: var(--accent); }
.cv__role {
  font-family: var(--font-mono); margin-top: 1.4rem;
  font-size: clamp(0.85rem, 1.4vw, 1.05rem); letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-faint); line-height: 1.55;
}
.cv__role .em { color: var(--ink); font-style: normal; }
.cv__meta {
  margin-top: 2.2rem; display: grid; gap: 0.35rem;
}
.cv__meta-item {
  display: flex; gap: 0.75rem; align-items: baseline; flex-wrap: wrap;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-faint);
}
.cv__meta-label { color: var(--ink-faint); }
.cv__meta-value {
  color: var(--ink); text-decoration: none; transition: color 0.3s;
}
.cv__meta-value:hover { color: var(--accent); }
.cv__chip {
  margin-top: 1.6rem; display: inline-flex; gap: 0.6rem; align-items: center;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: #fff; background: var(--accent); padding: 0.45rem 0.75rem; border-radius: 999px;
  text-transform: uppercase;
}
.cv__chip .dot { width: 7px; height: 7px; border-radius: 50%; background: #fff; }
.cv__tag {
  display: inline-block; font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--accent); background: transparent;
  border: 1px solid var(--line-strong); border-radius: 999px; padding: 0.32rem 0.6rem;
  transition: color 0.3s, border-color 0.3s, background 0.3s;
}
.cv__tag:hover { color: var(--ink); border-color: var(--ink); background: rgba(232,230,225,0.05); }

.cv__body {
  position: relative; z-index: 2;
  width: 100%; max-width: 780px; margin-inline: auto;
  padding: clamp(2rem, 5vw, 3.5rem) var(--gutter) clamp(2rem, 6vw, 5rem);
  display: grid; gap: clamp(2rem, 5vw, 4rem);
}

.cv__section {
  border-block: 1px solid var(--line); padding-block: clamp(1.1rem, 2.5vw, 1.6rem);
}
.cv__strap {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 1.15rem;
}
.cv__strap-proof {
  margin-top: 1.1rem; max-width: 62ch; color: var(--ink-dim);
  font-size: 0.95rem; line-height: 1.55;
}
.cv__section-divider {
  height: 1px; background: var(--line-strong); margin: 0;
}
.cv__section-h {
  display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: 1rem;
  margin-bottom: 0.9rem;
}
.cv__section-num {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--accent);
}
.cv__section-title {
  font-family: var(--font-display); font-size: clamp(1.5rem, 2.6vw, 2rem); font-weight: 300;
  letter-spacing: -0.01em; color: var(--ink);
}
.cv__section-dots {
  display: flex; gap: 0.5rem; align-items: center;
}
.cv__section-dot {
  width: 4px; height: 4px; border-radius: 50%; background: var(--ink-faint);
  border: 1px solid transparent;
}

.cv__company {
  font-family: var(--font-display); font-size: clamp(1.35rem, 2.2vw, 1.7rem);
  font-weight: 300; letter-spacing: -0.01em; color: var(--ink); line-height: 1.2;
}
.cv__company .em { color: var(--accent); font-style: normal; }
.cv__period {
  margin-top: 0.45rem; font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--ink-faint);
}
.cv__role {
  margin-top: 0.4rem; font-size: clamp(1.05rem, 1.6vw, 1.25rem); color: var(--ink); line-height: 1.45;
}
.cv__role-cargo { color: var(--ink-dim); }
.cv__points {
  margin-top: 0.75rem; display: grid; gap: 0.35rem;
}
.cv__point {
  display: grid; grid-template-columns: 14px 1fr; gap: 0.6rem; align-items: flex-start;
  font-size: clamp(0.95rem, 1.4vw, 1.05rem); color: var(--ink-dim); line-height: 1.5;
}
.cv__point::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); margin-top: 0.65rem;
}
.cv__point::after {
  content: ''; width: 1px; height: 1px; background: var(--ink-faint); margin-bottom: 0.1rem;
}
.cv__team-note {
  margin-top: 0.9rem; padding: 0.85rem 1rem; background: rgba(232,230,225,0.03);
  border: 1px solid var(--line); border-radius: 8px; color: var(--ink-faint); font-style: normal;
  font-size: 0.9rem; line-height: 1.55;
}

.cv__edu-meta {
  display: grid; gap: 0.2rem; margin-top: 0.35rem;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-faint);
}
.cv__edu-areas {
  margin-top: 0.85rem; display: flex; flex-wrap: wrap; gap: 0.5rem;
}

.cv__langs {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1.7rem; margin-top: 0.5rem;
}
.cv__lang {
  display: block; text-align: left;
}
.cv__lang-name {
  font-family: var(--font-display); font-size: clamp(1.1rem, 1.7vw, 1.4rem); color: var(--ink);
  font-weight: 300; letter-spacing: -0.01em;
}
.cv__lang-name .em { color: var(--accent); font-style: normal; }
.cv__lang-level {
  margin-top: 0.3rem; font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-faint);
}

.cv__skills {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.4rem, 3vw, 2.2rem) clamp(2rem, 4vw, 3rem);
  margin-top: 0.5rem;
}
.cv__skillgroup-name {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 0.55rem;
}
.cv__skillgroup-tags {
  display: flex; flex-wrap: wrap; gap: 0.45rem;
}

.cv__projects {
  border-block: none; padding-block: 0;
}
.cv__project-row {
  display: grid; grid-template-columns: 2.2rem 1fr auto; gap: 1rem; align-items: baseline;
  padding-block: 0.6rem; border-block: 1px solid var(--line); border-radius: 6px;
  transition: background 0.3s, border-color 0.3s;
  cursor: pointer; text-decoration: none;
}
.cv__project-row:hover { background: rgba(232,230,225,0.03); border-color: var(--line-strong); }
.cv__project-num {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.2em;
  color: var(--accent); align-self: start; padding-top: 0.1rem;
}
.cv__project-title {
  font-family: var(--font-display); font-size: clamp(1.15rem, 1.7vw, 1.35rem); color: var(--ink);
  font-weight: 300; letter-spacing: -0.005em; line-height: 1.2; transition: color 0.3s;
}
.cv__project-row:hover .cv__project-title { color: var(--accent); }
.cv__project-cat {
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-faint);
}
.cv__project-tech {
  display: inline-flex; gap: 0.4rem; align-items: baseline;
}
.cv__project-tech-tag {
  font-family: var(--font-mono); font-size: 0.55rem;
}

.cv__foot {
  margin-top: auto; padding-block: 1.2rem;
  border-top: 1px solid var(--line);
}
.cv__foot-lines {
  display: flex; justify-content: space-between; align-items: baseline; gap: 2rem;
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-faint);
}
.cv__foot-links { display: flex; gap: 1.2rem; }
.cv__foot-links a { color: var(--ink-faint); transition: color 0.3s; }
.cv__foot-links a:hover { color: var(--ink); }

@media print {
  html { background: #fff; color: #111; }
  body { background: #fff; color: #111; }
  .cv__toolbar, .no-print { display: none !important; }
  .contact__social, .cv__foot-links { display: none !important; }
  .cv__head, .cv__head a { color: #000; }
  .chip { display: none !important; }
  * { box-shadow: none !important; transition: none !important; animation: none !important; }
  p, li, td { color: #111 !important; }
  .cv__team .note { font-style: normal !important; color: #333 !important; }
  .table-of-contents { break-inside: avoid; }
  .cv__section-divider { break-after: avoid; }
  .cv__project-row { break-inside: avoid; }
  .cv__project-row { break-after: avoid; }
  .cv__langs { grid-template-columns: 1fr 1fr 1fr; }
}


/* ---------- STANDALONE CASE STUDY PAGE ----------
   Same case-study blocks as the dialog, promoted to a real document
   with its own URL and a minimal topbar. */

.casepage { background: var(--bg-0); }

.casepage__bar {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; gap: 1rem;
  padding: 0.8rem var(--gutter);
  background: rgba(10, 11, 13, 0.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.casepage__brand {
  font-family: var(--font-mono);
  font-size: 0.74rem; letter-spacing: 0.22em; font-weight: 600;
}
.casepage__brand em { color: var(--accent); font-style: normal; }
.casepage__back {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-dim);
  transition: color 0.3s;
}
.casepage__back:hover { color: var(--ink); }

.casepage .case__hero { height: clamp(360px, 58svh, 720px); }
.casepage .case__body { padding-top: clamp(2rem, 5vw, 4rem); }

.casepage__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  max-width: var(--max); margin-inline: auto;
  padding: 1.5rem var(--gutter);
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.6rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-faint);
}
.casepage__foot-links { display: flex; gap: 1.4rem; flex-wrap: wrap; }
.casepage__foot a { transition: color 0.3s; }
.casepage__foot a:hover { color: var(--ink); }
.casepage__tagline {
  flex-basis: 100%; margin: 0.6rem 0 0; font-size: 0.6rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--ink-faint);
}

@media (max-width: 640px) {
  .casepage__bar { gap: 0.7rem; padding-block: 0.7rem; }
  .casepage__back { font-size: 0.56rem; letter-spacing: 0.12em; }
}

/* ---------- LIGHTBOX / ZOOM VIEWER ----------
   One viewer for every image on the site. Opens over the page (and
   over a case-study dialog), zooms with buttons, wheel, double-click
   or pinch, and pans by dragging while zoomed. */

.zoom {
  position: fixed; inset: 0; z-index: 300;
  display: grid; place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(6, 7, 9, 0.95);
  -webkit-backdrop-filter: blur(20px) saturate(0.85);
  backdrop-filter: blur(20px) saturate(0.85);
  opacity: 0; visibility: hidden;
  transition: opacity 0.35s var(--ease-out), visibility 0s 0.35s;
  overscroll-behavior: contain;
}
.zoom.is-open {
  opacity: 1; visibility: visible;
  transition: opacity 0.35s var(--ease-out);
}
.zoom [hidden] { display: none !important; }

.zoom__stage {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  gap: 0.9rem;
  max-width: 100%; max-height: 100%;
}
.zoom__img {
  max-width: min(88vw, 1500px);
  max-height: 74svh;
  width: auto; height: auto;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 40px 120px rgba(0, 0, 0, 0.65);
  transform-origin: center center;
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  cursor: zoom-in;
  user-select: none;
  -webkit-user-drag: none;
  touch-action: none;
}
.zoom.is-zoomed .zoom__img { cursor: grab; }
.zoom.is-dragging .zoom__img { cursor: grabbing; }
.zoom__caption {
  max-width: min(72ch, 88vw);
  text-align: center;
  font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-dim);
}
.zoom.is-switching .zoom__img { animation: zoomFade 0.45s var(--ease-out); }
@keyframes zoomFade { from { opacity: 0.35; } to { opacity: 1; } }

.zoom__count {
  position: absolute; top: clamp(1rem, 3vw, 1.6rem); left: var(--gutter);
  font-size: 0.6rem; letter-spacing: 0.2em;
  color: var(--ink-dim);
}

.zoom__btn {
  position: absolute;
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: rgba(14, 16, 19, 0.72);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--ink-dim);
  font-size: 1rem;
  transition: background 0.3s, color 0.3s, border-color 0.3s, transform 0.3s;
}
.zoom__btn:hover { background: var(--ink); color: var(--bg-0); border-color: var(--ink); }
.zoom__btn--close { top: clamp(1rem, 3vw, 1.6rem); right: var(--gutter); }
.zoom__nav { top: 50%; transform: translateY(-50%); }
.zoom__nav:hover { transform: translateY(-50%) scale(1.06); }
.zoom__nav--prev { left: clamp(0.6rem, 2.5vw, 2rem); }
.zoom__nav--next { right: clamp(0.6rem, 2.5vw, 2rem); }

.zoom__zoom {
  position: absolute;
  left: 50%; bottom: clamp(1rem, 3vw, 1.8rem);
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 0.35rem;
  padding: 0.35rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(10, 11, 13, 0.72);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}
.zoom__zoom .zoom__btn {
  position: static;
  width: 38px; height: 38px;
  border: 0; background: transparent;
}
.zoom__zoom .zoom__btn:hover { background: var(--ink); color: var(--bg-0); }
.zoom__zoom-level { min-width: 58px; font-size: 0.55rem; letter-spacing: 0.08em; }

@media (max-width: 700px) {
  .zoom__img { max-width: 92vw; max-height: 68svh; }
  .zoom__btn { width: 40px; height: 40px; }
  .zoom__zoom .zoom__btn { width: 36px; height: 36px; }
  .zoom__caption { font-size: 0.54rem; }
  .zoom__nav--prev { left: 0.4rem; }
  .zoom__nav--next { right: 0.4rem; }
}

/* ---------- ARCHITECTURE DIAGRAM (drawn map of one project) ----------
   Wires are computed from the laid-out node boxes, so the drawing
   follows the layout instead of hard-coding it: it re-flows with the
   column change on mobile and with the length of a French label. */
.archviz-wrap { margin-top: clamp(2.5rem, 6vw, 5rem); }
.archviz { margin: 0; }
.archviz__caption {
  font-weight: 300;
  font-size: clamp(1.05rem, 1.7vw, 1.35rem);
  line-height: 1.5;
  color: var(--ink-dim);
  max-width: 58ch;
  margin-bottom: clamp(1.6rem, 3vw, 2.6rem);
}
.archviz__frame { position: relative; }
.archviz__wires {
  position: absolute; inset: 0; width: 100%; height: 100%;
  overflow: visible; z-index: 0; pointer-events: none;
}
.archviz__wire { fill: none; stroke: var(--line-strong); stroke-width: 1.25; }
.archviz__wires marker path { fill: var(--line-strong); }
.archviz.is-drawn .archviz__wire { stroke: color-mix(in srgb, var(--line-strong) 70%, var(--accent)); }
.archviz.is-drawn .archviz__wires marker path { fill: color-mix(in srgb, var(--line-strong) 70%, var(--accent)); }
.archviz__labels { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.archviz__wire-label {
  position: absolute;
  font-size: 0.55rem; letter-spacing: 0.14em;
  color: var(--ink-faint);
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 2px 6px;
  white-space: nowrap;
}
.archviz__bands {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.78fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  /* A diagram wants a diagram's measure — left-aligned in the column,
     not stretched to the full text width. */
  max-width: 60rem;
}
.archviz__band--cloud {
  border-left: 1px dashed var(--line-strong);
  padding-left: clamp(1.5rem, 3vw, 3rem);
}
.archviz__band-label { margin-bottom: 1.1rem; color: var(--ink-dim); }
.archviz__stack { display: grid; gap: clamp(2.75rem, 5vw, 3.6rem); max-width: 30rem; }
.archviz__band--cloud .archviz__stack { max-width: 26rem; }
.archviz__node {
  position: relative;
  display: grid; gap: 0.45rem;
  text-align: left;
  padding: 1rem 1.15rem;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink);
  cursor: pointer;
  font: inherit;
  transition:
    border-color 0.4s var(--ease-out), background 0.4s var(--ease-out),
    box-shadow 0.4s var(--ease-out), translate 0.4s var(--ease-out),
    opacity 0.7s cubic-bezier(0.22,1,0.36,1), transform 0.7s cubic-bezier(0.22,1,0.36,1);
}
.archviz__node-title { font-size: 1rem; font-weight: 500; letter-spacing: -0.01em; }
.archviz__node-sub { font-size: 0.56rem; letter-spacing: 0.13em; color: var(--ink-faint); }
.archviz__node:hover { border-color: var(--line-strong); background: var(--bg-1); }
.archviz__node:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.archviz__node.is-selected {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
}
.archviz__node.is-selected .archviz__node-sub { color: var(--accent); }
@media (hover: hover) and (pointer: fine) {
  .archviz__node:hover { translate: 0 -2px; }
}
.archviz__detail {
  position: relative;
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
  padding: 1.15rem 1.25rem;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  min-height: 7rem;
  max-width: 74ch;
}
.archviz__detail p { color: var(--ink-dim); font-size: 0.95rem; line-height: 1.65; }
.archviz__detail-title { margin-bottom: 0.6rem; color: var(--accent); }
.archviz__hint {
  font-family: var(--font-mono);
  font-size: 0.66rem !important;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint) !important;
}
.archviz__detail.is-shown { animation: archviz-detail-in 0.5s var(--ease-out) both; }
@keyframes archviz-detail-in {
  from { opacity: 0; transform: translateY(8px); }
}
@media (max-width: 760px) {
  .archviz__bands { grid-template-columns: minmax(0, 1fr); gap: 2.75rem; }
  .archviz__band--cloud {
    border-left: none;
    border-top: 1px dashed var(--line-strong);
    padding-left: 0;
    padding-top: 1.75rem;
  }
  .archviz__stack { gap: 3rem; }
  .archviz__wire-label { font-size: 0.5rem; letter-spacing: 0.1em; }
}

/* ============================================================
   KNOWLEDGE ATLAS — standalone interactive page
   Scoped to .atlaspage / .atlas-*. Nothing here leaks into the
   homepage sections.
   ============================================================ */

.atlaspage {
  /* Deep space: a steel-blue haze, one barely-there warm ember, and a
     vignette — depth for the transparent WebGL canvas, at 3–6% opacity
     so the network stays the only bright thing on screen. */
  background:
    radial-gradient(1300px 1000px at 16% 10%, rgba(126, 168, 201, 0.055), transparent 62%),
    radial-gradient(1050px 850px at 86% 90%, rgba(214, 172, 118, 0.04), transparent 58%),
    radial-gradient(rgba(148, 176, 200, 0.05), transparent 45%),
    radial-gradient(140% 120% at 50% 44%, transparent 52%, rgba(0, 0, 0, 0.6) 100%),
    #0a0b0d;
  overflow: hidden;
  height: 100dvh;
}

.atlas {
  position: relative;
  height: 100dvh;
  width: 100%;
  overflow: hidden;
}

/* ---------- top bar ---------- */

.atlas-bar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(0.8rem, 2vw, 1.3rem) clamp(1rem, 3vw, 2rem);
  background: linear-gradient(to bottom, rgba(10, 11, 13, 0.92), rgba(10, 11, 13, 0));
  pointer-events: none;
}
.atlas-bar > * { pointer-events: auto; }

.atlas-brand {
  font-weight: 300;
  letter-spacing: 0.14em;
  font-size: 1rem;
  color: var(--ink);
  text-decoration: none;
}
.atlas-brand em {
  font-style: normal;
  color: var(--accent);
  font-weight: 500;
}
.atlas-bar__title {
  display: none;
  font-size: 0.66rem;
  letter-spacing: 0.34em;
  color: var(--ink-faint);
}
@media (min-width: 900px) {
  .atlas-bar__title { display: block; }
}

.atlas-bar__right {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.atlas-back {
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-decoration: none;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.45rem 0.95rem;
  transition: color 0.3s, border-color 0.3s;
  white-space: nowrap;
}
.atlas-back:hover, .atlas-back:focus-visible {
  color: var(--ink);
  border-color: var(--line-strong);
  outline: none;
}

/* ---------- stage ---------- */

.atlas-stage {
  position: absolute;
  inset: 0;
}

.atlas-canvas-wrap {
  position: absolute;
  inset: 0;
}
.atlas-canvas-wrap canvas { display: block; }

.atlas-labels {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
/* speed-scaled motion feedback: while the camera travels fast the labels
   pick up a brief motion blur — stepped CSS classes only, never per-frame
   inline styles, so the idle map costs nothing. */
.atlas-labels { transition: filter 0.3s ease; }
.atlas-labels.is-cam-moving { filter: blur(1.1px); }
.atlas-labels.is-cam-racing { filter: blur(2.4px); }
@media (prefers-reduced-motion: reduce) {
  .atlas-labels { transition: none; }
  .atlas-labels.is-cam-moving,
  .atlas-labels.is-cam-racing { filter: none; }
}
.atlas-label {
  position: absolute;
  top: 0; left: 0;
  pointer-events: auto;
  background: none;
  border: none;
  padding: 0.15rem 0.4rem;
  font-family: var(--font-mono);
  font-size: clamp(0.52rem, 1vw, 0.64rem);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
  cursor: pointer;
  white-space: nowrap;
  text-shadow: 0 2px 12px rgba(10, 11, 13, 0.9);
  transition: color 0.25s, opacity 0.25s;
  will-change: transform;
}
.atlas-label:hover,
.atlas-label:focus-visible,
.atlas-label.is-focus {
  color: var(--ink);
  outline: none;
}
.atlas-label.is-dim,
.atlas-label.is-dimmed { opacity: 0.28; }
.atlas-label:focus-visible { box-shadow: 0 0 0 1px var(--line-strong); border-radius: 3px; }

/* ---------- intro sequence ----------
   While .is-intro is on the body the chrome and labels hold at zero;
   atlas.js releases them once the sky and network have arrived.
   Transitions double as the normal (non-intro) fade for labels. */

.atlaspage.is-intro .atlas-bar,
.atlaspage.is-intro .atlas-intro,
.atlaspage.is-intro .atlas-hint,
.atlaspage.is-intro .atlas-hud,
.atlaspage.is-intro .atlas-label { opacity: 0; }

.atlas-bar,
.atlas-intro,
.atlas-hint,
.atlas-hud { transition: opacity 0.9s ease; }
.atlas-bar { transition-delay: 0.05s; }
.atlas-intro { transition-delay: 0.2s; }
.atlas-hint { transition-delay: 0.4s; }
.atlas-hud { transition-delay: 0.55s; }
.atlas-label { transition: opacity 0.6s ease; }

/* ---------- chrome text ---------- */

.atlas-intro {
  position: fixed;
  left: clamp(1rem, 3vw, 2rem);
  bottom: clamp(4.4rem, 9vw, 7rem);
  z-index: 20;
  max-width: 34ch;
  font-size: clamp(0.8rem, 1.4vw, 0.95rem);
  line-height: 1.6;
  color: var(--ink-dim);
  pointer-events: none;
}
.atlas-hint {
  position: fixed;
  left: clamp(1rem, 3vw, 2rem);
  bottom: calc(clamp(1rem, 3vw, 2rem) + env(safe-area-inset-bottom, 0px));
  z-index: 20;
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  pointer-events: none;
}
@media (max-width: 759px) {
  .atlas-intro {
    max-width: 21ch;
    font-size: 0.78rem;
    background: rgba(10, 11, 13, 0.72);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 0.7rem 0.9rem;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
  }
  /* Lifted clear of the HUD: the search pill and the chip row now own
     the bottom-right corner, and the hint used to run underneath them. */
  .atlas-hint {
    max-width: 44vw;
    font-size: 0.55rem;
    bottom: calc(6.4rem + env(safe-area-inset-bottom, 0px));
  }
  .atlas-label {
    padding: 0.3rem 0.5rem;   /* taller hit area for taps */
    font-size: 0.56rem;       /* lifts the 1vw clamp's 8px floor */
  }
}

/* ---------- HUD ---------- */

.atlas-hud {
  position: fixed;
  z-index: 30;
  inset: auto clamp(1rem, 3vw, 2rem) calc(clamp(0.8rem, 2vw, 1.2rem) + env(safe-area-inset-bottom, 0px)) auto;
  display: flex;
  align-items: flex-end;
  gap: 0.8rem;
  pointer-events: none;
}
.atlas-hud > * { pointer-events: auto; }
/* mid-width band: the full chrome (search + chips + zoom) is wider than
   the space left of the intro lede — wrap the chips onto their own row
   so nothing crosses the text. */
@media (min-width: 900px) and (max-width: 1180px) {
  .atlas-hud {
    flex-wrap: wrap;
    justify-content: flex-end;
    max-width: 52vw;
  }
  .atlas-searchbox { order: 2; }
  .atlas-chips { order: 1; flex-basis: 100%; }
  .atlas-view { order: 2; }
}

.atlas-searchbox { position: relative; }

.atlas-search {
  width: clamp(13rem, 24vw, 17rem);
  background: rgba(10, 11, 13, 0.72);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  padding: 0.62rem 1.1rem;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: border-color 0.3s;
}
.atlas-search::placeholder { color: var(--ink-faint); }
.atlas-search:focus {
  outline: none;
  border-color: var(--line-strong);
}
.atlas-search::-webkit-search-cancel-button { -webkit-appearance: none; }

.atlas-results {
  position: absolute;
  right: 0;
  bottom: calc(100% + 0.6rem);
  min-width: min(20rem, 72vw);
  background: rgba(10, 11, 13, 0.94);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 0.4rem;
  margin: 0;
  list-style: none;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
}
.atlas-results button,
.atlas-results__empty {
  width: 100%;
  text-align: right;
  background: none;
  border: none;
  color: var(--ink-dim);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  padding: 0.55rem 0.8rem;
  border-radius: 8px;
  cursor: pointer;
  text-transform: none;
}
.atlas-results button:hover,
.atlas-results button:focus-visible {
  color: var(--ink);
  background: rgba(126, 168, 201, 0.08);
  outline: none;
}
.atlas-results__empty {
  color: var(--ink-faint);
  cursor: default;
}

.atlas-chips {
  display: none;
  gap: 0.4rem;
  flex-wrap: wrap-reverse;
  justify-content: flex-end;
}
@media (min-width: 900px) { .atlas-chips { display: flex; } }
/* Phones keep the cluster filter too: a single scrollable row of chips
   above the search, so a tap can still narrow the map instead of the
   visitor only being able to pan around it. */
@media (max-width: 899px) {
  .atlas-hud {
    left: clamp(1rem, 3vw, 2rem);
    flex-wrap: wrap;
    justify-content: flex-end;
    row-gap: 0.5rem;
  }
  .atlas-chips {
    display: flex;
    flex-wrap: nowrap;
    flex-basis: 100%;
    justify-content: flex-start;
    gap: 0.35rem;
    overflow-x: auto;
    padding-bottom: 0.15rem;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .atlas-chips::-webkit-scrollbar { display: none; }
  .atlas-chip { flex: 0 0 auto; }
  .atlas-searchbox { order: 2; }
  .atlas-view { order: 3; }
}

.atlas-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  background: rgba(10, 11, 13, 0.72);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink-dim);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  padding: 0.5rem 0.9rem;
  cursor: pointer;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: color 0.3s, border-color 0.3s;
}
.atlas-chip i {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--chip, var(--accent));
  opacity: 0.7;
}
.atlas-chip:hover,
.atlas-chip:focus-visible {
  color: var(--ink);
  border-color: var(--line-strong);
  outline: none;
}
.atlas-chip[aria-pressed="true"] {
  color: var(--ink);
  border-color: var(--line-strong);
  background: rgba(126, 168, 201, 0.1);
}

.atlas-view {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.atlas-btn {
  width: 2.4rem; height: 2.4rem;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(10, 11, 13, 0.72);
  color: var(--ink-dim);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: color 0.3s, border-color 0.3s, transform 0.3s;
}
.atlas-btn:hover,
.atlas-btn:focus-visible {
  color: var(--ink);
  border-color: var(--line-strong);
  outline: none;
  transform: translateY(-1px);
}

/* ---------- detail panel ---------- */

.atlas-panel {
  position: fixed;
  z-index: 40;
  right: clamp(1rem, 3vw, 2rem);
  top: clamp(4rem, 9vw, 6.5rem);
  width: min(21rem, calc(100vw - 2rem));
  max-height: min(76dvh, 40rem);
  overflow-y: auto;
  background: rgba(10, 11, 13, 0.96);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 1.5rem 1.6rem 1.7rem;
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}
.atlas-panel[hidden] { display: none; }

.atlas-panel__close {
  position: absolute;
  top: 0.7rem; right: 0.8rem;
  width: 2rem; height: 2rem;
  border-radius: 50%;
  border: 1px solid transparent;
  background: none;
  color: var(--ink-faint);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  transition: color 0.3s, border-color 0.3s;
}
.atlas-panel__close:hover,
.atlas-panel__close:focus-visible {
  color: var(--ink);
  border-color: var(--line);
  outline: none;
}

.atlas-panel__tag {
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  color: var(--accent);
  margin: 0 0 0.55rem;
}
.atlas-panel__title {
  font-size: 1.25rem;
  font-weight: 400;
  letter-spacing: -0.01em;
  margin: 0 0 0.8rem;
  padding-right: 1.4rem;
}
.atlas-panel__desc {
  font-size: 0.9rem;
  line-height: 1.7;
  color: var(--ink-dim);
  margin: 0 0 1.2rem;
}
.atlas-panel__label {
  font-size: 0.58rem;
  letter-spacing: 0.22em;
  color: var(--ink-faint);
  margin: 1.1rem 0 0.55rem;
}

.atlas-panel__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.atlas-panel__chip {
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.3rem 0.65rem;
}

.atlas-panel__links {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 1.1rem;
}
.atlas-panel__link {
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.45rem;
  transition: color 0.3s, border-color 0.3s;
}
.atlas-panel__link:hover,
.atlas-panel__link:focus-visible {
  color: var(--accent);
  border-color: var(--line-strong);
  outline: none;
}

.atlas-panel__related {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.atlas-panel__rel {
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--ink-dim);
  background: none;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.3rem 0.65rem;
  cursor: pointer;
  transition: color 0.3s, border-color 0.3s;
}
.atlas-panel__rel:hover,
.atlas-panel__rel:focus-visible {
  color: var(--ink);
  border-color: var(--line-strong);
  outline: none;
}

@keyframes atlas-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/* touch targets: everything a thumb presses clears the 44px floor
   (kept after the base rules so the cascade actually applies it) */
@media (max-width: 759px) {
  .atlas-btn { width: 2.85rem; height: 2.85rem; }
  .atlas-search {
    padding: 0.78rem 1.15rem;
    font-size: 0.78rem;
    width: min(14rem, 62vw);
  }
  .atlas-panel__close { width: 2.8rem; height: 2.8rem; top: 0.4rem; right: 0.4rem; }
}
