/* ===========================================================================
   Irtaza Javed — portfolio.

   THEME
   `data-theme` on <html> is always present, set by an inline script in <head>
   before first paint, and is only ever "dark" or "light". The stylesheet
   therefore matches two plain attribute selectors and nothing clever. The
   dark tokens are ALSO on a bare :root so the page still has a full palette
   if that script never runs; the media query below is the no-JS light path
   and is scoped to :root:not([data-theme]) so it can never fight the
   attribute. An earlier version inverted this — light lived inside a media
   query guarded by :not([data-theme="dark"]) — and was too subtle to trust.
   =========================================================================== */

:root {
  --bg:     #0b0c0e;
  --bg-alt: #101114;
  --raise:  #141519;
  --line:   #222429;
  --line-2: #2d3038;
  --text:   #e8e9eb;
  --muted:  #8b919b;
  --accent: #c9a96b;
  --glow:   rgba(201, 169, 107, 0.16);
  --shadow: rgba(0, 0, 0, 0.55);
  --grain:  0.022;
  --wash:   rgba(11, 12, 14, 0.45);

  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --wrap: 74rem;
  --pad:  clamp(1.25rem, 5vw, 3.5rem);
  --band: clamp(4.5rem, 11vh, 8rem);
}

[data-theme="dark"] {
  --bg: #0b0c0e; --bg-alt: #101114; --raise: #141519;
  --line: #222429; --line-2: #2d3038;
  --text: #e8e9eb; --muted: #8b919b;
  --accent: #c9a96b; --glow: rgba(201, 169, 107, 0.16);
  --shadow: rgba(0, 0, 0, 0.55); --grain: 0.022; --wash: rgba(11, 12, 14, 0.45);
}

[data-theme="light"] {
  --bg: #f7f6f3; --bg-alt: #efede8; --raise: #ffffff;
  --line: #e3e0d9; --line-2: #cfcbc1;
  --text: #14161a; --muted: #5b616b;
  --accent: #8a6a2f;                       /* the dark gold fails contrast on paper */
  --glow: rgba(138, 106, 47, 0.14);
  --shadow: rgba(30, 26, 18, 0.14);
  --grain: 0.012;
  --wash: rgba(247, 246, 243, 0.35);
}

/* No-JS only: the inline script always sets the attribute, so this can never
   compete with a real choice. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    --bg: #f7f6f3; --bg-alt: #efede8; --raise: #ffffff;
    --line: #e3e0d9; --line-2: #cfcbc1;
    --text: #14161a; --muted: #5b616b;
    --accent: #8a6a2f; --glow: rgba(138, 106, 47, 0.14);
    --shadow: rgba(30, 26, 18, 0.14); --grain: 0.012;
    --wash: rgba(247, 246, 243, 0.35);
  }
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 1rem/1.7 var(--sans);
  letter-spacing: -0.003em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
/* No transition on the page background. A cross-fade here makes the theme
   switch feel like it half-worked on a slow device, and it hides a genuine
   failure behind an animation. The swap is instant and unambiguous. */

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--pad); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 300;
  background: var(--accent); color: var(--bg); padding: 0.75rem 1rem;
}
.skip:focus { left: 0; }

.grain {
  position: fixed; inset: 0; z-index: 200; pointer-events: none;
  opacity: var(--grain);
  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.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* reading progress */
.progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 250; pointer-events: none; }
.progress i {
  display: block; height: 100%; width: 100%;
  background: var(--accent);
  transform: scaleX(0); transform-origin: 0 50%;
}

/* --------------------------------- nav --------------------------------- */

.nav {
  position: sticky; top: 0; z-index: 120;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.9rem var(--pad);
  padding-top: calc(0.9rem + env(safe-area-inset-top, 0px));
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s ease;
}
.nav.stuck { border-bottom-color: var(--line); }

.mark { font-size: 0.9375rem; font-weight: 600; letter-spacing: -0.01em; text-decoration: none; }

.nav nav { display: flex; align-items: center; gap: clamp(0.85rem, 2.4vw, 1.75rem); }
.nav nav a { font-size: 0.875rem; text-decoration: none; color: var(--muted); transition: color 0.2s; }
.nav nav a:hover, .nav nav a:focus-visible { color: var(--text); }
@media (max-width: 52rem) { .nav nav a { display: none; } }

