/* Allison Chu Photography — layout follows portfolio.joemcnally.com/index/all:
   a thin full-width header, a fixed vertical nav down the left, and a near-flush
   masonry photo grid. Black ground, white text, nothing decorative. */

:root {
  --bg: #000;
  --fg: #fff;
  --muted: #8a8a8a;
  --line: #1e1e1e;
  --header-h: 80px;
  --sidebar-w: 200px;
  --gutter: 20px;         /* page edge padding */
  --grid-x: 210px;        /* where the photo grid starts, measured off the reference */
  --grid-gap: 12px;       /* the reference grid is near-flush, but not zero */
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

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

/* Visible to screen readers, not on screen — each gallery still needs an h1. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Header ---------- */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 30;
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 var(--gutter);
  background: var(--bg);
}

.brand {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}

.header-meta {
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: 22px;
  font-size: 0.78rem;
  letter-spacing: 0.01em;
  color: var(--fg);
  white-space: nowrap;
}
.header-meta a:hover { color: var(--muted); }

/* ---------- Left sidebar ---------- */
.sidebar {
  position: fixed;
  top: var(--header-h);
  left: 0;
  bottom: 0;
  width: var(--sidebar-w);
  padding: 4px var(--gutter) 32px;
  overflow-y: auto;
  background: var(--bg);
  z-index: 20;
}

.nav-group {
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
}
.nav-group:last-child { margin-bottom: 0; }

.nav-link {
  display: block;
  font-size: 0.875rem;        /* 14px, matching the reference nav */
  line-height: 27px;          /* the row rhythm of the reference nav */
  font-weight: 400;
  color: var(--fg);
  white-space: nowrap;
}
.nav-link.sub { padding-left: 10px; }   /* categories indent under Overview All */

/* A category Allison has not filled yet: still linked, but plainly marked so the
   tab does not read as a broken gallery. */
.soon-tag {
  display: inline-block;
  margin-left: 7px;
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 400;
  vertical-align: 1px;
}
.nav-link.active .soon-tag { font-weight: 400; }
.nav-link:hover { color: var(--muted); }
.nav-link.active { font-weight: 700; text-decoration: underline; text-underline-offset: 4px; }

.nav-contact {
  display: flex;
  gap: 14px;
  align-items: center;
  margin-top: 4px;
}
.nav-contact a { display: block; line-height: 0; color: var(--fg); }
.nav-contact a:hover { color: var(--muted); }

