/* Erfan Naji — erfannaji.com · design system locked from exploration round 7b */

* { box-sizing: border-box; margin: 0; padding: 0; }
img { display: block; max-width: 100%; height: auto; }
html { scroll-behavior: smooth; }
button { font: inherit; border: none; cursor: pointer; background: none; }
textarea { font: inherit; border: none; background: none; resize: none; width: 100%; color: inherit; }
textarea:focus { outline: none; }

:root {
  --ink: #0B0E0F;
  --ink-2: #10161A;
  --panel: #0E1417;
  --porcelain: #F3F1EA;
  --grey: #9FB0B3;
  --line: rgba(243, 241, 234, .14);
  --line-strong: rgba(243, 241, 234, .3);
  --water: #7FB2C4;
  --petroleum: #0C3440;
  --mist: #7E9296; /* muted text tier: 5.9:1 on ink; on petroleum use only inside the darkened composer (≈4.8:1) */
  --display: "Bricolage Grotesque", system-ui, sans-serif;
  --sans: "DM Sans", system-ui, sans-serif;
  --ease: cubic-bezier(.16, 1, .3, 1);
  --gutter: clamp(1.25rem, 4vw, 4rem);
}
body { background: var(--ink); color: var(--porcelain); font-family: var(--sans);
  line-height: 1.5; min-width: 320px; overflow-x: clip; -webkit-font-smoothing: antialiased; }
body.menu-open { overflow: hidden; }

.skip-link { position: fixed; top: -100%; left: var(--gutter); z-index: 200;
  background: var(--porcelain); color: var(--ink); padding: .7rem 1.2rem; border-radius: 2px;
  font-weight: 500; text-decoration: none; }
.skip-link:focus-visible { top: .8rem; }

::selection { background: var(--water); color: var(--ink); }
a:focus-visible, button:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--water); outline-offset: 3px; }

/* Text for screen readers only. Where a numeral carries meaning that its
   own glyph cannot ("4" alone is not "4 notes observed"), the sentence is
   spelled out here and the visual parts are hidden from the tree. */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; white-space: nowrap;
  clip: rect(0 0 0 0); clip-path: inset(50%); }

/* ================= intro (home only) ================= */
.intro { position: fixed; inset: 0; z-index: 100; background: var(--ink);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.4rem; }
.intro-mark { font-family: var(--display); font-weight: 600; letter-spacing: .3em;
  font-size: clamp(1.4rem, 4vw, 2.6rem); display: flex; overflow: hidden; }
.intro-mark span { display: inline-block; white-space: pre; transform: translateY(120%); }
.intro-line { width: 0; height: 1px; background: var(--water); }
html.anim .intro-mark span { animation: letter-up .7s var(--ease) forwards;
  animation-delay: calc(.25s + var(--i) * .045s); }
html.anim .intro-line { animation: line-grow .8s var(--ease) .9s forwards; }
html.anim .intro { animation: curtain .8s var(--ease) 1.9s forwards; }
@keyframes letter-up { to { transform: translateY(0); } }
@keyframes line-grow { to { width: clamp(8rem, 20vw, 14rem); } }
@keyframes curtain { to { transform: translateY(-100%); visibility: hidden; } }
html:not(.anim) .intro { display: none; }

/* ================= reveals (JS-gated: visible without JS) ================= */
html.anim [data-reveal] { opacity: 0; transform: translateY(22px);
  transition: opacity .8s var(--ease), transform .8s var(--ease); }
html.anim [data-reveal].is-in { opacity: 1; transform: none; }
@keyframes rise { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }

/* ================= collapsing wordmark: ERFAN NAJI -> E – N ================= */
.brand-morph { position: sticky; top: 0; z-index: 45; pointer-events: none;
  height: clamp(3rem, 5.5vw, 4.6rem); padding: .95rem var(--gutter) 0; --p: 0; }
.brand-morph .morph { display: inline-flex; font-family: var(--display); font-weight: 600;
  white-space: pre; line-height: 1.1; pointer-events: auto;
  font-size: calc(clamp(1.6rem, 3vw, 2.6rem) * (1 - var(--p)) + .95rem * var(--p));
  letter-spacing: calc(.06em * (1 - var(--p)) + .22em * var(--p));
  transform: translateY(calc(var(--p) * .2rem)); }
.brand-morph a { color: inherit; text-decoration: none; display: inline-flex; }
.brand-morph .l { display: inline-block; }
.brand-morph .go { max-width: calc(1.25ch * (1 - var(--p))); overflow: clip;
  opacity: calc(1 - var(--p) * 1.35); }
.brand-morph .come { display: inline-block; max-width: calc(1.4ch * var(--p)); overflow: clip;
  opacity: calc(var(--p) * 1.4 - .25); }
html.anim body[data-intro] .brand-morph .morph { opacity: 0; transform: translateY(24px);
  animation: rise .9s var(--ease) 2.15s forwards; }
html.anim.is-loaded body[data-intro] .brand-morph .morph { animation: none; opacity: 1;
  transform: translateY(calc(var(--p) * .2rem)); }
