/* ---------------------------------------------------------------
   nayeemhassan.com — homepage styles
   Layout: artworld-style. A cluster of serif discipline words,
   anchored by a huge lowercase wordmark at the bottom.
   Colour: set by JS from a rotating set of palettes (see main.js).
   --------------------------------------------------------------- */

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

:root {
  /* Fonts (loaded in each page's <head> from Google Fonts) */
  --font-serif: "Fraunces", Georgia, "Times New Roman", serif;   /* the words */
  --font-sans: "Inter", -apple-system, "Helvetica Neue", Arial, sans-serif;

  /* Palette — these three are overwritten by JS on load.
     Values here are a sensible default in case JS doesn't run. */
  --bg: #f7f2e0;         /* background */
  --ink: #1a1a1a;        /* primary: wordmark + words */
  --accent: #d95122;     /* secondary: hover / rollover */

  --space: clamp(1rem, 3vw, 2rem);
}

body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Calm fade when the palette changes */
  transition: background-color 0.6s ease, color 0.6s ease;
  overflow-x: hidden;
}

/* The landing screen is fixed to the viewport — it stays perfectly
   still while the letters morph, then the content scrolls up over
   it. GSAP fades it out as the morph completes. */
.hero {
  position: fixed;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
}

/* Invisible scroll runway; its height (set by JS) is the morph
   distance plus one screen, so the letters finish docking a full
   screen before the content scrolls into view. */
.stage { width: 100%; }

/* Empty runway after Contact. Scrolling down through it rebuilds the
   landing screen (see the return loop in main.js), then the page
   wraps to the top. Height is set by JS. */
.return-zone { width: 100%; }

/* The plywood-grain texture. A fixed layer behind everything; JS
   draws the image, sets the height (tall enough to cover the whole
   parallax travel) and slides it at a fraction of the scroll speed.
   See the terrain section in main.js. */
.terrain {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;                  /* real height set by JS */
  z-index: 0;
  pointer-events: none;
  background-repeat: repeat-x;
  will-change: transform;
}

/* Everything below the landing screen. Higher than the hero, and
   TRANSPARENT so the contour texture shows behind the cards — the
   landing screen's words have already faded out by the time this
   scrolls over them, so nothing bleeds through. */
.content {
  position: relative;
  z-index: 2;
}

a { color: inherit; text-decoration: none; }

/* --- Top bar --- */
.site-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: var(--space);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
}

.site-header nav a { margin-left: 1.25rem; }
.site-header a { transition: color 0.25s ease; }
.site-header a:hover { color: var(--accent); }

/* --- Word cluster (the middle) --- */
.cluster {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space) calc(var(--space) * 1.5);
}

.cluster-words {
  max-width: 60rem;
  text-align: center;
  font-family: var(--font-serif);
  font-optical-sizing: auto;
  font-weight: 380;
  font-size: clamp(1.4rem, 3.2vw, 2.6rem);
  line-height: 1.35;
}

.cluster-words .word {
  white-space: nowrap;
  margin: 0 0.35em;
  transition: color 0.25s ease;
}
.cluster-words .word:hover { color: var(--accent); }
.cluster-words .i { font-style: italic; }

/* discipline tags, e.g. (A) (C, P) */
.cluster-words sup {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 0.42em;
  vertical-align: super;
  letter-spacing: 0.04em;
  opacity: 0.55;
  margin-left: 0.15em;
}

/* --- Bottom of the hero --- */
.footer {
  padding: 0 var(--space) calc(var(--space) * 0.75);
}

/* Empty space at the bottom of the hero that the name unit sits
   over. Its height is set by JS to match the two-line name. */
.mast-spacer { width: 100%; }

/* The name unit: legend + name as ONE fixed element. It starts at
   the bottom of the landing screen, morphs on scroll, docks at the
   top, and stays locked there. The animation uses transforms and
   opacity only — no layout work — so it stays smooth. */
.mast-unit {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 10;
  visibility: hidden;          /* JS shows it once measured */
  /* No background — the cards scroll past, visible behind the name */
  background: transparent;
  pointer-events: none;        /* don't block clicks on cards behind */
  padding-top: calc(var(--space) * 0.5);
  padding-bottom: calc(var(--space) * 0.35);
  will-change: transform;
}

/* ...but the name and legend themselves stay clickable */
.mast-unit a,
.mast-unit button { pointer-events: auto; }

.mast-name {
  position: relative;          /* anchor for the absolutely-placed letters */
  display: block;
  margin: 0 var(--space);      /* same side gutters as the content */
  font-family: var(--font-sans);
  font-weight: 900;
  letter-spacing: -0.03em;
  line-height: 0.82;
  white-space: nowrap;
  color: var(--ink);
  cursor: pointer;
  user-select: none;
}