.nav-icon {
  width: 16px; height: 16px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.nav-icon .icon-dot { fill: currentColor; stroke: none; }

/* ---------- Main / photo grid ---------- */
main {
  margin-top: var(--header-h);
  margin-left: var(--grid-x);
  padding: 0 48px 60px 0;   /* right margin measured off the reference */
}

.photo-grid {
  /* Masonry: equal-width columns, a 12px gutter, each photo keeping its own aspect
     ratio. (The brief said zero gutter, but the reference site measures ~12px between
     columns and rows, so it is matched rather than flattened.) CSS columns rather than
     JS balancing means the DOM order IS the read order, so the lightbox's prev/next
     follows exactly what the eye follows down a column — and it survives a resize
     with no script. */
  column-count: 4;
  column-gap: var(--grid-gap);
  line-height: 0;             /* kills the inline-block gap under each image */
}
@media (max-width: 1200px) { .photo-grid { column-count: 3; } }
@media (max-width: 760px)  { .photo-grid { column-count: 2; } }

.tile {
  display: block;
  break-inside: avoid;
  cursor: zoom-in;
  position: relative;
  margin-bottom: var(--grid-gap);
}

.tile img {
  display: block;
  width: 100%;
  height: auto;
  transition: opacity 0.25s ease;
}
.tile:hover img { opacity: 0.72; }

/* ---------- Hamburger + off-canvas nav (mobile only) ---------- */
.nav-burger {
  display: none;
  position: relative;
  width: 26px;
  height: 20px;
  flex-direction: column;
  justify-content: space-between;
  cursor: pointer;
  flex: none;
}
/* The three bars stay 26x20 so the header keeps its proportions, but a thumb
   needs about 44px. This invisible pad stretches the tappable area past the
   bars without pushing anything in the header around. */
.nav-burger::before {
  content: "";
  position: absolute;
  inset: -12px -14px;
}
.nav-burger span {
  display: block;
  height: 2px;
  background: var(--fg);
  border-radius: 2px;
}

.nav-scrim { display: none; }

@media (max-width: 760px) {
  :root { --header-h: 40px; --gutter: 14px; --grid-x: 0px; --grid-gap: 8px; }

  .nav-burger { display: flex; }
  .brand { font-size: 0.78rem; letter-spacing: 0.1em; }

  /* Desktop rows are 27px, which is a tight target for a thumb. On the phone the
     menu is a full slide-out panel with room to spare, so give each row 44px. */
  .nav-link { line-height: 44px; }
  .nav-group { margin-bottom: 14px; }
  .nav-contact a { padding: 8px 0; }

  /* A 40px bar has no room for the email and the copyright line: at 390px they
     overflow the screen and get clipped mid-address. The phone header keeps the
     hamburger and her name; both contacts live one tap away in the menu, and the
     copyright sits on the About page. */
  .header-meta { display: none; }

  /* Sidebar parks off-canvas and slides in when the hamburger is checked. */
  .sidebar {
    top: var(--header-h);
    width: 220px;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    border-right: 1px solid var(--line);
    padding-top: 16px;
  }
  .nav-toggle:checked ~ .sidebar { transform: translateX(0); }

  /* Tapping anywhere outside the open menu closes it. */
  .nav-toggle:checked ~ .nav-scrim {
    display: block;
    position: fixed;
    inset: var(--header-h) 0 0 0;
    z-index: 15;
    background: rgba(0, 0, 0, 0.55);
  }

  main { margin-left: 0; padding-right: var(--gutter); padding-left: var(--gutter); }
}

/* ---------- Lightbox ---------- */
.lb-lock { overflow: hidden; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.96);
  padding: env(safe-area-inset-top) 12px env(safe-area-inset-bottom);
  touch-action: pan-y;
  line-height: 0;
}
.lightbox[data-open="true"] { display: flex; }

.lb-stage {
  margin: 0;
  max-width: 100%;
  max-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lb-stage img {
  max-width: 94vw;
  max-height: 88vh;
  width: auto;
  height: auto;
  display: block;
}

.lb-btn {
  position: absolute;
  background: rgba(20, 20, 20, 0.6);
  color: var(--fg);
  border: 1px solid var(--line);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  transition: background 0.15s, border-color 0.15s;
  -webkit-tap-highlight-color: transparent;
}
.lb-btn:hover { background: rgba(255, 255, 255, 0.14); border-color: #555; }

.lb-prev, .lb-next {
  top: 50%;
  transform: translateY(-50%);
  width: 52px;
  height: 52px;
  border-radius: 50%;
  font-size: 1.9rem;
  font-weight: 700;
}
.lb-prev { left: clamp(8px, 3vw, 28px); }
.lb-next { right: clamp(8px, 3vw, 28px); }

.lb-close {
  top: clamp(10px, 3vw, 24px);
  right: clamp(10px, 3vw, 24px);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 1.6rem;
}

@media (max-width: 520px) {
  .lb-prev, .lb-next { width: 44px; height: 44px; font-size: 1.5rem; }
}

/* ---------- Coming soon ---------- */
.coming-soon { padding: 40px var(--gutter) 60px 0; }
.cs-title {
  margin: 0;
  font-size: clamp(1.6rem, 4vw, 2.2rem);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.cs-line {
  margin: 10px 0 0;
  color: var(--muted);
  font-size: 0.95rem;
}

/* ---------- About ---------- */
/* Allison's own words, with the portraits she sent alongside them. The text column
   is capped near 60 characters a line; the photos sit beside it on a wide screen and
   stack under it on a narrow one. */
.about {
  padding: 40px var(--gutter) 70px 0;
  max-width: 1000px;
}

/* A tall portrait beside a short paragraph left a hole under the text. The photo
   is capped by HEIGHT rather than width — so it never towers over its paragraphs,
   and never gets cropped to fit — and both columns centre against each other, which
   splits what slack is left evenly instead of pooling it all in one gap. */
.about-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  gap: 40px;
  align-items: start;
}
.about-head-text { max-width: 620px; }

.about-name {
  margin: 0;
  font-size: clamp(1.6rem, 4vw, 2.2rem);
  letter-spacing: -0.01em;
  font-weight: 700;
}
.about-role {
  margin: 6px 0 0;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.72rem;
}
.about-para {
  margin: 16px 0 0;
  font-size: 0.95rem;
  line-height: 1.65;
  color: #d8d8d8;
}
.about-portrait, .about-photo {
  margin: 0;
  display: flex;
  justify-content: flex-end;
}
.about-portrait img, .about-photo img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 300px;   /* caps the tall frames; wide ones are limited by max-width */
}

.about-section {
  margin-top: 40px;
  padding-top: 34px;
  border-top: 1px solid var(--line);
}
.about-section-text { max-width: 620px; }
.about-section h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}
/* A section with a photo splits into two columns; one without keeps the full
   text measure. */