html:not(.anim) .brand-morph { position: static; }

/* ================= nav ================= */
.site-nav { position: sticky; top: 0; z-index: 40; display: flex; align-items: center;
  justify-content: space-between; gap: 1.5rem; padding: 1.1rem var(--gutter);
  background: transparent; border-bottom: 1px solid transparent;
  transition: background-color .4s, border-color .4s;
  margin-top: calc(-1 * clamp(3rem, 5.5vw, 4.6rem)); }
.site-nav.is-scrolled { background: rgba(11, 14, 15, .82); backdrop-filter: blur(12px);
  border-bottom-color: var(--line); }
.nav-spacer { visibility: hidden; font-family: var(--display); font-weight: 600;
  letter-spacing: .22em; font-size: .95rem; }
.wordmark { font-family: var(--display); font-weight: 600; letter-spacing: .22em; font-size: .95rem; }
.site-nav ul { display: flex; gap: clamp(1.2rem, 2.5vw, 2.2rem); list-style: none;
  margin-left: auto; counter-reset: navi; }
.site-nav ul li { counter-increment: navi; display: flex; align-items: baseline; gap: .45rem; }
.site-nav ul li::before { content: "0" counter(navi); font-size: .6rem; letter-spacing: .08em;
  color: var(--mist); font-variant-numeric: tabular-nums; transition: color .25s; }
.site-nav ul li:hover::before,
.site-nav ul li:has(a[aria-current="page"])::before { color: var(--water); }
.site-nav ul a { color: var(--grey); text-decoration: none; font-size: .92rem; transition: color .25s; }
.site-nav ul a:hover, .site-nav ul a[aria-current="page"] { color: var(--porcelain); }
.nav-cta { background: var(--porcelain); color: var(--ink); font-weight: 500; font-size: .92rem;
  padding: .68rem 1.35rem; border-radius: 2px; text-decoration: none; white-space: nowrap;
  transition: transform .25s var(--ease), box-shadow .25s; }
.nav-cta:hover { transform: translateY(-1px); box-shadow: 0 6px 24px rgba(243,241,234,.12); }

/* mobile menu */
.menu-btn { display: none; color: var(--porcelain); font-size: .92rem; letter-spacing: .14em;
  text-transform: uppercase; text-decoration: none; }
.mobile-menu { position: fixed; inset: 0; z-index: 90; background: var(--ink);
  display: none; flex-direction: column; padding: 1.2rem var(--gutter) 3rem; }
.mobile-menu.is-open, .mobile-menu:target { display: flex; }
.mobile-menu .mm-top { display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 3rem; }
.mobile-menu .mm-top .wordmark { visibility: visible; }
.mobile-menu nav { display: flex; flex-direction: column; gap: 1.2rem; }
.mobile-menu nav a { font-family: var(--display); font-weight: 500; color: var(--porcelain);
  text-decoration: none; font-size: clamp(2rem, 9vw, 2.8rem); line-height: 1.15; }
.mobile-menu nav a[aria-current="page"] { color: var(--water); }
.mobile-menu .mm-cta { margin-top: auto; }

/* ================= hero (home) ================= */
.hero { position: relative; padding: clamp(2.5rem, 7vh, 5rem) var(--gutter) 0; }
.hero::before { content: ""; position: absolute; top: -20%; right: -10%; width: 60%; height: 80%;
  background: radial-gradient(ellipse at center, rgba(127,178,196,.10) 0%, transparent 65%);
  pointer-events: none; }
.hero-label { font-size: .78rem; letter-spacing: .26em;
  text-transform: uppercase; color: var(--water); font-weight: 500; margin-bottom: 2rem; }
.hero h1 { font-family: var(--display); font-weight: 500; font-size: clamp(2.2rem, 4.8vw, 4.2rem);
  line-height: 1.04; letter-spacing: -.012em; max-width: 16ch; }
.hero h1 .accent { color: var(--water); }
.hero h1 .w { display: inline-block; overflow: hidden; vertical-align: bottom; }
.hero h1 .w > span { display: inline-block; white-space: pre; }
html.anim body[data-intro] .hero h1 .w > span { transform: translateY(115%);
  animation: letter-up .8s var(--ease) forwards; animation-delay: calc(2.2s + var(--i) * .07s); }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(2rem, 5vw, 5rem); align-items: end; margin-top: clamp(2rem, 5vh, 3.2rem); }
html.anim body[data-intro] .hero-grid > * { opacity: 0; animation: rise .9s var(--ease) forwards; }
html.anim body[data-intro] .hero-grid > :first-child { animation-delay: 2.7s; }
html.anim body[data-intro] .hero-grid > :last-child { animation-delay: 2.85s; }
.hero-sub { font-size: 1.08rem; line-height: 1.65; color: var(--grey); max-width: 30rem; margin-bottom: 2rem; }
.hero-roles { margin-top: 1.8rem; font-size: .8rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--mist); }
.hero-media { position: relative; }
.hero-media img { width: 100%; height: clamp(24rem, 58vh, 34rem); object-fit: cover; object-position: 30% 30%;
  border-radius: 6px 6px 0 0; }
