/* =============================================================
   Shien Huang — shared styles
   Photos sit in a grid whose column count follows the available
   width. --col-min below decides when a new column appears.
   ============================================================= */
:root {
  --bg: #FFFFFF;
  --ink: #111111;
  --ink-soft: #777777;
  --ink-faint: #B5B5B5;
  --line: #E4E4E4;
  --accent: #1F2A6B;
  --foot: #111111;
  --foot-ink: #DADADA;
  --font-ui: 'Jost', 'Futura', 'Helvetica Neue', Arial, sans-serif;
  --font-serif: 'Cormorant Garamond', Georgia, serif;

  /* grid: space between photos, and the width below which a column is dropped */
  --gutter: 25px;
  --col-min: 320px;
}
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --bg: #FFFFFF; } }
:root[data-theme="dark"] { --bg: #FFFFFF; }

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0; padding-top: 6rem;
  background: var(--bg); color: var(--ink);
  font-family: var(--font-ui); font-weight: 300; font-size: .95rem; line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* keeps the footer at the bottom on short pages, like About */
  min-height: 100vh; display: flex; flex-direction: column;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
a:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }

/* ---- fixed name header ---- */
.name-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 10;
  padding: 1.5rem clamp(1.5rem, 8vw, 9rem);
  background: var(--bg); border-bottom: 1px solid var(--line);
}
.name-header a {
  font-family: var(--font-ui); font-weight: 200;
  font-size: clamp(1.5rem, 3.2vw, 2.2rem);
  letter-spacing: .08em; text-transform: uppercase; line-height: 1;
}

/* ---- fixed sidebar nav ---- */
.side { position: fixed; top: 6rem; left: clamp(1.5rem, 8vw, 9rem); width: 120px; z-index: 5; }
.side nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.side nav a { font-size: .66rem; letter-spacing: .16em; text-transform: uppercase; }
.side nav a.current { font-weight: 700; color: #111; }
.side nav a:hover { color: var(--ink-soft); }
.side .social { margin-top: 2.4rem; }
.side .social a { display: block; font-size: .64rem; letter-spacing: .14em; text-transform: uppercase; margin-bottom: .5rem; }

.rail {
  position: fixed; right: clamp(1rem, 4vw, 3.5rem); bottom: 6rem; z-index: 5;
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-size: .58rem; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-faint);
}
.rail::after { content: ''; display: block; width: 3px; height: 30px; background: var(--accent); margin-top: 1.4rem; }

.column {
  --side: clamp(12rem, 24vw, 20rem);
  margin-left: var(--side); margin-right: clamp(2rem, 6vw, 6rem);
  max-width: 1400px; padding: 1rem 0 6rem;
  flex: 1 0 auto;
}

/* ---- section headings ---- */
.section-head { display: flex; align-items: baseline; gap: 1.2rem; margin: 0; }
.section-head h2 { font-size: .68rem; letter-spacing: .22em; text-transform: uppercase; font-weight: 400; margin: 0; }
.section-head span { font-size: .62rem; letter-spacing: .12em; color: var(--ink-faint); }

/* ---- the photo grid ----
   Columns are equal width and fill the space available: one on a phone,
   two on a laptop, three or four on a wide window. Each photo keeps its
   own aspect ratio, so heights vary down a column and nothing is cropped.

   This is a column flow, not a grid, on purpose. The photos come in two
   aspect ratios; in a grid every row would be as tall as its tallest
   photo, leaving ragged dead space under the shorter ones. Here each
   column packs independently, so the space between two photos is always
   exactly --gutter, across and down. Photos read top-to-bottom down a
   column, then continue at the top of the next one. */
.collage {
  column-width: var(--col-min);
  column-gap: var(--gutter);
  margin-bottom: 5rem; padding-top: 25px;
}
.collage .ph {
  position: relative; margin: 0 0 var(--gutter);
  break-inside: avoid;
  background: #E9E9E9; overflow: hidden;
}
.collage .ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Tablets: after the sidebar takes its share there isn't room for two
   --col-min columns, so the width-based flow would drop to one. Force two. */
@media (min-width: 600px) and (max-width: 1000px) {
  .collage { column-width: auto; column-count: 2; }
}
/* Small laptops and iPad landscape: pinned to three. */
@media (min-width: 1024px) and (max-width: 1440px) {
  .collage { column-width: auto; column-count: 3; }
}
/* Anything wider: four. */
@media (min-width: 1441px) {
  .collage { column-width: auto; column-count: 4; }
}

/* ---- lights toggle: greys every page, so this stays unscoped ---- */
.collage .ph img { transition: filter .7s cubic-bezier(.4, 0, .2, 1); }
body.lights-out .collage .ph img { filter: grayscale(1) contrast(1.06) !important; }

/* ---- black and white until viewed, then colour ----
   Opt-in: only pages whose <body> carries `develop` get this. The
   catalog pages leave it off and show their photos in colour straight
   away. Turning it on elsewhere is just adding the class. */
body.develop .collage .ph img { filter: grayscale(1) contrast(1.06); }
body.develop .collage .ph.is-colour img { filter: grayscale(0) contrast(1); }
@media (prefers-reduced-motion: reduce) {
  .collage .ph img { transition: none; }
  body.develop .collage .ph img { filter: none; }
}

/* ---- lightbox: click a photo to see it large ----
   The overlay itself is built by site.js, so no page needs extra HTML.
   It uses the same 1600px file as the grid — the grid only shows it at
   a fraction of that size. */