/* theme toggle — a labelled control, not a 15px glyph nobody finds */
.theme {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.42rem 0.9rem;
  font: inherit; font-size: 0.8125rem; font-weight: 500;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--line-2); border-radius: 999px;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.theme:hover, .theme:focus-visible { border-color: var(--accent); color: var(--accent); }
.theme-dot {
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--accent);
  box-shadow: inset -3px -1px 0 0 var(--bg);   /* crescent in dark, sun in light */
  transition: box-shadow 0.3s ease, background 0.3s ease;
}
[data-theme="light"] .theme-dot { box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 25%, transparent); }

/* --------------------------------- hero --------------------------------- */

.hero {
  position: relative;
  display: flex; align-items: center;
  min-height: min(92svh, 52rem);
  padding-block: clamp(3rem, 8vh, 6rem) clamp(5rem, 11vh, 7rem);
}

.hero-grid {
  display: grid; gap: clamp(2.5rem, 6vw, 5rem);
  grid-template-columns: 1fr; align-items: center;
}
@media (min-width: 58rem) { .hero-grid { grid-template-columns: 1.35fr 0.65fr; } }

.eyebrow { margin: 0 0 1.4rem; font-size: 0.8125rem; color: var(--accent); }

h1 {
  margin: 0;
  font-size: clamp(2.75rem, 7.5vw, 5.25rem);
  font-weight: 600; line-height: 1.02; letter-spacing: -0.035em;
}

.lede {
  max-width: 36rem; margin: 1.75rem 0 0;
  font-size: clamp(1.0625rem, 1.9vw, 1.1875rem); color: var(--muted);
}

.cta { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2.25rem; }

.btn {
  display: inline-block; padding: 0.78rem 1.5rem;
  border: 1px solid var(--text); border-radius: 10px;
  background: var(--text); color: var(--bg);
  font-size: 0.9375rem; font-weight: 500; text-decoration: none;
  will-change: transform;
}
.btn.ghost { background: transparent; color: var(--text); border-color: var(--line-2); }
.btn.ghost:hover, .btn.ghost:focus-visible { border-color: var(--accent); color: var(--accent); }

.portrait { margin: 0; justify-self: center; width: min(19rem, 74vw); }
.portrait img {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover; object-position: 50% 32%;
  border-radius: 14px; border: 1px solid var(--line);
  box-shadow: 0 30px 60px -30px var(--shadow);
  filter: saturate(0.92) contrast(1.02);
}

.cue {
  position: absolute; left: 50%; bottom: 1.6rem; translate: -50% 0;
  width: 1.35rem; height: 2.25rem;
  border: 1px solid var(--line-2); border-radius: 999px;
  display: grid; place-items: start center; padding-top: 0.38rem;
}
.cue span { width: 3px; height: 0.45rem; border-radius: 2px; background: var(--accent); animation: cue 1.9s ease-in-out infinite; }
@keyframes cue { 0%,100% { transform: translateY(0); opacity: 1; } 50% { transform: translateY(0.55rem); opacity: 0.2; } }

/* -------------------------------- bands --------------------------------- */

.band { padding-block: var(--band); border-top: 1px solid var(--line); }
.band.alt { background: var(--bg-alt); }

.kicker { display: block; font-size: 0.75rem; font-weight: 500; letter-spacing: 0.06em; color: var(--accent); margin-bottom: 1rem; }

h2 {
  margin: 0 0 clamp(1.75rem, 4vw, 2.75rem);
  font-size: clamp(1.5rem, 3.1vw, 2.125rem);
  font-weight: 600; line-height: 1.22; letter-spacing: -0.024em;
  max-width: 26ch;
}
.statement { max-width: 20ch; }

.two { display: grid; gap: clamp(1rem, 3vw, 2.5rem); grid-template-columns: 1fr; }
@media (min-width: 54rem) { .two { grid-template-columns: 1fr 1fr; } }
.two p { margin: 0; color: var(--muted); }

.tags { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 2rem 0 0; padding: 0; list-style: none; }
.tags li { padding: 0.3rem 0.8rem; border: 1px solid var(--line); border-radius: 6px; font-size: 0.8125rem; color: var(--muted); }

/* ------------------------------- the slab -------------------------------- */

.slab-grid { display: grid; gap: clamp(2.5rem, 6vw, 4.5rem); grid-template-columns: 1fr; align-items: center; }
@media (min-width: 62rem) { .slab-grid { grid-template-columns: 1fr 1fr; } }
.slab-copy p { color: var(--muted); max-width: 36rem; }

