/* Preview: Koto-inspired layout for the portfolio.
   One dark canvas, a single grotesk (Helvetica Neue) set light and large, small mono labels,
   two-tone headings (statement in white, context in grey), hairline rows and rounded media. */

:root {
  --bg: #070707;
  --fg: #f1f1f1;
  --grey: #8d8d8d;
  --line: rgba(255, 255, 255, 0.12);
  --card: #141414;
  --accent: #fef84b;
  --radius: 6px;
  --gutter: 24px;
  --side: 30%;
  --font: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: "DM Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --ease: cubic-bezier(.22, 1, .36, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { background: var(--bg); scroll-behavior: smooth; }
body {
  background: var(--bg); color: var(--fg);
  font-family: var(--font); font-size: 15px; line-height: 1.5;
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
img, video { display: block; max-width: 100%; }
/* Images carry width/height attributes so the browser can reserve their space before they load;
   auto here keeps the attributes from setting the drawn size, which stays with the rules below. */
img { width: auto; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

/* ---------- Shared type ---------- */
.mono { font-family: var(--mono); font-size: 11px; line-height: 1.4; letter-spacing: .06em; text-transform: uppercase; }
.grey { color: var(--grey); }
/* Two-tone heading: the name in white, the context beneath it in grey. */
.duo { font-size: clamp(26px, 2.4vw, 34px); font-weight: 300; line-height: 1.1; letter-spacing: -0.02em; }
.duo span { display: block; color: var(--grey); }
.bracket { font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--grey); transition: color .2s; }
.bracket::before { content: "[ "; } .bracket::after { content: " ]"; }
.bracket:hover { color: var(--fg); }

/* ---------- Top bar ---------- */
.topbar {
  position: fixed; inset: 0 0 auto 0; z-index: 20;
  display: flex; justify-content: space-between; align-items: flex-start;
  padding: 16px var(--gutter); pointer-events: none;
}
.topbar > * { pointer-events: auto; }
.nav {
  display: flex; align-items: center; gap: 40px;
  padding: 8px 12px; margin: -8px -12px; border-radius: var(--radius);
  transition: background .5s var(--ease), gap .5s var(--ease);
}
/* The logo art is 118×49 with texture specks above the wordmark (y 22–49). As in Framer, show
   only the wordmark: at 84px wide that is a 20px-tall clipped box with the art shifted up 15.7px. */
.nav-logo { position: relative; display: block; flex: none; width: 84px; height: 20px; overflow: hidden; }
.nav-logo img { position: absolute; top: -15.7px; left: -0.7px; width: 84px; height: auto; max-width: none; }
.nav-links { display: flex; gap: 32px; }
.nav-links a { color: var(--fg); opacity: .85; transition: opacity .2s; }
.nav-links a:hover, .nav-links a[aria-current] { opacity: 1; }
.nav-links a[aria-current]::before { content: "• "; }
.nav-crumb { display: none; color: var(--grey); }
.nav-crumb b { font-weight: 400; color: var(--fg); margin-right: 8px; }
.clock { color: var(--grey); padding-top: 3px; }
/* Once you scroll, the nav folds into a small box with the current page; hover opens it. */
.is-scrolled .nav { background: var(--card); gap: 20px; }
.is-scrolled .nav:not(:hover):not(:focus-within) .nav-links { display: none; }
.is-scrolled .nav:not(:hover):not(:focus-within) .nav-crumb { display: block; }

/* ---------- Home: above the fold ---------- */
.hero { position: relative; height: 100svh; min-height: 560px; overflow: hidden; }
.hero video { width: 100%; height: 100%; object-fit: cover; }
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(0, 0, 0, .55), rgba(0, 0, 0, 0) 45%);
}
.hero-text {
  position: absolute; left: var(--gutter); right: var(--gutter); bottom: 28px; z-index: 1;
  display: flex; justify-content: space-between; align-items: flex-end; gap: 24px;
}
/* --fs drives both languages: the same line height for each, so the lines sit in exactly the
   same place when the text swaps. */
.hero h1 { --fs: clamp(34px, 4vw, 58px); --lh: calc(var(--fs) * 1.08); font-size: var(--fs); font-weight: 300; line-height: var(--lh); letter-spacing: -0.025em; }
.hero-name { display: block; margin-bottom: 16px; color: rgba(255, 255, 255, .7); }
/* English and Nepali share one grid cell and simply cross-fade in place on hover (tap on touch
   screens). Devanagari reads larger at the same size, so it is set at 86% to match visually. */