.hero-media::after { content: ""; position: absolute; inset: 0; border-radius: 6px 6px 0 0;
  background: linear-gradient(to top, rgba(11,14,15,.55) 0%, transparent 40%); }
.hero-media figcaption { position: absolute; bottom: 1rem; left: 1.2rem; z-index: 2; font-size: .78rem;
  letter-spacing: .14em; text-transform: uppercase; color: rgba(243,241,234,.75); }

/* ================= page hero (subpages) ================= */
.page-hero { padding: clamp(3rem, 8vh, 5.5rem) var(--gutter) clamp(2.5rem, 6vh, 4rem); }
.page-hero h1 { font-family: var(--display); font-weight: 500; font-size: clamp(2.4rem, 5.6vw, 4.8rem);
  line-height: 1.03; letter-spacing: -.014em; margin-top: 1.1rem; max-width: 16ch; }
.page-hero .lede { margin-top: 1.4rem; font-size: 1.1rem; line-height: 1.65; color: var(--grey);
  max-width: 38rem; }

/* ================= composer ================= */
.composer { border: 1px solid var(--line-strong); background: var(--ink-2); border-radius: 4px;
  padding: 1.2rem; max-width: 34rem; transition: border-color .3s, box-shadow .3s; }
.composer:focus-within { border-color: var(--water); box-shadow: 0 0 0 3px rgba(127,178,196,.15); }
.composer textarea { min-height: 4.6rem; max-height: 20rem; font-size: 1.05rem;
  field-sizing: content; overflow-y: auto; }
.composer textarea::placeholder { color: var(--mist); }
.composer-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  margin-top: .7rem; flex-wrap: wrap; }
.composer-hint { font-size: .8rem; color: var(--mist); }
.composer-send { background: var(--porcelain); color: var(--ink); font-weight: 500; font-size: .95rem;
  padding: .75rem 1.5rem; border-radius: 2px; transition: transform .25s var(--ease), box-shadow .25s; }
.composer-send:hover { transform: translateY(-1px); box-shadow: 0 6px 24px rgba(243,241,234,.14); }
.composer-status { margin-top: .6rem; font-size: .85rem; color: var(--water); min-height: 1.2em; }
.composer-note { margin-top: .7rem; font-size: .8rem; color: var(--mist); max-width: 46ch; }
.composer-note a { color: var(--water); }
.petro .composer-note { color: #AFC4C9; }

/* ================= marquee ================= */
.marquee { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  overflow: hidden; padding: 1.1rem 0; }
.marquee-track { display: flex; width: max-content; }
html.anim .marquee-track { animation: scroll-x 44s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee span { font-family: var(--display); font-weight: 500; font-size: clamp(1.6rem, 3.4vw, 2.8rem);
  letter-spacing: .06em; text-transform: uppercase; color: transparent;
  -webkit-text-stroke: 1px rgba(243,241,234,.34); white-space: pre; }
.marquee span b { font-weight: 500; color: rgba(243,241,234,.75); -webkit-text-stroke: 0; }
@keyframes scroll-x { to { transform: translateX(-50%); } }

/* ================= shared section bits ================= */
.eyebrow { font-size: .78rem; letter-spacing: .22em; text-transform: uppercase; color: var(--water);
  font-weight: 500; }
.section { padding: clamp(4rem, 10vh, 7rem) var(--gutter); }

.thesis { padding: clamp(4rem, 10vh, 7rem) var(--gutter);
  display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr); gap: clamp(2rem, 5vw, 5rem); }
.thesis h2 { font-family: var(--display); font-weight: 500; font-size: clamp(2rem, 4.2vw, 3.6rem);
  line-height: 1.08; letter-spacing: -.012em; margin-top: 1.1rem; }
.thesis p { align-self: end; color: var(--grey); font-size: 1.05rem; line-height: 1.7; max-width: 28rem; }

/* ================= practices carousel ================= */
.practices { padding: 0 0 clamp(4rem, 10vh, 7rem); }
.practices-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1.5rem;
  flex-wrap: wrap; margin-bottom: 2.4rem; padding: 0 var(--gutter); }
.practices-head h2 { font-family: var(--display); font-weight: 500; font-size: clamp(1.9rem, 3.6vw, 3rem);
  letter-spacing: -.01em; margin-top: 1rem; }
.practices-head .head-link { font-size: .95rem; color: var(--grey); text-decoration: none;
  transition: color .25s; }
.practices-head .head-link:hover { color: var(--porcelain); }
.ptrack { display: flex; gap: clamp(1.2rem, 2.5vw, 2rem); overflow-x: auto; cursor: grab;
  scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  padding: 1.5rem calc(50vw - min(17rem, 42vw)) 1.5rem; perspective: 1200px; }
