/* stillfrm — one deliberate look: a dark gallery wall, so the prints' white
   borders read as mounted photographs. Nothing else in the way. */
:root {
  color-scheme: dark;
  --paper: #121211;
  --panel: #1c1b1a;
  --ink: #ece9e2;
  --soft: #b8b4ab;
  --muted: #8f8b83;
  --faint: #6c6963;
  --hair: #262523;
  --serif: 'Cormorant Garamond', 'Iowan Old Style', Georgia, serif;
  --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --gutter: clamp(16px, 4vw, 64px);
  --ease: cubic-bezier(.2, .7, .2, 1);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 15px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; height: auto; }
/* Components set display:flex/grid; `hidden` must still win. */
[hidden] { display: none !important; }
::selection { background: var(--ink); color: var(--paper); }

/* Images arrive over their own blurred thumbnail, then fade in. */
/* Only hidden when boot.js has run, so a script failure never blanks the page. */
.js img[decoding], .js .ph { opacity: 0; transition: opacity .9s var(--ease); }
.js img.in, .js .ph.in { opacity: 1; }
.frame, .jg .t, .ph { background-size: cover; background-position: center; }

/* Small capitals used for every bit of UI text. */
.tagline, .album-meta, .contact-link, .album-year, .album-foot a, .colophon, .back,
.contact label, .send {
  font: 500 10.5px/1.4 var(--sans);
  letter-spacing: .24em;
  text-transform: uppercase;
}

/* ---------------------------------------------------------------- home */

.masthead {
  position: relative;
  text-align: center;
  padding: clamp(56px, 11vh, 132px) var(--gutter) clamp(44px, 8vh, 96px);
}
.wordmark {
  margin: 0;
  font: 300 clamp(40px, 6vw, 68px)/1 var(--serif);
  letter-spacing: .015em;
}
.wordmark.small { font-size: 26px; display: inline-block; }
.tagline { margin: 18px 0 0; color: var(--muted); }
.contact-link {
  position: absolute;
  top: clamp(20px, 3.4vh, 36px);
  right: var(--gutter);
  background: none;
  border: 0;
  padding: 6px 0;
  color: var(--muted);
  cursor: pointer;
  transition: color .3s;
}
.contact-link:hover, .contact-link:focus-visible { color: var(--ink); }

.albums {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
  gap: clamp(40px, 5vw, 72px) clamp(24px, 3.4vw, 56px);
  padding: 0 var(--gutter) clamp(64px, 10vh, 120px);
  max-width: 1500px;
  margin: 0 auto;
  align-items: end; /* covers keep their own shape; titles still line up */
}
.album-card { display: block; }
/* The cover at its natural proportions — never cropped, so a print's border
   stays intact. */
.frame {
  display: block;
  aspect-ratio: var(--r, 3 / 2);
  overflow: hidden;
  background-color: var(--hair);
}
.frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity .9s var(--ease), transform 1.6s var(--ease), filter 1.2s var(--ease);
  filter: contrast(.97);
}
.album-card:hover .frame img, .album-card:focus-visible .frame img { transform: scale(1.025); filter: contrast(1.04); }
.album-title {
  display: block;
  margin-top: 18px;
  font: italic 400 23px/1.25 var(--serif);
}
.album-meta { display: block; margin-top: 6px; color: var(--muted); }
.empty { grid-column: 1 / -1; text-align: center; font: italic 300 22px var(--serif); color: var(--muted); }

/* ---------------------------------------------------------------- most loved */

/* Deliberately unlike the album cards: a ruled-off section, one horizontal
   filmstrip of smaller prints, each with a rank and its likes. */
.loved {
  max-width: 1500px;
  margin: 0 auto clamp(64px, 10vh, 112px);
  padding: 0 var(--gutter);
}
.loved-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: clamp(28px, 5vh, 44px);
  border-top: 1px solid var(--hair);
  margin-bottom: 22px;
}
.loved-head h2 {
  margin: 0;
  font: 500 10.5px/1.4 var(--sans);
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--muted);
}
.strip-nav { display: flex; gap: 2px; margin-right: -8px; }
.strip {
  --h: clamp(150px, 19vw, 260px);
  list-style: none;
  margin: 0;
  padding: 0 0 14px;
  display: flex;
  gap: clamp(14px, 1.8vw, 26px);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--hair) transparent;
  -webkit-overflow-scrolling: touch;
}
.strip li { flex: none; scroll-snap-align: start; }
.strip a { display: block; }
.strip-img {
  display: block;
  height: var(--h);
  width: calc(var(--h) * var(--r));
  background-size: cover;
  background-position: center;
  background-color: var(--hair);
  overflow: hidden;
}
.strip-img img { width: 100%; height: 100%; object-fit: cover; transition: opacity .9s var(--ease), filter .8s var(--ease); }
.strip a:hover img { filter: brightness(1.08); }
.strip-cap { display: flex; align-items: baseline; justify-content: space-between; margin-top: 10px; }
.strip-cap em { font: italic 400 21px/1 var(--serif); color: var(--ink); }
.strip-cap span { font: 500 10.5px/1.4 var(--sans); letter-spacing: .14em; color: var(--muted); }