.mast-row { display: inline; }

/* Every letter is its own element. JS positions each one absolutely
   at a measured, KERNED coordinate (so spacing matches real type),
   then animates only its transform. */
.mast-letter {
  display: inline-block;
  transform-origin: 0 0;       /* scale/translate from the top-left */
  will-change: transform, opacity;
}
.mast-name.split .mast-letter { position: absolute; top: 0; left: 0; }

/* Hidden element used only to measure natural (kerned) letter runs */
.mast-measure {
  position: absolute;
  visibility: hidden;
  top: 0;
  left: 0;
  white-space: nowrap;
}

/* --- Work section --- */
.work {
  /* Top padding = the docked name unit's height (JS sets --mast-h),
     so the grid starts below the locked name */
  padding: calc(var(--mast-h, 30vh) + var(--space) * 0.5) var(--space) calc(var(--space) * 2);
}

/* The legend inside the name unit — also the discipline filter.
   Explicit stacking so it always wins clicks over the huge name
   text below it, even while that text is mid-transform. */
.work-legend {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.35rem 1.2rem;
  padding: 0 var(--space) calc(var(--space) * 0.4);
}

.work-legend button {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: inherit;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  opacity: 0.6;
  transition: color 0.25s ease, opacity 0.25s ease;
}
.work-legend button:hover { color: var(--accent); opacity: 1; }
.work-legend button.active { color: var(--accent); opacity: 1; }

/* --- Card grid --- */
.grid {
  display: grid;
  /* auto-fit: however many cards there are, they share the full
     width of the window (each at least 240px wide) */
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: calc(var(--space) * 1.25) var(--space);
  margin-top: var(--space);
}

.card { cursor: pointer; }

.card .thumb {
  aspect-ratio: 4 / 5;              /* every card crops to this shape */
  overflow: hidden;
  background: rgba(0, 0, 0, 0.06);
}

.card img {
  width: 100%;
  height: 100%;
  object-fit: cover;                /* crop, don't squash */
  display: block;
  transition: transform 0.4s ease;
}
.card:hover img { transform: scale(1.03); }

.card h3 {
  font-family: var(--font-serif);
  font-optical-sizing: auto;
  font-weight: 380;
  font-size: 1.1rem;
  margin-top: 0.6rem;
  line-height: 1.2;
}

.card .meta {
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  opacity: 0.6;
  margin-top: 0.2rem;
}

.grid-empty {
  grid-column: 1 / -1;
  font-family: var(--font-serif);
  font-size: 1.2rem;
  opacity: 0.6;
  padding: calc(var(--space) * 2) 0;
}

/* --- Project detail (expands in place when a card is clicked) ---
   A fixed panel that sits BELOW the locked name unit and fills the
   rest of the screen. It starts hidden; JS fades/morphs it in while
   the cards clear away, so it reads as the cards making room for it
   rather than a window opening on top. */
.detail {
  position: fixed;
  top: var(--mast-h, 4rem);      /* start just under the docked name */
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 8;                    /* under the name unit (10), over content */
  /* Transparent, so the wood grain shows through behind the project —
     the cleared-away cards are faded out, so nothing else shows. */
  background: transparent;
  overflow-y: auto;             /* the panel scrolls on its own */
  -webkit-overflow-scrolling: touch;
  visibility: hidden;           /* shown by JS (or the .open class) */
  opacity: 0;
  pointer-events: none;
}
/* The class alone shows the panel (so the site works even without
   the animation libraries); JS animates opacity on top of this. */
.detail.open { pointer-events: auto; visibility: visible; opacity: 1; }

/* Everything is left-justified against the same gutter as the rest
   of the site — no centred column. */
.detail-inner {
  padding: calc(var(--space) * 1.25) var(--space) calc(var(--space) * 3);
}

/* Title on the left, close button on the right of the same row */
.detail-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space);
  margin-bottom: calc(var(--space) * 1.1);
}

.detail-close {
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 0.25rem 0;                /* a little extra tap area */
  cursor: pointer;
  color: inherit;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  transition: color 0.25s ease;
}
.detail-close:hover { color: var(--accent); }

.detail-title {
  font-family: var(--font-serif);
  font-optical-sizing: auto;
  font-weight: 380;
  font-size: clamp(2rem, 6vw, 3.5rem);
  line-height: 1.02;
}

/* Narrow screens: image first, text below (one column). The wide
   side-by-side layout is in the media query further down. */