.ptrack::-webkit-scrollbar { display: none; }
.ptrack.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.pcard { flex: 0 0 auto; width: min(34rem, 84vw); min-height: clamp(24rem, 52vh, 30rem);
  scroll-snap-align: center; border-radius: 1.4rem; background: var(--ink-2);
  border: 1px solid var(--line); padding: clamp(1.6rem, 3vw, 2.6rem);
  display: flex; flex-direction: column; justify-content: space-between;
  will-change: transform, opacity; }
.pcard.is-active { background: var(--petroleum); border-color: rgba(127,178,196,.4);
  box-shadow: inset 0 2px 0 var(--water), 0 24px 60px rgba(0,0,0,.45); }
.pcard-top { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.pcard-top .count { font-size: .8rem; letter-spacing: .2em; color: var(--water); font-weight: 500; }
.pcard-top .tag { font-size: .78rem; letter-spacing: .16em; text-transform: uppercase; color: var(--mist); }
.pcard.is-active .pcard-top .tag { color: #8FB0BC; }
.pcard h3 { font-family: var(--display); font-weight: 600; font-size: clamp(1.8rem, 3.4vw, 2.7rem);
  line-height: 1.05; letter-spacing: -.01em; margin-top: 1.2rem; max-width: 12ch; }
.pcard-bottom p { color: var(--grey); font-size: 1rem; line-height: 1.6; max-width: 26rem; }
.pcard.is-active .pcard-bottom p { color: #AFC4C9; }
.p-link { position: relative; margin-top: 1.4rem; font-size: .95rem; color: var(--water); text-decoration: none;
  display: inline-flex; align-items: center; gap: .45rem; width: fit-content; }
/* a resting hairline sits under every p-link; the anim layer wipes a full-
   strength line across it on hover. No arrows — the line is the affordance. */
.p-link::after { content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 1px;
  background: currentColor; opacity: .28; }
.pdots { display: flex; justify-content: center; gap: 0; margin-top: 1.4rem; }
.pdots button { width: 1.7rem; height: 1.65rem; border-radius: 999px; background: none;
  padding: 0; position: relative; }
.pdots button::before { content: ""; position: absolute; left: 0; right: 0;
  top: calc(50% - .275rem); height: .55rem; border-radius: 999px;
  background: #3A4649; transform: scaleX(.33); transition: transform .35s var(--ease), background-color .35s; }
.pdots button.is-active::before { transform: none; background: var(--water); }
.phint { text-align: center; margin-top: 1rem; font-size: .8rem; color: var(--mist);
  letter-spacing: .14em; text-transform: uppercase; }

/* ================= horizontal gallery ================= */
.gallery { padding: clamp(3rem, 8vh, 5rem) 0 clamp(4rem, 10vh, 6.5rem); }
.gallery-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1.5rem;
  padding: 0 var(--gutter); margin-bottom: 1.8rem; flex-wrap: wrap; }
.gallery-head h2 { font-family: var(--display); font-weight: 500; font-size: clamp(1.9rem, 3.6vw, 3rem);
  letter-spacing: -.01em; margin-top: 1rem; }
.gallery-nav { display: flex; gap: .5rem; }
.gallery-nav button { width: 2.9rem; height: 2.9rem; border: 1px solid var(--line-strong);
  border-radius: 50%; color: var(--porcelain); font-size: 1.1rem; display: grid; place-items: center;
  transition: background-color .3s, border-color .3s, transform .2s var(--ease); }
.gallery-nav button:hover { background: var(--porcelain); color: var(--ink); border-color: var(--porcelain); }
.gallery-nav button:active { transform: scale(.94); }
.track { display: flex; gap: clamp(1rem, 2vw, 1.6rem); overflow-x: auto; cursor: grab;
  padding: 0 var(--gutter) 1rem; scroll-snap-type: x mandatory;
  scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.track::-webkit-scrollbar { display: none; }
.track.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.track.is-dragging .card img { pointer-events: none; }
.card { flex: 0 0 auto; width: clamp(16rem, 30vw, 24rem); scroll-snap-align: start; }
.card img { width: 100%; height: clamp(20rem, 46vh, 28rem); object-fit: cover; border-radius: 6px;
  transition: transform .5s var(--ease); }
.card:hover img { transform: scale(1.02); }
.card figcaption { margin-top: .8rem; display: flex; justify-content: space-between; gap: 1rem;
  font-size: .78rem; letter-spacing: .16em; text-transform: uppercase; color: var(--grey); }
.card figcaption i { font-style: normal; color: var(--mist); }
.gallery-hint { padding: .6rem var(--gutter) 0; font-size: .8rem; color: var(--mist);
  letter-spacing: .14em; text-transform: uppercase; }

/* ================= porcelain section ================= */
.light { background: var(--porcelain); color: var(--ink); padding: clamp(4rem, 11vh, 7.5rem) var(--gutter); }
.light .eyebrow { color: var(--petroleum); }
.light h2 { font-family: var(--display); font-weight: 500; font-size: clamp(2.2rem, 4.6vw, 4rem);
  letter-spacing: -.012em; line-height: 1.05; margin-top: 1.1rem; max-width: 16ch; }
.light .lede { margin-top: 1.3rem; font-size: 1.08rem; line-height: 1.65; color: #4A5354; max-width: 38rem; }
.light .p-link { color: var(--petroleum); font-weight: 500; }
.principles { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: clamp(1.5rem, 3vw, 3rem);
  margin-top: clamp(2.5rem, 6vh, 4rem); }
.principle { border-top: 1px solid rgba(11,14,15,.25); padding-top: 1.2rem; }
.principle h3 { font-family: var(--display); font-weight: 600; font-size: 1.08rem; }
.principle p { margin-top: .55rem; font-size: .95rem; line-height: 1.6; color: #4A5354; }

/* ================= petroleum band ================= */
.petro { background: var(--petroleum); padding: clamp(3.5rem, 10vh, 6.5rem) var(--gutter);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 5rem);
  align-items: center; }
.petro .eyebrow { color: var(--water); }
.petro h2 { font-family: var(--display); font-weight: 500; font-size: clamp(1.9rem, 3.6vw, 3rem);
  line-height: 1.1; letter-spacing: -.01em; margin-top: 1rem; }
.petro p { color: #AFC4C9; line-height: 1.65; margin-top: 1rem; max-width: 30rem; }
.petro .composer { background: rgba(11,14,15,.35); border-color: rgba(127,178,196,.35); }

/* ================= person section ================= */
/* The photograph matches the height of the prose beside it rather than
   floating in the middle of it. Centred at a fixed 34rem, the image left
   ~218px of dead space above and below a 977px text column, and the two
   halves read as unrelated. Stretching costs nothing because the frame
   here is a 9:16 portrait — 0.563 against the column's 0.577, so `cover`
   trims about 25px and crops nothing that matters. Swap in a landscape
   photograph and this rule will crop it savagely; that is the constraint,
   not an accident. */
.person { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: clamp(2rem, 5vw, 5rem); padding: clamp(4rem, 11vh, 7.5rem) var(--gutter);
  align-items: stretch; }
/* The height chain has to be unbroken: the figure is stretched by the grid,
   but the img's containing block is the <picture>, so without a definite
   height on that too the 100% below resolves against auto and the frame
   collapses to its intrinsic size. */
.person figure { margin: 0; }
.person picture { display: block; height: 100%; }
/* Focal point per image, not one global default: these frames differ in how
   high the head sits (a full-length seated shot puts it near the top edge, a
   three-quarter shot much lower), and a single object-position crops through
   somebody's head the moment the photograph is swapped. Set --focal on the img. */
.person img { width: 100%; height: 100%; min-height: clamp(24rem, 60vh, 34rem);
  max-height: 64rem; object-fit: cover;
  object-position: var(--focal, 50% 25%); border-radius: 6px; }
.person h2 { font-family: var(--display); font-weight: 500; font-size: clamp(2rem, 3.8vw, 3.2rem);
  letter-spacing: -.012em; line-height: 1.08; margin-top: 1.1rem; }
.person p { color: var(--grey); line-height: 1.7; margin-top: 1.1rem; max-width: 30rem; }
.person .roles { margin-top: 1.6rem; font-size: .8rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--mist); }

/* ================= advisory: lifecycle + practice blocks ================= */
.steps { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: clamp(1.2rem, 2.5vw, 2.5rem);
  padding: 0 var(--gutter) clamp(3.5rem, 9vh, 6rem); }
.step { border-top: 1px solid var(--line-strong); padding-top: 1.1rem; }
.step .num { font-family: var(--display); font-weight: 600; color: var(--water); font-size: .95rem;
  letter-spacing: .12em; }
.step h3 { font-family: var(--display); font-weight: 500; font-size: 1.2rem; margin-top: .5rem; }
.step p { margin-top: .5rem; font-size: .92rem; line-height: 1.6; color: var(--grey); }

.block-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line);
  border: 1px solid var(--line); margin: 0 var(--gutter) clamp(4rem, 10vh, 7rem); }
.block { background: var(--ink); padding: clamp(1.8rem, 3.5vw, 2.8rem); }
.block .tag { font-size: .75rem; letter-spacing: .2em; text-transform: uppercase; color: var(--mist); }
.block h3 { font-family: var(--display); font-weight: 600; font-size: clamp(1.5rem, 2.8vw, 2.1rem);
  margin-top: .7rem; }
.block dl { margin-top: 1.3rem; display: grid; gap: 1rem; }
.block dt { font-size: .78rem; letter-spacing: .16em; text-transform: uppercase; color: var(--water); }
.block dd { margin-top: .25rem; font-size: .96rem; line-height: 1.6; color: var(--grey); }

/* ================= briefing · the three gates =================
   A spine, not three containers. The old lanes needed the word "lane" to
   explain an arrangement the layout never drew; a gate needs no noun,
   because the progression is the drawing. The count is the hero and the
   gate name is only its label.

   Nothing here animates, deliberately. The stillness of the spine is what
   will make the marks legible when they draw in on a note beneath it. */
.gates { --gate-n: clamp(120px, 18vw, 260px); --gate-gap: clamp(1rem, 5vw, 4rem);
  margin: 0 var(--gutter) clamp(3rem, 8vh, 5rem); }
/* Gates size to their own content and the connectors take the rest, so the
   arrow spans the true distance between two glyphs. Equal 1fr columns put
   the arrow flush against the following numeral instead — a single digit
   never fills a column, and the leftover space all pooled on one side. */
.gate-spine { list-style: none; margin: clamp(1.6rem, 4vh, 2.6rem) 0 0; padding: clamp(2rem, 5vh, 3rem) 0 0;
  display: grid; grid-template-columns: auto 1fr auto 1fr auto; gap: var(--gate-gap);
  align-items: start; border-top: 1px solid var(--line); }
.gate { position: relative; }
.gate-n { display: block; font-family: var(--display); font-weight: 500;
  font-size: var(--gate-n); line-height: .84; letter-spacing: -.035em;
  font-variant-numeric: proportional-nums; color: var(--porcelain); }
/* the zero is the claim the page is making, so it is the one that carries colour */
.gate--last .gate-n { color: var(--water); }
.gate-name { display: block; margin-top: .9rem; font-size: .75rem;
  letter-spacing: .24em; text-transform: uppercase; color: var(--mist); }
.gate-note { margin-top: .85rem; color: var(--grey); font-size: .9rem;
  line-height: 1.6; max-width: 14rem; text-wrap: balance; }

/* The connector is a hairline with a chevron at its head, sitting on the
   numeral's optical mid-line — .42em down a face set at .84 leading. It is
   aria-hidden in the markup, so the list still counts three items. */
.gate-link { --chev: clamp(7px, calc(var(--gate-n) * .045), 13px);
  position: relative; align-self: start; height: calc(var(--gate-n) * .84); }
.gate-link::before, .gate-link::after { content: ""; position: absolute;
  border-color: var(--line-strong); border-style: solid; }
.gate-link::before { left: 0; right: 0; top: calc(var(--gate-n) * .42);
  border-width: 1px 0 0; }
/* A chevron rotated about its own centre lands its vertex .207 × its side
   to the right of the box, so the offsets below put the point exactly on
   the end of the rule at any size rather than near it. */
.gate-link::after { width: var(--chev); height: var(--chev);
  right: calc(var(--chev) * .207); top: calc(var(--gate-n) * .42 - var(--chev) / 2);
  border-width: 1px 1px 0 0; transform: rotate(45deg); }

/* One column. Three 120px numerals plus gaps overflow a 430px screen, so the
   spine turns on its side well before that: the connector becomes a single
   rule down the left with the counts to its right, and the numeral drops to
   a phone-scale hero rather than the desktop floor. */
@media (max-width: 560px) {
  .gates { --gate-n: min(22vw, 96px); }
  .gate-spine { grid-template-columns: 1fr; gap: clamp(1.5rem, 5vh, 2.2rem);
    position: relative; padding-left: 1.4rem; }
  .gate-spine::before { content: ""; position: absolute; left: 0;
    top: calc(clamp(2rem, 5vh, 3rem) + .35rem); bottom: .35rem;
    border-left: 1px solid var(--line-strong); }
  .gate-link { display: none; }
  .gate-note { max-width: none; }
}

/* ================= empty states =================
   These replace the wireframe placeholders that used to ship on the live
   Opportunities and Briefing pages ("Property identity", "Disclaimer area").
   PRODUCT.md principle 3: where evidence doesn't exist yet, say so plainly —
   a short list stated honestly IS the scarcity argument, not a hole. */
.soon {
  margin: 0 var(--gutter) clamp(4rem, 10vh, 6rem); max-width: 56rem;
  border: 1px solid var(--line); border-radius: 16px; background: var(--panel);
  padding: clamp(1.6rem, 4vw, 2.8rem);
}
.soon h2 {
  margin-top: .8rem; font-family: var(--display); font-weight: 500;
  font-size: clamp(1.5rem, 3vw, 2.2rem); line-height: 1.2; color: var(--porcelain);
}
.soon p { margin-top: .9rem; font-size: .98rem; line-height: 1.65; color: var(--grey); max-width: 54ch; }
.soon .soon-meta {
  margin-top: 1.6rem; display: flex; align-items: center; gap: .6rem;
  font-size: .74rem; letter-spacing: .16em; text-transform: uppercase; color: var(--mist);
}
.soon .soon-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--water); flex: none; }

/* ================= advisory practice numerals =================
   Layout, not motion: must survive with JavaScript off, so it lives here
   rather than in the removable interactive layer.

   The four practices used to be illustrated with photographs of Erfan. Three
   problems with that: the parallax translated his head out of frame on 03 and
   04, the four frames were graded three different ways, and a portrait argues
   "one person" on the page whose whole argument is "four practices" — the man
   himself belongs on /about. With no fourth non-portrait photograph in the
   library, the numeral becomes the image rather than sitting on one. */
.p-n {
  margin: 0 0 clamp(.4rem, 1.4vh, .9rem);
  font-family: var(--display); font-weight: 500; line-height: .78;
  font-size: clamp(4rem, 11vw, 9rem); letter-spacing: -.04em;
  color: var(--line-strong); pointer-events: none;
}
/* Above 900px the pinned .flow-stage already carries the numeral at display
   scale, and two of them side by side is one signal too many. */
@media (min-width: 901px) { .p-n { display: none; } }

/* the lead sentence carries the weight the accent-coloured dt labels were carrying */
.block-flow .p-lead {
  margin-top: 1rem; font-family: var(--display); font-weight: 500;
  font-size: clamp(1.05rem, 1.7vw, 1.35rem); line-height: 1.4; color: var(--porcelain);
  max-width: 34ch;
}
.block-flow .p-body {
  margin-top: .8rem; font-size: .96rem; line-height: 1.65; color: var(--grey); max-width: 52ch;
}
.block-flow .p-note {
  margin-top: .7rem; font-size: .82rem; line-height: 1.55; color: var(--mist); max-width: 52ch;
}

/* ================= contact methods =================
   This is a ledger, so the values have to sit on one axis. It used to be a
   flex row with space-between, which gives every row a different middle: the
   value was centred in whatever gap that row's label and note happened to
   leave, so the left edges landed at 561 / 583 / 533 / 561 / 596 at 1440 — a
   63px wander down five rows. Explicit tracks fix it. The middle track is a
   fixed 18rem between two equal 1fr tracks, so it is centred by construction
   (value left edge measured at 576 at 1440, within 15px of where the approved
   design rested it) and identical on every row because no track is sized from
   content. */
.methods { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line);
  margin: 0 var(--gutter) clamp(4rem, 10vh, 6rem); }