.hint { display: flex; align-items: center; gap: 0.55rem; font-size: 0.875rem; color: var(--accent); }
.grip { width: 26px; height: 14px; border: 1px solid currentColor; border-radius: 3px; position: relative; flex: none; }
.grip::after {
  content: ""; position: absolute; inset: 3px 4px; border-left: 1px solid currentColor; border-right: 1px solid currentColor;
  animation: grip 2.4s ease-in-out infinite;
}
@keyframes grip { 0%,100% { transform: translateX(-2px); } 50% { transform: translateX(2px); } }

/* The box is sized from two custom properties so every translateZ can be a
   calc() off the same numbers — no JS measuring, and it stays correct at
   every viewport because the clamp lives in one place. */
.stage {
  --cw: clamp(16.5rem, 41vw, 27rem);
  --ch: calc(var(--cw) * 1.25);
  --cd: 26px;
  perspective: 1400px;
  display: grid; justify-items: center;
  /* A rotated box sweeps outside its layout box, so the caption needs more
     clearance than the untransformed slab suggests — at ~50deg the near
     corner lands on top of it. */
  gap: 2.25rem;
  padding-block: 0.5rem;
}

.slab {
  position: relative;
  width: var(--cw); height: var(--ch);
  transform-style: preserve-3d;
  transform: rotateX(var(--rx, -6deg)) rotateY(var(--ry, -22deg));
  cursor: grab;
  touch-action: pan-y;               /* vertical scrolling still works on it */
  will-change: transform;
  /* Dragging a box that contains images otherwise selects the text around it
     and lifts a ghost of the photo out of the page. Three separate browser
     behaviours have to be switched off, and none of them covers the others. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.slab img {
  -webkit-user-drag: none;
  user-select: none; -webkit-user-select: none;
  pointer-events: none;              /* the drag is handled by .slab itself */
}
.slab.dragging { cursor: grabbing; }

.slab .face, .slab .edge { position: absolute; border-radius: 10px; }

.slab .face {
  inset: 0; overflow: hidden;
  backface-visibility: hidden;
  border: 1px solid var(--line-2);
  background: var(--raise);
  box-shadow: 0 40px 70px -40px var(--shadow);
}
.slab .face img { width: 100%; height: 100%; object-fit: cover; filter: saturate(0.9) contrast(1.03); }
.slab .front { transform: translateZ(calc(var(--cd) / 2)); }
.slab .back  { transform: rotateY(180deg) translateZ(calc(var(--cd) / 2)); }


/* The four sides that make it a solid object rather than two planes. */
.slab .edge { background: linear-gradient(180deg, var(--line-2), var(--line)); }
.slab .edge.left,
.slab .edge.right  { top: 0; height: var(--ch); width: var(--cd); left: calc(50% - var(--cd) / 2); }
.slab .edge.left   { transform: rotateY(-90deg) translateZ(calc(var(--cw) / 2)); }
.slab .edge.right  { transform: rotateY(90deg)  translateZ(calc(var(--cw) / 2)); }
.slab .edge.top,
.slab .edge.bottom { left: 0; width: var(--cw); height: var(--cd); top: calc(50% - var(--cd) / 2); }
.slab .edge.top    { transform: rotateX(90deg)  translateZ(calc(var(--ch) / 2)); }
.slab .edge.bottom { transform: rotateX(-90deg) translateZ(calc(var(--ch) / 2)); }


/* -------------------------------- panels --------------------------------- */

.panels { display: grid; gap: 1.25rem; grid-template-columns: 1fr; }
@media (min-width: 56rem) { .panels { grid-template-columns: 1fr 1fr; } }

.panel {
  position: relative;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: 16px;
  transform-style: preserve-3d;
  will-change: transform;
}
.panel h3 { margin: 0 0 1.25rem; font-size: 1.0625rem; font-weight: 600; letter-spacing: -0.015em; }
.panel p { margin: 0; font-size: 0.9375rem; color: var(--muted); }

/* Pointer spotlight. The element sets --mx/--my; this paints them. */
.spot { position: relative; }
.spot::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  border-radius: inherit; pointer-events: none;
  background: radial-gradient(22rem circle at var(--mx, 50%) var(--my, 0%), var(--glow), transparent 68%);
  opacity: 0; transition: opacity 0.35s ease;
}
.spot.lit::before { opacity: 1; }
.panel > * { position: relative; z-index: 1; }