.collage .ph { cursor: zoom-in; }
.collage .ph:focus-visible { outline: 1px solid var(--ink); outline-offset: 3px; }
body.lightbox-open { overflow: hidden; }
.lightbox {
  position: fixed; inset: 0; z-index: 50;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, .96);
  opacity: 0; transition: opacity .35s ease;
}
.lightbox[hidden] { display: none; }
.lightbox.is-open { opacity: 1; }
.lightbox .lb-img {
  display: block; max-width: min(88vw, 1400px); max-height: 86vh;
  width: auto; height: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .18);
  transform: scale(.86); opacity: 0;
  transition: transform .5s cubic-bezier(.2, .7, .2, 1), opacity .4s ease;
}
.lightbox .lb-img.is-shown { transform: scale(1); opacity: 1; }
.lightbox button {
  position: absolute; background: none; border: 0; padding: .8rem 1rem;
  cursor: pointer; color: var(--ink);
  font-family: var(--font-ui); font-weight: 200; font-size: 2.4rem; line-height: 1;
}
.lightbox button:hover { color: var(--ink-soft); }
.lightbox button:focus-visible { outline: 1px solid var(--ink); }
.lightbox .lb-close { top: .6rem; right: .8rem; }
.lightbox .lb-prev { left: .6rem; top: 50%; transform: translateY(-50%); }
.lightbox .lb-next { right: .6rem; top: 50%; transform: translateY(-50%); }
/* on a phone the arrows would sit on the photo — swiping does the job */
@media (max-width: 760px) { .lightbox .lb-prev, .lightbox .lb-next { display: none; } }
body.lights-out .lightbox .lb-img { filter: grayscale(1) contrast(1.06); }
@media (prefers-reduced-motion: reduce) {
  .lightbox, .lightbox .lb-img { transition: none; }
  .lightbox .lb-img { transform: none; }
}

/* ---- lights toggle ---- */
.lights {
  position: fixed; left: clamp(1.5rem, 8vw, 9rem); bottom: clamp(1.2rem, 3vw, 2.4rem); z-index: 20;
  width: 36px; height: 36px; border-radius: 50%; cursor: pointer;
  background: #fff; border: 1px solid var(--line); color: var(--ink);
  display: grid; place-items: center; padding: 0;
  box-shadow: 0 6px 20px rgba(0,0,0,.12);
  transition: background .25s ease, color .25s ease, border-color .25s ease, transform .2s ease;
}
.lights:hover { transform: translateY(-2px); }
.lights svg { width: 18px; height: 18px; display: block; }
.lights .on { display: none; }
.lights .off { display: block; }
body.lights-out .lights { background: #111; color: #fff; border-color: #111; }
body.lights-out .lights .on { display: block; }
body.lights-out .lights .off { display: none; }
@media (prefers-reduced-motion: reduce) { .lights { transition: none; } }

/* ---- about page ---- */
.about {
  display: grid;
  grid-template-columns: max-content minmax(0, 46ch);
  gap: calc(var(--gutter) * 1.6);
  align-items: start;
  padding: 25px 0 5rem;
}
/* The portrait is set by height; its width follows from its aspect-ratio,
   so it is never cropped. */
.about .portrait { position: relative; margin: 0; background: #E9E9E9; overflow: hidden; height: 480px; }
.about .portrait img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.about .bio p { margin: 0 0 1.4rem; }
.about .bio p.q { font-family: var(--font-serif); font-style: italic; font-size: 1.55rem; line-height: 1.35; }
.about .facts { display: grid; grid-template-columns: repeat(2, auto); gap: 2rem; margin: 2rem 0; }
.about .facts div { font-size: .62rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
.about .facts strong { display: block; font-weight: 400; font-size: 1rem; letter-spacing: .02em; color: var(--ink); margin-bottom: .2rem; }
.about .bio p.more a { font-size: .8rem; letter-spacing: .18em; text-transform: uppercase; border-bottom: 1px solid var(--ink); padding-bottom: 3px; }
/* the lights button greys the portrait too */
.about .portrait img { transition: filter .7s cubic-bezier(.4, 0, .2, 1); }
body.lights-out .about .portrait img { filter: grayscale(1) contrast(1.06); }
@media (prefers-reduced-motion: reduce) { .about .portrait img { transition: none; } }
/* Stacked above the text on narrow screens: sized by width instead, so it
   can shrink on a phone. 360px wide is 480px tall for the 3:4 portrait. */
@media (max-width: 860px) {
  .about { grid-template-columns: minmax(0, 420px); }
  .about .portrait { height: auto; max-width: 360px; }
}

/* ---- contact ---- */
.contact { padding: 0 0 4rem; }
.contact a.mail { font-family: var(--font-serif); font-size: 1.5rem; border-bottom: 1px solid var(--ink); padding-bottom: .1rem; }
.contact p { color: var(--ink-soft); margin: 1rem 0 0; font-size: .85rem; }

/* ---- footer ---- */
footer {
  background: var(--foot); color: var(--foot-ink);
  padding: 1.3rem clamp(1.5rem, 8vw, 9rem);
  display: flex; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap;
  font-size: .62rem; letter-spacing: .16em; text-transform: uppercase;
}
footer ul { list-style: none; margin: 0; padding: 0; display: flex; gap: 1.6rem; flex-wrap: wrap; }
footer a:hover { color: #fff; }

/* ---- responsive ---- */
@media (max-width: 980px) { .column { --side: clamp(10rem, 22vw, 14rem); margin-right: 2rem; } }
@media (max-width: 760px) {
  body { padding-top: 4.4rem; }
  .name-header { padding: 1.1rem 1.5rem; }
  .side { position: static; width: auto; padding: 1.6rem 1.5rem 0; }
  .side nav ul { display: flex; flex-wrap: wrap; gap: 1rem; }
  .side .social, .rail { display: none; }
  .column { margin: 0 auto; width: min(620px, 100% - 3rem); padding-top: 1rem; }
  footer { padding: 1.3rem 1.5rem; }
}