.method { background: var(--ink); padding: 1.4rem clamp(1.5rem, 3vw, 2.4rem);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 18rem) minmax(0, 1fr);
  align-items: baseline; gap: clamp(1rem, 2.2vw, 2rem);
  text-decoration: none; transition: background-color .3s; }
a.method:hover { background: var(--panel); }
.method .m-label { font-size: .78rem; letter-spacing: .2em; text-transform: uppercase; color: var(--mist); }
.method .m-value { font-family: var(--display); font-weight: 500; color: var(--porcelain);
  font-size: clamp(1.05rem, 2vw, 1.35rem); }
.method .m-note { font-size: .85rem; color: var(--grey); text-align: right; }

/* Three columns need ~900px to hold the longest note on one line. Below that
   the row folds to two: the label sits above its value on the left, the note
   holds the right edge. The old flex rule wrapped instead, and wrapping is
   per-row — at 375 the Instagram row broke to three lines while its four
   neighbours broke to two, which is what made the table look loose on every
   tablet and phone. Folding is uniform by construction. */
@media (max-width: 900px) {
  .method { grid-template-columns: minmax(0, 1fr) minmax(0, 13rem);
    align-items: start; gap: .4rem clamp(1rem, 3vw, 2rem); }
  .method .m-label { grid-area: 1 / 1; }
  .method .m-value { grid-area: 2 / 1; }
  .method .m-note { grid-area: 1 / 2 / 3 / 3; align-self: end; }
}

