/* All geometry is expressed in units of --u: 1u = 1px of a 1108 x 658 reference viewport. */
:root {
  --u: min(calc(100vw / 1108), calc(100vh / 658));
  --bg: #ffffff;
  --ink: #000000;
  --text: #111111;
  --gray: #999999;
  --mid: #555555;
  --ease: cubic-bezier(.22, .61, .36, 1);
  --font: "Didact Gothic", "Century Gothic", "CenturyGothic", "URW Gothic", "Futura", sans-serif;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { background: var(--bg); scrollbar-width: none; }
html::-webkit-scrollbar, .detail-scroll::-webkit-scrollbar { display: none; }
body { font-family: var(--font); color: var(--ink); background: var(--bg); -webkit-font-smoothing: antialiased; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; cursor: pointer; }
ul { list-style: none; }
img { display: block; }
body.on-landing { overflow: hidden; }

.stage { position: relative; width: calc(1108 * var(--u)); height: calc(658 * var(--u)); }

/* ---------- Landing ---------- */
.landing {
  position: fixed; inset: 0; z-index: 50; background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  transition: opacity .45s var(--ease), visibility .45s;
}
body:not(.on-landing) .landing { opacity: 0; visibility: hidden; pointer-events: none; }
.brand {
  position: absolute; left: 50%; top: calc(270 * var(--u)); transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center;
  color: var(--ink);
  transition: transform .5s var(--ease), color .5s var(--ease);
}
.brand-name { font-size: calc(72 * var(--u)); line-height: 1; letter-spacing: .09em; margin-right: -.09em; white-space: nowrap; }
.brand-role { font-size: calc(17 * var(--u)); line-height: 1; margin-top: calc(23 * var(--u)); letter-spacing: 0; }
.landing.open .brand { transform: translate(-50%, calc(-49 * var(--u))); color: #989898; }

.menu { position: absolute; left: 0; right: 0; top: calc(354 * var(--u)); display: flex; flex-direction: column; align-items: center; }
.menu a {
  font-size: calc(26 * var(--u)); line-height: calc(37 * var(--u));
  opacity: 0; transform: translateY(calc(14 * var(--u))); pointer-events: none;
  transition: opacity .35s var(--ease), transform .45s var(--ease), color .25s;
}
.landing.open .menu a { opacity: 1; transform: none; pointer-events: auto; }
.landing.open .menu a:nth-child(1) { transition-delay: .06s, .06s, 0s; }
.landing.open .menu a:nth-child(2) { transition-delay: .12s, .12s, 0s; }
.landing.open .menu a:nth-child(3) { transition-delay: .18s, .18s, 0s; }
.landing.open .menu a:nth-child(4) { transition-delay: .24s, .24s, 0s; }
.landing.open .menu a:hover { color: var(--gray); transition-delay: 0s; }

/* ---------- Header ---------- */
.header { position: fixed; top: calc(20 * var(--u)); left: calc(34 * var(--u)); z-index: 40; display: flex; flex-direction: column; gap: calc(12 * var(--u)); }
.header-brand { font-size: calc(13.5 * var(--u)); line-height: 1; letter-spacing: .04em; }
.burger { width: calc(26 * var(--u)); height: calc(12 * var(--u)); position: relative; }
.burger i { position: absolute; left: 0; right: 0; height: 1px; background: var(--ink); }
.burger i:nth-child(1) { top: 0; } .burger i:nth-child(2) { top: 50%; } .burger i:nth-child(3) { bottom: 0; }
.header-brand:hover, .burger:hover { opacity: .5; }

/* ---------- Pages ---------- */
.page { height: 100vh; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.titles { position: fixed; inset: 0; z-index: 30; pointer-events: none; display: flex; align-items: center; justify-content: center; }
.ptitle {
  position: absolute; left: 50%; top: 0;
  font-size: calc(48 * var(--u)); line-height: 1; white-space: nowrap;
  transform-origin: 50% 50%; will-change: transform, opacity;
  pointer-events: auto; color: var(--ink);
}

/* About */
.about-photo { position: absolute; left: calc(156 * var(--u)); top: calc(166 * var(--u)); width: calc(234 * var(--u)); height: calc(294 * var(--u)); object-fit: cover; }
.about-name { position: absolute; left: calc(156 * var(--u)); top: calc(472 * var(--u)); font-size: calc(36 * var(--u)); line-height: 1.2; letter-spacing: .01em; }
/* Right-hand column spans exactly the portrait's height, so it can never run past its bottom edge.
   space-between spreads the leftover room between sections instead of leaving it dead at the bottom. */
.about-col {
  position: absolute; left: calc(418 * var(--u)); top: calc(166 * var(--u));
  width: calc(560 * var(--u)); height: calc(294 * var(--u));
  display: flex; flex-direction: column; justify-content: space-between; gap: calc(16 * var(--u));
}
.about-block { width: calc(var(--w, 560) * var(--u)); }
.about-block h3 { font-weight: 400; font-size: calc(18 * var(--u)); line-height: 1; margin-bottom: calc(11 * var(--u)); letter-spacing: .005em; }
.about-block p { font-size: calc(12 * var(--u)); line-height: calc(16.5 * var(--u)); color: var(--text); }
.about-block p span { display: block; }
.about-block p span + span { margin-top: calc(6 * var(--u)); }
/* Hierarchy without bold: Didact Gothic has only one weight, so emphasis comes from size and colour. */
.about-edu p span:nth-child(1) { font-size: calc(13.5 * var(--u)); line-height: calc(18 * var(--u)); color: var(--ink); }
.about-edu p span:nth-child(2) { color: var(--ink); }
.about-edu p span:nth-child(n+3) { color: var(--mid); }
.about-block p.about-bio { font-size: calc(12.5 * var(--u)); line-height: calc(18 * var(--u)); }
/* Top-right of the body text: right edge flush with the text column (978u), top flush with EDUCATION. */
/* z-index: .about-col is a later sibling starting at the same top, so without this the EDUCATION block paints over the icons and swallows the clicks. */
.about-social { position: absolute; right: calc(130 * var(--u)); top: calc(166 * var(--u)); z-index: 1; display: flex; gap: calc(13 * var(--u)); }
.about-social a { width: calc(38 * var(--u)); height: calc(38 * var(--u)); border: 1px solid #cdcdcd; border-radius: calc(9 * var(--u)); display: flex; align-items: center; justify-content: center; color: var(--mid); transition: color .3s, border-color .3s; }
.about-social a:hover { color: var(--ink); border-color: var(--ink); }
.about-social svg { width: calc(18.5 * var(--u)); height: calc(18.5 * var(--u)); fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* Experiences timeline */
.tl { position: absolute; left: calc(214 * var(--u)); top: calc(167 * var(--u)); width: calc(680 * var(--u)); }
.tl-row { position: relative; display: grid; grid-template-columns: 1fr 1fr; column-gap: calc(54 * var(--u)); padding-bottom: calc(30 * var(--u)); }
.tl-row::after { content: ""; position: absolute; left: 50%; top: calc(8.5 * var(--u)); bottom: 0; width: 1px; background: #d5d5d5; }
.tl-row:last-child::after { content: none; }
.tl-row::before { content: ""; position: absolute; left: 50%; top: calc(5 * var(--u)); width: calc(7 * var(--u)); height: calc(7 * var(--u)); margin-left: calc(-3.5 * var(--u)); border-radius: 50%; background: var(--ink); }
.tl-body { text-align: right; }
.tl-body h4 { font-weight: 400; font-size: calc(15 * var(--u)); line-height: 1.25; letter-spacing: .005em; }
.tl-body p { font-size: calc(10.5 * var(--u)); line-height: calc(13.4 * var(--u)); color: var(--text); }
.tl-body p + p { color: var(--gray); }
.tl-date { text-align: left; padding-top: calc(2 * var(--u)); font-size: calc(11 * var(--u)); line-height: 1.2; color: var(--mid); }
.tl-row:nth-child(even) .tl-body { order: 2; text-align: left; }
.tl-row:nth-child(even) .tl-date { order: 1; text-align: right; }

/* Project list */
.cards {
  position: absolute; left: 0; right: 0; top: calc(250 * var(--u));
  display: flex; gap: calc(40 * var(--u));
  overflow-x: auto; scrollbar-width: none; cursor: grab;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 calc(70 * var(--u)), #000 calc(100% - 70 * var(--u)), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 calc(70 * var(--u)), #000 calc(100% - 70 * var(--u)), transparent 100%);
}
.cards::-webkit-scrollbar { display: none; }
/* main.js adds .is-centered while there are fewer than 5 projects; "safe" keeps card 01 reachable if a row ever does overflow. */
.cards.is-centered { justify-content: safe center; }
.cards.dragging { cursor: grabbing; }
/* min-width: 0 stops a long title (the label is nowrap) from widening a card and changing when the row starts to scroll. */
.card { flex: 0 0 calc(190 * var(--u)); min-width: 0; user-select: none; }
.card .img { width: calc(190 * var(--u)); height: calc(190 * var(--u)); overflow: hidden; }
.card img { width: 100%; height: 100%; object-fit: cover; transition: opacity .4s var(--ease), transform .8s var(--ease); pointer-events: none; }
.card:hover img { opacity: .78; }
.card span { display: block; margin-top: calc(9 * var(--u)); font-size: calc(10.5 * var(--u)); color: var(--mid); white-space: nowrap; }
/* Equal spacers instead of padding: scroll containers honour these on both ends, and they keep the centring symmetric. */
.cards::before, .cards::after { content: ""; flex: 0 0 calc(58 * var(--u)); }

/* ---------- Project detail ---------- */
.detail { position: fixed; inset: 0; z-index: 35; background: var(--bg); opacity: 0; visibility: hidden; transition: opacity .45s var(--ease), visibility .45s; }
.detail.show { opacity: 1; visibility: visible; }
/* align-items: flex-start keeps the stage content-sized; stretch would freeze it at viewport
   height and its bottom padding would add no scrollable room. */
.detail-scroll { position: absolute; inset: 0; overflow-y: auto; display: flex; justify-content: center; align-items: flex-start; }
.detail-stage { height: auto; min-height: 100vh; padding-bottom: calc(80 * var(--u)); transition: opacity .35s var(--ease), transform .45s var(--ease); }
.detail-stage.swap { opacity: 0; transform: translateX(calc(var(--dir, 1) * 24 * var(--u))); }
.all-projects { position: fixed; right: calc(43 * var(--u)); bottom: calc(24 * var(--u)); z-index: 2; font-size: calc(12.5 * var(--u)); color: var(--mid); }
.all-projects:hover { color: var(--ink); }
.arrow { position: fixed; top: 50%; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: calc(12 * var(--u)); color: #333; transform: translateY(calc(-25 * var(--u))); }
.arrow svg { width: calc(19 * var(--u)); height: calc(33 * var(--u)); }
.arrow span { font-size: calc(12 * var(--u)); color: var(--mid); }
.arrow-l { left: calc(38 * var(--u)); } .arrow-r { right: calc(38 * var(--u)); }
.arrow:hover { color: var(--gray); }
.d-num { position: absolute; left: calc(195 * var(--u)); top: calc(92 * var(--u)); font-size: calc(13 * var(--u)); color: var(--mid); }
.d-title { position: absolute; left: calc(193 * var(--u)); top: calc(101 * var(--u)); font-weight: 400; font-size: calc(52 * var(--u)); line-height: 1.1; white-space: nowrap; }
.d-sub { position: absolute; left: calc(195 * var(--u)); top: calc(167 * var(--u)); font-size: calc(19 * var(--u)); color: #666; }
.d-meta { position: absolute; left: calc(195 * var(--u)); top: calc(221 * var(--u)); width: calc(150 * var(--u)); font-size: calc(12.5 * var(--u)); line-height: calc(20.6 * var(--u)); color: var(--mid); }
.d-meta li:last-child { line-height: calc(13.5 * var(--u)); margin-top: calc(3 * var(--u)); }
.d-desc { position: absolute; left: calc(393 * var(--u)); top: calc(225 * var(--u)); width: calc(525 * var(--u)); font-size: calc(14.5 * var(--u)); line-height: calc(19.2 * var(--u)); color: var(--text); }
/* Media block sits below the description; its top margin is set in JS from the description's height. */
.d-media { position: relative; margin: 0 calc(195 * var(--u)); display: grid; grid-template-columns: repeat(3, 1fr); gap: calc(60 * var(--u)); align-items: start; }
.d-media img { width: 100%; height: auto; }
.d-media.is-video { display: block; }
.d-media video { width: 100%; height: auto; display: block; background: #f4f4f4; }