.colophon { text-align: center; color: var(--faint); padding: 0 0 40px; }

/* ---------------------------------------------------------------- album */

.album-head {
  text-align: center;
  padding: clamp(28px, 5vh, 48px) var(--gutter) clamp(40px, 7vh, 80px);
}
.album-name {
  margin: clamp(36px, 7vh, 80px) 0 0;
  font: 300 clamp(36px, 5.4vw, 64px)/1.05 var(--serif);
}
.album-desc {
  max-width: 34em;
  margin: 20px auto 0;
  font: italic 400 19px/1.55 var(--serif);
  color: var(--soft);
}
.album-year { margin: 18px 0 0; color: var(--muted); }

/* Justified rows: each tile grows in proportion to its aspect ratio, so every
   row fills the width at a common height and nothing gets cropped. */
.jg {
  --row: clamp(180px, 26vw, 340px);
  display: flex;
  flex-wrap: wrap;
  gap: clamp(12px, 1.6vw, 24px); /* room for each print on the dark wall */
  padding: 0 var(--gutter);
  max-width: 1800px;
  margin: 0 auto;
}
.jg::after { content: ''; flex-grow: 999999; } /* keeps the last row from ballooning */
.jg .t {
  position: relative;
  margin: 0;
  flex: var(--r) 1 calc(var(--r) * var(--row));
  aspect-ratio: var(--r);
  overflow: hidden;
  background-color: var(--hair);
}
.jg .t > a { display: block; width: 100%; height: 100%; }
.jg img { width: 100%; height: 100%; object-fit: cover; transition: opacity .9s var(--ease), filter .8s var(--ease); }
.jg .t:hover img { filter: brightness(1.06); }

/* Like heart, bottom-right of each photo: on hover (desktop), always on touch
   screens, and always once you've liked it. */
.heart {
  position: absolute;
  right: 4%;
  bottom: 5%;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(14, 14, 13, .5);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transition: opacity .3s, transform .35s var(--ease), background-color .3s;
  -webkit-tap-highlight-color: transparent;
}
.heart svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linejoin: round; }
.jg .t:hover .heart, .heart:focus-visible, .heart[aria-pressed="true"] { opacity: 1; }
.heart:hover { background: rgba(14, 14, 13, .72); }
.heart[aria-pressed="true"] svg { fill: currentColor; }
.heart.pop { animation: pop .5s var(--ease); }
.heart:focus-visible { outline: 1px solid #fff; outline-offset: 2px; }
@media (hover: none) { .heart { opacity: .9; } }
@media (max-width: 640px) {
  .jg:not(.single) .heart { width: 28px; height: 28px; }
  .jg:not(.single) .heart svg { width: 13px; height: 13px; }
}
@media (max-width: 640px) {
  .jg { --row: 28vw; }
}
/* album.js has sized every tile exactly (rows fill the width; the last row
   matches the others' height). */
.jg.laid .t { flex: none; }
.jg.laid::after { display: none; }
/* Single column: one large photo per row, centred, with room to breathe. */
.jg.single { flex-direction: column; align-items: center; gap: clamp(28px, 6vh, 72px); }

/* Grid / single-column switch, top-right — the mirror of the back button. */
.layout-switch {
  position: fixed;
  z-index: 10;
  top: max(10px, env(safe-area-inset-top));
  right: max(10px, env(safe-area-inset-right));
  display: flex;
  gap: 2px;
}
.layout-switch .ctl { border-radius: 50%; }
.layout-switch .ctl svg { width: 16px; height: 16px; }
.layout-switch .ctl[aria-pressed="true"] { color: var(--ink); }
.layout-switch .ctl:hover, .layout-switch .ctl:focus-visible { background-color: rgba(18, 18, 17, .55); }

.album-foot { text-align: center; padding: clamp(56px, 9vh, 100px) 0 48px; }
.album-foot a, .back { color: var(--muted); transition: color .3s; }
.album-foot a:hover, .back:hover { color: var(--ink); }

/* ---------------------------------------------------------------- back */

/* One level up: album → home, photo → its album. Pinned, quiet, always there. */
.back-btn {
  position: fixed;
  z-index: 10;
  top: max(10px, env(safe-area-inset-top));
  left: max(10px, env(safe-area-inset-left));
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: var(--muted);
  transition: color .35s, background-color .35s;
  -webkit-tap-highlight-color: transparent;
}
.back-btn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.15; stroke-linecap: round; stroke-linejoin: round; }
.back-btn:hover, .back-btn:focus-visible { color: var(--ink); background-color: rgba(18, 18, 17, .55); }
.back-btn:focus-visible { outline: 1px solid var(--hair); outline-offset: 2px; }
/* Landing back on the album from a photo: leave a little air above it. */
.jg .t { scroll-margin-top: 96px; }