/* One column at phone width: 13rem of note against a 375px screen leaves the
   value ~150px and it wraps. Full stack, everything on the same left edge. */
@media (max-width: 560px) {
  .method { grid-template-columns: minmax(0, 1fr); gap: .3rem; }
  .method .m-label, .method .m-value, .method .m-note { grid-area: auto; }
  .method .m-note { text-align: left; align-self: auto; }
}

/* ================= mega footer ================= */
.mega-footer { border-top: 1px solid var(--line); padding: clamp(3.5rem, 9vh, 6rem) var(--gutter) 2.5rem; }
.mega-grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr);
  gap: clamp(2.5rem, 6vw, 6rem); align-items: start; }
.mega-mark .l1 { font-family: var(--display); font-weight: 600; font-size: clamp(3rem, 7vw, 6rem);
  line-height: .95; letter-spacing: .02em; }
.mega-mark .desc { margin: 1.4rem 0 0 .2rem; max-width: 24rem; font-size: .78rem; letter-spacing: .18em;
  text-transform: uppercase; line-height: 1.9; color: var(--grey); }
.mega-mark .l2 { font-family: var(--display); font-weight: 600; font-size: clamp(3rem, 7vw, 6rem);
  line-height: .95; letter-spacing: .02em; margin-top: 1.2rem; padding-left: clamp(2rem, 8vw, 7rem);
  color: var(--water); }