.spec { margin: 0 0 1.5rem; }
.spec > div {
  display: flex; flex-wrap: wrap; gap: 0.4rem 1.5rem; justify-content: space-between;
  padding: 0.75rem 0; border-bottom: 1px solid var(--line);
}
.spec > div:first-child { border-top: 1px solid var(--line); }
.spec dt { font-size: 0.9375rem; color: var(--muted); }
.spec dd { margin: 0; font-size: 0.9375rem; font-weight: 500; }

.mini { margin: 0; padding: 0; list-style: none; display: grid; gap: 1.1rem; }
.mini strong { display: block; font-size: 0.9375rem; font-weight: 600; }
.mini span { display: block; font-size: 0.9375rem; color: var(--muted); }

/* ------------------------------- the steps -------------------------------- */

.steps { position: relative; margin: 0; padding: 0 0 0 2.25rem; list-style: none; }

/* Two lines in the same place: a static track, and a gold fill whose scaleY
   the script drives from scroll position. One element cannot do both, because
   the fill has to be transformable independently of the track. */
.steps::before, .steps::after {
  content: ""; position: absolute; left: 0; top: 0.65rem; bottom: 0.65rem; width: 2px; border-radius: 2px;
}
.steps::before { background: var(--line-2); }
.steps::after {
  background: var(--accent);
  transform: scaleY(var(--fill, 0)); transform-origin: 50% 0;
}

.step { position: relative; padding-bottom: 2.75rem; }
.step:last-child { padding-bottom: 0; }
.step::before {
  content: ""; position: absolute; left: -2.25rem; top: 0.6rem; translate: -4px 0;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--bg-alt); border: 2px solid var(--line-2);
  transition: background 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
.step.on::before { border-color: var(--accent); background: var(--accent); }
.step.last.on::before { box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 20%, transparent); }

.step .age { display: block; margin-bottom: 0.35rem; font-size: 0.8125rem; color: var(--accent); }
.step h3 { margin: 0 0 0.4rem; font-size: 1.125rem; font-weight: 600; letter-spacing: -0.018em; }
.step p { margin: 0; max-width: 40rem; color: var(--muted); }

/* ------------------------------- contact --------------------------------- */

.big { margin: 0 0 1.75rem; font-size: clamp(1.375rem, 3.6vw, 2.25rem); letter-spacing: -0.025em; word-break: break-word; }
.big a { font-weight: 600; text-decoration: none; border-bottom: 1px solid var(--line-2); display: inline-block; will-change: transform; }
.big a:hover, .big a:focus-visible { color: var(--accent); border-color: var(--accent); }
/* No address yet. Muted so it reads as a placeholder rather than as the
   answer — full-strength text at this size looks like a finished statement. */
.big.soon { color: var(--muted); margin-bottom: 0; }


footer {
  border-top: 1px solid var(--line);
  padding-block: 2rem; padding-bottom: calc(2rem + env(safe-area-inset-bottom, 0px));
  font-size: 0.8125rem; color: var(--muted);
}
footer .wrap { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; justify-content: space-between; }
footer p { margin: 0; }
footer a { text-decoration: none; }
footer a:hover { color: var(--text); }

/* ------------------------------ animation -------------------------------- */

.up { opacity: 0; transform: translateY(14px); transition: opacity 0.7s ease, transform 0.7s ease; }
.up.in { opacity: 1; transform: none; }

/* Word-by-word headline reveal. The script wraps each word in
   <span class="w"><i>word</i></span>; the span clips, the <i> slides up. */
/* `overflow: hidden` is what makes the word wipe instead of fade — and it
   clips descenders, so "taught" loses its g. The clip box is extended below
   the baseline and the extra height pulled back off with a negative margin,
   which keeps the line spacing unchanged. */
[data-split] .w {
  display: inline-block; overflow: hidden; vertical-align: top;
  padding-bottom: 0.16em; margin-bottom: -0.16em;
}
[data-split] .w i {
  display: inline-block; font-style: inherit;
  transform: translateY(105%);
  transition: transform 0.75s cubic-bezier(0.22, 1, 0.36, 1);
}
[data-split].in .w i { transform: none; }

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .up { opacity: 1; transform: none; transition: none; }
  [data-split] .w i { transform: none; transition: none; }
  .cue span, .grip::after { animation: none; }
  .slab { transform: rotateY(-18deg) rotateX(-5deg); }
  .steps::after { transform: scaleY(1); }
  .spot::before { display: none; }
}