.tagline { display: grid; align-items: end; cursor: default; outline: none; }
.tagline > span { grid-area: 1 / 1; display: block; transition: opacity .7s var(--ease); }
.tagline span span { display: block; color: rgba(255, 255, 255, .62); }
.tagline .ne {
  font-family: "Noto Sans Devanagari", "Kohinoor Devanagari", "Devanagari Sangam MN", var(--font);
  font-size: calc(var(--fs) * .86); line-height: var(--lh); letter-spacing: 0; opacity: 0; pointer-events: none;
}
.tagline.is-ne .en { opacity: 0; }
.tagline.is-ne .ne { opacity: 1; }
@media (hover: hover) {
  .tagline:hover .en, .tagline:focus-visible .en { opacity: 0; }
  .tagline:hover .ne, .tagline:focus-visible .ne { opacity: 1; }
}
.hero-text .bracket { color: rgba(255, 255, 255, .7); padding-bottom: 8px; white-space: nowrap; }

/* ---------- Home: intro statement ---------- */
/* About: held to the left half of the screen. The statement and the bio share its width;
   the bio runs in two columns, English beside Nepali. */
.intro { --measure: calc(50vw - var(--gutter)); padding: 160px var(--gutter) 200px; }
.intro p.statement { max-width: var(--measure); font-size: clamp(22px, 2.1vw, 32px); font-weight: 400; line-height: 1.18; letter-spacing: -0.02em; }
.intro p.statement span { color: var(--grey); }
.intro .more { margin-top: 28px; }
/* The bio spans the full width in four equal columns: English flows across the first two,
   Nepali across the last two. Every gap is the same, so the four columns match. */
.intro-more { --gap: 32px; margin-top: 40px; display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); color: var(--grey); }
.intro-more .col .mono { color: var(--fg); margin-bottom: 18px; }
.col-text { columns: 2; column-gap: var(--gap); font-size: 15px; line-height: 1.55; text-wrap: pretty; widows: 3; orphans: 3; }
.col-text p + p { margin-top: 14px; }
.intro-more .col[lang="ne"] .col-text { font-family: "Noto Sans Devanagari", "Kohinoor Devanagari", "Devanagari Sangam MN", var(--font); line-height: 1.75; }
.intro-more .col[lang="ne"] .mono { font-family: "Noto Sans Devanagari", var(--mono); letter-spacing: 0; text-transform: none; font-size: 12px; }
.intro-more[hidden] { display: none; }

/* ---------- Two-column frame (work, contact, case studies) ---------- */
.split { display: grid; grid-template-columns: var(--side) 1fr; gap: var(--gutter); padding: 0 var(--gutter); }
.side { position: sticky; top: 0; height: 100svh; display: flex; flex-direction: column; justify-content: space-between; padding: 120px 0 32px; }

/* ---------- Home: work ---------- */
/* Project switch, modelled on Koto's:
   - Name: a masked slide. Every name sits in one clipped cell; upcoming names wait just below
     the mask, finished ones just above. The outgoing name leaves in 133ms (accelerating) while
     the new one rises in 333ms (sharp ease-out). Scrolling back reverses the direction.
   - Description and meta: the old one fades out at once (167ms); the new one fades in only
     after the name has landed (333ms delay), so the two never overlap. */
.duo .names { display: grid; overflow: hidden; padding-bottom: .12em; margin-bottom: -.12em; }
.names-item {
  grid-area: 1 / 1; transform: translateY(calc(100% + .2em));
  transition: transform 133ms cubic-bezier(.75, 0, .85, 1);
}
.names-item.is-past { transform: translateY(calc(-100% - .2em)); }
.names-item.is-current { transform: none; transition: transform 333ms cubic-bezier(0, 0, 0, 1); }
.infos { display: grid; align-items: end; }
.info {
  grid-area: 1 / 1; opacity: 0; visibility: hidden;
  transition: opacity 167ms cubic-bezier(.4, 0, .2, 1), visibility 0s linear 167ms;
}
.info.is-current {
  opacity: 1; visibility: visible;
  transition: opacity 167ms cubic-bezier(.4, 0, .2, 1) 333ms, visibility 0s;
}
.work-desc { max-width: 340px; font-size: 13px; line-height: 1.55; color: var(--fg); opacity: .85; }
.work-meta { display: flex; align-items: center; gap: 14px; margin-top: 28px; }
.work-meta .thumb { width: 44px; height: 44px; border-radius: 4px; object-fit: cover; }
.work-meta p { font-size: 13px; line-height: 1.3; }
.work-meta .mono { margin-top: 4px; color: var(--grey); }
/* The pinned column is exactly one card tall and rests where each card rests (80px from the top),
   so the heading lines up with the card's top edge and the description with its bottom edge.
   --card-h is measured from a card in preview.js; the calc is the same height before the script
   runs (a card is 16:10 and spans 70% of the frame less the 24px gap). */