/* the maker's mark: a quiet signature under the wordmark, aligned to .NAJI's
   indent so it reads as part of the identity block, not the legal row */
.maker-mark { margin: 1.5rem 0 0; padding-left: clamp(2rem, 8vw, 7rem);
  font-size: .72rem; letter-spacing: .2em; text-transform: uppercase; color: var(--mist); }
.mega-cols { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: clamp(1.5rem, 3vw, 3rem); }
.mega-col h4 { font-size: .95rem; font-weight: 600; letter-spacing: .06em; display: flex;
  flex-direction: column; gap: .4rem; width: fit-content; }
.mega-col h4 svg { width: 4.2rem; height: .5rem; overflow: visible; }
.mega-col h4 svg path { fill: none; stroke: var(--water); stroke-width: 1.6; stroke-linecap: round; }
.mega-col ul { list-style: none; margin-top: 1.1rem; display: grid; gap: .55rem; }
.mega-col a { color: var(--grey); text-decoration: none; font-size: .95rem; transition: color .25s; }
.mega-col a:hover { color: var(--porcelain); }
.mega-col li span { color: var(--grey); font-size: .95rem; }
/* contact entries carry an intent line above the value; the e-mail one is a
   copy control whose label narrates the interaction (hover: "Copy e-mail",
   after copying: "E-mail copied to clipboard"). Two-line entries need their
   own rhythm — at the single-line gap the column reads as four jammed rows. */