/* ---------------------------------------------------------------- photo */

.k-photo { overflow: hidden; }
.viewer {
  height: 100vh;
  height: 100svh;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: max(56px, 3.2vh) clamp(12px, 3vw, 48px) 0; /* clears the back button */
}
.stage {
  margin: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ph {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.ph.leaving { opacity: 0; transition-duration: .25s; }

.controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: clamp(28px, 5vw, 56px);
  padding: 14px 0 max(16px, env(safe-area-inset-bottom));
}
.ctl {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  transition: color .35s, transform .35s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.ctl svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.15; stroke-linecap: round; stroke-linejoin: round; }
.ctl:hover, .ctl:focus-visible { color: var(--ink); }
.ctl:focus-visible { outline: 1px solid var(--hair); outline-offset: 2px; border-radius: 50%; }
.like svg { width: 16px; height: 16px; }
.like[aria-pressed="true"] { color: var(--ink); }
.like[aria-pressed="true"] svg { fill: currentColor; }
.like.pop { animation: pop .5s var(--ease); }
@keyframes pop { 40% { transform: scale(1.32); } }

/* ---------------------------------------------------------------- contact */

.contact {
  width: min(92vw, 460px);
  border: 0;
  padding: clamp(28px, 5vw, 44px);
  background: var(--panel);
  color: var(--ink);
  box-shadow: 0 30px 90px rgba(0, 0, 0, .6);
}
.contact::backdrop { background: rgba(0, 0, 0, .62); backdrop-filter: blur(3px); }
.contact[open] { animation: rise .45s var(--ease); }
@keyframes rise { from { opacity: 0; transform: translateY(12px); } }
.contact h2 { margin: 0 0 26px; font: 300 34px/1 var(--serif); }
.contact label { display: block; color: var(--muted); margin-bottom: 20px; }
.contact input, .contact textarea {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 8px 0;
  border: 0;
  border-bottom: 1px solid var(--hair);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font: 400 17px/1.5 var(--serif);
  letter-spacing: normal;
  text-transform: none;
  resize: vertical;
  transition: border-color .3s;
}
.contact input:focus, .contact textarea:focus { outline: 0; border-bottom-color: var(--ink); }
.contact .hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.contact-close-form { position: absolute; top: 10px; right: 12px; margin: 0; }
.x { background: none; border: 0; font: 300 28px/1 var(--serif); color: var(--muted); cursor: pointer; padding: 6px; }
.x:hover { color: var(--ink); }
.send {
  margin-top: 6px;
  padding: 13px 30px;
  background: var(--ink);
  color: var(--paper);
  border: 0;
  cursor: pointer;
  transition: opacity .3s;
}
.send:hover { opacity: .82; }
.send[disabled] { opacity: .4; cursor: default; }
.form-error { color: #e8958b; font-size: 13px; margin: -6px 0 14px; }
.contact-thanks p { font: italic 400 19px/1.5 var(--serif); color: var(--soft); margin: 0; }

/* ---------------------------------------------------------------- misc */

.notfound { min-height: 100svh; display: grid; place-content: center; text-align: center; gap: 24px; }
.notfound p { font: italic 300 24px var(--serif); color: var(--muted); margin: 0; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
.strip-nav .ctl[disabled] { opacity: .3; cursor: default; }