.work-side {
  align-self: start; top: 80px; margin-top: 80px; padding: 0;
  height: auto; min-height: var(--card-h, calc((70vw - 57.6px) * .625));
}
/* Lift the heading by the space type leaves above capitals, so the cap tops sit on the card's edge. */
.work-side h2 { margin-top: -0.2em; }
.work-list { display: flex; flex-direction: column; gap: 8px; padding: 80px 0 0; }
.work-card { position: relative; display: block; aspect-ratio: 16 / 10; border-radius: var(--radius); overflow: hidden; background: var(--card); }
.work-card > img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.work-card:hover > img { transform: scale(1.03); }
.work-card .overlay-logo { position: absolute; inset: 0; margin: auto; width: 36%; height: auto; }
.work-item { display: block; }
.work-item .caption { display: none; }
.work-foot { display: flex; justify-content: flex-end; padding: 24px 0 0; }

/* ---------- Contact (all pages) ---------- */
.contact { margin-top: 200px; }
.contact .side { position: static; height: auto; min-height: 520px; padding: 0 0 32px; }
.hello { display: block; width: 260px; padding: 14px; border-radius: var(--radius); background: var(--card); transition: background .3s; }
.hello:hover { background: #1c1c1c; }
.hello img { width: 96px; margin: 6px 0 40px; }
.hello .mono + .mono { color: var(--fg); margin-top: 2px; }
.rows { border-top: 1px solid var(--line); }
.row { display: grid; grid-template-columns: 1fr 1.6fr; gap: var(--gutter); padding: 22px 0 56px; border-bottom: 1px solid var(--line); font-size: 14px; }
.row > div { display: flex; flex-direction: column; gap: 2px; }
.row a { color: var(--grey); transition: color .2s; }
.row a:hover { color: var(--accent); }
.legal { display: grid; grid-template-columns: 1fr 1.6fr; gap: var(--gutter); padding: 20px 0 28px; color: var(--grey); }
.legal div { display: flex; justify-content: space-between; }

/* ---------- Case study ---------- */
/* Right padding keeps the sidebar text clear of the content column beside it. */
.case-side { padding-top: 96px; padding-right: clamp(40px, 5vw, 96px); }
/* The project's one-line idea leads; the project name sits above it as a smaller label. */
.case-head { font-weight: 300; }
.case-head span { display: block; }
.case-name { font-size: 18px; line-height: 1.3; letter-spacing: -0.01em; color: var(--grey); margin-bottom: 10px; }
.case-title { font-size: clamp(26px, 2.2vw, 34px); line-height: 1.1; letter-spacing: -0.02em; color: var(--fg); text-wrap: balance; }
.case-side .mono { margin-top: 18px; color: var(--grey); }
.case-side .mono.credit { margin-top: 6px; }
.toc { list-style: none; margin-top: 40px; display: flex; flex-direction: column; gap: 6px; font-size: 14px; }
.toc a { position: relative; color: var(--grey); transition: color .3s; }
.toc a:hover { color: var(--fg); }
.toc a[aria-current="true"] { color: var(--fg); }
.toc a[aria-current="true"]::before { content: "•"; position: absolute; left: -12px; }
.facts { display: flex; flex-direction: column; gap: 16px; max-width: var(--title-w, 100%); font-size: 13px; line-height: 1.45; }
.facts dt { color: var(--grey); margin-bottom: 4px; }
.case-main { display: flex; flex-direction: column; gap: 8px; padding: 16px 0 0; }
.media { display: block; width: 100%; border-radius: var(--radius); overflow: hidden; background: var(--card); }
.media img, .media video { width: 100%; height: 100%; object-fit: cover; }
.media.r { aspect-ratio: var(--r); }
.grid { display: grid; grid-template-columns: repeat(var(--n, 2), 1fr); gap: 8px; }
.chapter { display: grid; grid-template-columns: 1fr 1.6fr; gap: var(--gutter); padding: 28px 0 96px; border-top: 1px solid var(--line); margin-top: 88px; scroll-margin-top: 24px; }
.chapter:first-of-type { margin-top: 24px; }
.chapter h2 { color: var(--grey); }
.chapter-body { display: flex; flex-direction: column; gap: 16px; max-width: 600px; font-size: 16px; line-height: 1.5; }
.chapter-body .lead { font-size: 20px; line-height: 1.35; letter-spacing: -0.01em; }
.chapter-body h3 { margin-top: 12px; color: var(--grey); }
.chapter-body h3 + p { margin-top: -10px; }
.chapter-body .soft { color: var(--grey); }
/* A chapter that only names the images after it. */
.chapter.is-label { padding-bottom: 24px; }
/* Long chapters show their opening, then fold. The rest sits in a row of zero height that
   grows to its full height when "Read more" opens it. The negative margin cancels the
   column gap while folded, so the button sits right under the last visible paragraph. */
.fold {
  display: grid; grid-template-rows: 0fr; margin-top: -16px; opacity: 0;
  transition: grid-template-rows .8s var(--ease), opacity .5s var(--ease);
}
.fold.is-open { grid-template-rows: 1fr; opacity: 1; transition: grid-template-rows .8s var(--ease), opacity .8s var(--ease) .1s; }
.fold > div { display: flex; flex-direction: column; gap: 16px; min-height: 0; overflow: hidden; }
/* An empty first item: the column gap after it restores the space the margin took away,
   and unlike padding it folds all the way to nothing. */
.fold > div::before { content: ""; }
.read-more { align-self: flex-start; margin-top: 8px; }
/* The Lab: album cover times vinyl record makes the mark. The card is a size container, so
   everything inside scales with the column: the square, the circle, the signs and the logo all
   share one height (--h), and the logo (6:1) is six of them wide. */
.media.equation { container-type: inline-size; display: flex; align-items: center; justify-content: center; padding: 0 24px; aspect-ratio: 2.4; background: var(--bg); }
.eq { --h: clamp(28px, 6cqi, 80px); --gap: calc(var(--h) * .6); display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: center; gap: 28px var(--gap); }
/* "= logo" stays together, so on a narrow screen the result wraps as one line. */
.eq .result { display: flex; align-items: flex-start; gap: var(--gap); }
.eq figure { display: flex; flex-direction: column; align-items: center; gap: 22px; }
/* Captions take no width of their own and centre under their shape, so a label wider than
   its shape never pushes the row apart. */
.eq figcaption { display: flex; justify-content: center; width: 0; white-space: nowrap; color: var(--grey); }
.eq .op { display: flex; align-items: center; height: var(--h); font-size: calc(var(--h) * .5); font-weight: 300; line-height: 1; color: var(--fg); }
.eq .sq, .eq .ci { width: var(--h); height: var(--h); background: #fff; }
.eq .ci { border-radius: 50%; }
.media.equation img { width: calc(var(--h) * 6); height: var(--h); }
/* The Lab: the logo animation (a Lottie file drawn as SVG). The still logo stands in until
   the animation has loaded, at the same size: half the width of the 16:9 frame. */
.logo-motion { display: flex; align-items: center; justify-content: center; }
.media.logo-motion > img { width: 50%; height: auto; }
.logo-motion.is-ready > img { display: none; }
/* Nubri: competitor names switch the image beneath them. */
.switch { display: flex; flex-wrap: wrap; gap: 8px 24px; }
.switch [aria-pressed="true"] { color: var(--fg); }
.stack { display: grid; }
.stack img { grid-area: 1 / 1; opacity: 0; transition: opacity .6s var(--ease); }
.stack img.is-current { opacity: 1; }
/* Artwork on a transparent ground needs a light card. */
.media.light { background: #fff; }
.media.light img { object-fit: contain; padding: 4% 8%; }
.before-after { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.before-after figure { position: relative; display: flex; align-items: center; justify-content: center; aspect-ratio: 16 / 9; border-radius: var(--radius); background: rgb(223, 228, 232); }
.before-after figcaption { position: absolute; top: 12px; left: 14px; color: #555; }
.before-after img { width: 62%; }
.overlay { position: relative; }
.overlay .mark { position: absolute; inset: 0; margin: auto; height: auto; }
.posters .mark { bottom: auto; top: 8%; width: 30%; }

/* Next project */
.next { margin-top: 160px; }
.next-head { display: flex; justify-content: space-between; align-items: flex-end; padding: 0 var(--gutter) 24px; }
.next-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 0 var(--gutter); }
.next-cards a { display: block; }
.next-cards .media { aspect-ratio: 4 / 5; position: relative; }
.next-cards .media img:first-child { transition: transform 1.2s var(--ease); }
.next-cards a:hover .media img:first-child { transform: scale(1.03); }
.next-cards .logo { position: absolute; inset: 0; margin: auto; width: 46%; height: auto; }
.next-cards p { margin-top: 12px; font-size: 14px; }
.next-cards p span { display: block; color: var(--grey); }

/* ---------- Motion (main.js tags elements; nothing hides without JS) ---------- */
.reveal, .reveal-media { opacity: 0; transition: opacity 1.1s var(--ease), transform 1.4s var(--ease), clip-path 1.4s var(--ease); transition-delay: var(--d, 0s); }
.reveal { transform: translateY(24px); }
.reveal-media { transform: scale(1.04); clip-path: inset(4% 3% round var(--radius)); }
.reveal.is-in { opacity: var(--out, 1); transform: translateY(calc((1 - var(--out, 1)) * -12px)); }
.reveal-media.is-in { opacity: var(--out, 1); transform: none; clip-path: inset(0 round var(--radius)); }
.is-in.is-leaving { transition: opacity .2s linear, transform .2s linear; transition-delay: 0s; }
@keyframes rise { from { opacity: 0; transform: translateY(28px); } }
.js-motion .hero .en, .js-motion .hero .en span { animation: rise 1.4s var(--ease) both; }
.js-motion .hero .en span { animation-delay: .25s; }
.js-motion .hero-text .bracket { animation: rise 1.2s var(--ease) .5s both; }
@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal-media { opacity: 1 !important; transform: none !important; clip-path: none !important; transition: none; }
  .js-motion .hero .en, .js-motion .hero .en span, .js-motion .hero-text .bracket { animation: none; }
  .tagline > span, .fold, .fold.is-open, .stack img { transition: none; }
}

/* ---------- Smaller screens: one column, nothing pinned ---------- */
@media (max-width: 899.98px) {
  :root { --gutter: 16px; }
  .clock, .nav-links a:not([href*="contact"]) { display: none; }
  .split { grid-template-columns: 1fr; }
  .side, .contact .side { position: static; height: auto; min-height: 0; padding: 0 0 24px; }
  .hero-text { flex-direction: column; align-items: flex-start; }
  .intro { --measure: 100%; padding: 96px var(--gutter) 120px; }
  .intro-more { grid-template-columns: 1fr; gap: 40px; }
  .col-text { columns: 1; }
  .work-side .names, .work-side .infos { display: none; }
  .work-side { margin-top: 0; min-height: 0; }
  .work-list { padding-top: 0; gap: 32px; }
  .work-card { aspect-ratio: 4 / 3; }
  .work-item .caption { display: block; margin-top: 10px; font-size: 14px; }
  .work-item .caption span { display: block; color: var(--grey); }
  .contact { margin-top: 120px; }
  .hello { margin-top: 24px; }
  .row, .legal, .chapter { grid-template-columns: 1fr; gap: 10px; }
  .row { padding-bottom: 28px; }
  .legal div { flex-wrap: wrap; gap: 12px; }
  .case-side { padding-top: 88px; padding-right: 0; }
  .toc, .facts { display: none; }
  .chapter { margin-top: 48px; padding-bottom: 40px; }
  .chapter.is-label { padding-bottom: 8px; }
  .media.equation { aspect-ratio: auto; padding: 72px 16px; }
  .eq { --h: clamp(28px, 11cqi, 56px); }
  .eq figcaption { width: auto; }
  /* A taller frame crops the animation's empty sides, so the logo reads larger. */
  .media.logo-motion { aspect-ratio: 4 / 3; }
  .media.logo-motion > img { width: 67%; }
  .grid { grid-template-columns: 1fr; }
  .next-cards { grid-template-columns: 1fr 1fr; }
}