.mega-col ul:has(.mc-label) { gap: 1.3rem; }
.mega-col .mc-label { display: block; font-size: .7rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--mist); margin-bottom: .35rem; transition: color .25s; }
.mega-col .mc-value { color: var(--grey); font-size: .95rem; transition: color .25s; }
.mega-col a:hover .mc-value { color: var(--porcelain); }
.mega-col a.is-copied .mc-label { color: var(--water); }
.mega-base { display: flex; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap;
  margin-top: clamp(2.5rem, 6vh, 4rem); padding-top: 1.4rem; border-top: 1px solid var(--line);
  font-size: .8rem; color: var(--mist); letter-spacing: .1em; text-transform: uppercase; }
.to-top { color: var(--mist); text-decoration: none; letter-spacing: inherit; transition: color .25s; }
.to-top:hover { color: var(--porcelain); }
/* "Luma" means light, so the hover is literal: a beam sweeps through the
   letters. Gated on html.anim — reduced motion and no-JS get a plain
   colour lift, and on touch the tap simply follows the link. */
.luma-credit { color: var(--grey); text-decoration: none; font-weight: 600;
  transition: color .3s var(--ease), letter-spacing .4s var(--ease); }
.luma-credit:hover, .luma-credit:focus-visible { color: var(--porcelain); letter-spacing: .28em; }
html.anim .luma-credit {
  background: linear-gradient(105deg,
    var(--grey) 0%, var(--grey) 38%,
    var(--porcelain) 46%, var(--water) 50%, var(--porcelain) 54%,
    var(--grey) 62%, var(--grey) 100%);
  background-size: 320% 100%; background-position: 100% 0;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  transition: background-position .9s var(--ease), letter-spacing .4s var(--ease);
}
html.anim .luma-credit:hover, html.anim .luma-credit:focus-visible {
  background-position: 0% 0; color: transparent; }

/* anchor travel (back to top, the advisory rail) glides; the reduced-motion
   block below already forces this back to auto */
html { scroll-behavior: smooth; }

/* ================= responsive ================= */
@media (max-width: 900px) {
  .site-nav ul { display: none; }
  .site-nav { margin-top: 0; }
  .menu-btn { display: block; }
  .hero-grid, .thesis, .petro, .person, .mega-grid { grid-template-columns: 1fr; }
  .principles, .steps, .block-grid { grid-template-columns: 1fr; }
  /* One column: the frame leads the page, so it keeps a portrait shape
     instead of being squeezed into a 20rem letterbox. At 20rem against a
     390px column this crops a 9:16 photograph to 1.09:1 and throws away
     most of the person. 4:5 is 487px at 390 — the lead image, not the
     whole first screen. */
  .person img { height: auto; min-height: 0; max-height: none; aspect-ratio: 4 / 5; }
  /* On one column the text block comes first in source order, which buried the
     hero photograph below the whole composer — the home page opened as a wall
     of type with nothing showing who this is. The image leads instead. */
  .hero-media { order: -1; margin-bottom: clamp(1.4rem, 4vh, 2.2rem); }
  .hero-media img { height: 22rem; }
  .mega-cols { grid-template-columns: 1fr; gap: 1.8rem; }
  .card { width: 78vw; }
  .lane { grid-template-columns: 1fr; }
  .lane .state { justify-self: start; }
}

/* ================= returning visitor: intro plays once per session ================= */
html.anim.intro-seen .intro { display: none; }
html.anim.intro-seen body[data-intro] .hero-grid > *,
html.anim.intro-seen body[data-intro] .hero h1 .w > span,
html.anim.intro-seen body[data-intro] .brand-morph .morph { opacity: 1 !important;
  transform: none !important; animation: none !important; }

/* ================= reduced motion ================= */
@media (prefers-reduced-motion: reduce) {
  html.anim .intro { display: none; }
  html.anim [data-reveal], html.anim body[data-intro] .hero-grid > *,
  html.anim body[data-intro] .hero h1 .w > span,
  html.anim body[data-intro] .brand-morph .morph { opacity: 1 !important; transform: none !important;
    animation: none !important; transition: none !important; }
  html.anim .marquee-track { animation: none !important; }
  * { scroll-behavior: auto !important; }
}