.detail-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: calc(var(--space) * 1.5);
  align-items: start;
}

.detail-hero { width: 100%; }
.detail-hero img {
  width: 100%;
  max-height: 72vh;
  object-fit: contain;
  object-position: left top;         /* image hugs the left, not centred */
  display: block;
}

/* Wide windows: NO scrolling inside the project. The panel becomes a
   fixed frame; the image scales to whatever height is left after the
   title row, and the text is fitted by JS (see fitDetailText).

   The image's WIDTH comes from its own shape (height 100%, width
   auto): a portrait picture stays narrow, a landscape one runs wide.
   The text column starts one gutter after the image — the same
   spacing as the image from the screen edge — and fills the rest. */
@media (min-width: 761px) {
  .detail { overflow: hidden; }
  .detail-inner {
    height: 100%;
    display: flex;
    flex-direction: column;
    padding-bottom: var(--space);
  }
  .detail-layout {
    display: flex;
    gap: var(--space);               /* image↔text = image↔screen edge */
    flex: 1;
    min-height: 0;                   /* lets the image row actually shrink */
    align-items: stretch;
  }
  /* The wrapper leaves the layout (display: contents) so the IMAGE
     itself is the flex item — otherwise the wrapper is sized from
     the image file's natural width and leaves dead space beside the
     rendered image, pushing the text too far right. */
  .detail-hero { display: contents; }
  .detail-hero img {
    flex: 0 0 auto;
    height: 100%;
    width: auto;                     /* width follows the image's shape */
    max-width: 68%;                  /* even a panorama leaves text room */
    max-height: none;
  }
  /* (.detail-inner prefix: outranks the narrow 34rem cap below) */
  .detail-inner .detail-body {
    flex: 1;
    min-width: 0;
    max-width: none;                 /* text widens to fill the space */
    overflow: hidden;
  }
}

/* The year, at the top of the text column.
   NOTE: the text column's sizes are in em (not rem) on purpose —
   JS shrinks the column's font-size until everything fits in the
   window, and em sizes scale along with it. */
.detail-byline {
  font-size: 0.72em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.55;
  margin-bottom: 0.9rem;
}

.detail-body { max-width: 34rem; }

.detail-desc { font-size: 0.98em; line-height: 1.7; }

.detail-meta {
  font-size: 0.75em;
  letter-spacing: 0.03em;
  opacity: 0.6;
  margin-top: 0.9rem;
}

/* The other photos: a row of clickable thumbnails under the text */
.detail-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: calc(var(--space) * 1.25);
}
.detail-thumb {
  width: 72px;
  height: 90px;
  padding: 0;
  border: none;
  cursor: pointer;
  background: rgba(0, 0, 0, 0.06);
  opacity: 0.55;
  transition: opacity 0.25s ease;
}
.detail-thumb:hover { opacity: 0.85; }
/* The selected photo reads at full strength; the rest sit back.
   No frame — the opacity difference is the marker. */
.detail-thumb.active { opacity: 1; }
.detail-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* --- Info & Contact: sections at the bottom of the same page --- */
.page-section {
  padding: calc(var(--space) * 2.5) var(--space);
  /* When jumped to via #anchor, land below the locked name unit */
  scroll-margin-top: calc(var(--mast-h, 4rem) + 1rem);
}

.page-section h2 {
  font-family: var(--font-serif);
  font-optical-sizing: auto;
  font-weight: 380;
  font-size: clamp(2rem, 5vw, 3.25rem);
  line-height: 1.05;
  margin-bottom: 1.25rem;
}

.page-section .bio {
  font-family: var(--font-serif);
  font-optical-sizing: auto;
  font-weight: 380;
  font-size: clamp(1.2rem, 2.4vw, 1.7rem);
  line-height: 1.4;
  max-width: 34rem;
  margin-bottom: calc(var(--space) * 1.5);
}

.info-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: calc(var(--space) * 1.5) var(--space);
}

.info-cols h3 {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.6;
  margin-bottom: 0.75rem;
}

.info-cols ul { list-style: none; }

.info-cols li {
  font-size: 0.9rem;
  line-height: 1.45;
  margin-bottom: 0.6rem;
}

#contact p { margin-bottom: 0.5rem; }

#contact a { border-bottom: 1px solid currentColor; }
#contact a:hover { color: var(--accent); }

.contact-links { margin-top: 1.25rem; }
.contact-links a { margin-right: 1.25rem; }

/* --- Footer --- */
.site-footer {
  padding: calc(var(--space) * 2) var(--space) var(--space);
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  opacity: 0.55;
}