.about-section.has-photo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  gap: 40px;
  align-items: start;
}

/* Below the two-column breakpoint the photo sits under its text, so it is capped
   by width instead — a full-height portrait would push the next heading off screen. */
@media (max-width: 900px) {
  .about-head,
  .about-section.has-photo {
    grid-template-columns: minmax(0, 1fr);
    gap: 26px;
  }
  .about-portrait, .about-photo { justify-content: flex-start; }
  /* min() so the 420px cap never beats the viewport: a plain max-width: 420px
     overrode the 100% above it and pushed a 390px phone 59px sideways. */
  .about-portrait img, .about-photo img {
    max-width: min(420px, 100%);
    max-height: none;
  }
}

.contact-block {
  margin-top: 44px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}
.contact-block h2 {
  margin: 0 0 12px;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  font-weight: 400;
}
.contact-list { list-style: none; margin: 0; padding: 0; font-size: 0.9rem; }
.contact-list li { margin: 0 0 10px; }
.contact-list a {
  border-bottom: 1px solid #333;
  padding-bottom: 2px;
  transition: border-color 0.15s;
}
.contact-list a:hover { border-bottom-color: var(--fg); }


/* ---------- One-page home ---------- */
/* Her About sits at the top and every gallery follows, one scroll. The sidebar
   jumps between them, so each section needs to clear the fixed header when the
   browser lands on it — that is what scroll-margin-top does. */
html { scroll-behavior: smooth; }

.home-section {
  scroll-margin-top: calc(var(--header-h) + 10px);
}
/* The one-page home runs eight grids together, so the break between them has to be
   unmissable while scrolling past a wall of photos: a bright rule and a wide gap.
   The old hairline in --line (#1e1e1e) read as a smudge on black. */
.home-section + .home-section {
  margin-top: 72px;
  padding-top: 44px;
  border-top: 2px solid #4a4a4a;
}
.home-section.about { padding-bottom: 0; }

/* Sleeker section headers: small caps-style label in grey, letter-spaced, so the
   photos carry the page and the headings just mark the break (Bing, 2026-09-04).
   The bright rule above still does the separating work. */
.section-title {
  margin: 0 0 26px;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--muted);
  font-weight: 500;
}

/* ---------- A gallery's own words ---------- */
/* Live Editing is the only section with copy today: a tagline, two paragraphs, and
   the photography credit under the grid. The text column is capped near 65
   characters a line, matching About. */
.section-tagline {
  margin: -4px 0 0;
  font-size: clamp(1.15rem, 2.6vw, 1.5rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  max-width: 620px;
}
.section-intro { max-width: 620px; }
.section-intro p {
  margin: 14px 0 0;
  font-size: 0.95rem;
  line-height: 1.65;
  color: #d8d8d8;
}
.grid-heading {
  margin: 30px 0 14px;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  font-weight: 400;
}
.section-credits {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: 18px 0 0;
  font-size: 0.78rem;
  color: var(--muted);
}

/* Someone who prefers less motion gets an instant jump, not a long glide. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
