/*
 * CDS Photography — modern visual layer
 * Replace: public/assets/styles.css
 *
 * No JavaScript/data changes are required.
 */

/* Self-hosted Inter Variable (latin + latin-ext only — the site is English-
   only copy). url() resolves relative to this stylesheet, so it stays
   base-path independent. The weight axis (100–900) is what lets the type
   scale below use in-between weights like 560/680/720 instead of snapping
   to the nearest static cut. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('fonts/inter-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('fonts/inter-latin-ext-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg: #f5f5f3;
  --bg-soft: #ececea;
  --surface: rgba(255, 255, 255, 0.72);
  --surface-solid: #ffffff;
  --surface-hover: #ffffff;
  --text: #111214;
  --muted: #6f7175;
  --muted-strong: #4c4f54;
  --line: rgba(17, 18, 20, 0.09);
  --line-strong: rgba(17, 18, 20, 0.16);
  --accent: #111214;
  --accent-contrast: #ffffff;
  --hero-bg: #090a0c;
  --hero-text: #ffffff;
  --hero-muted: rgba(255, 255, 255, 0.68);
  --glass: rgba(248, 248, 246, 0.72);
  --glass-line: rgba(255, 255, 255, 0.42);
  --shadow-sm: 0 8px 30px rgba(18, 20, 24, 0.07);
  --shadow-md: 0 22px 60px rgba(18, 20, 24, 0.13);
  --shadow-lg: 0 38px 100px rgba(0, 0, 0, 0.24);
  --page-x: clamp(18px, 4vw, 72px);
  --section-y: clamp(72px, 9vw, 148px);
  --header-height: 72px;
  --radius-sm: 12px;
  --radius-md: 20px;
  --radius-lg: 28px;
  --radius-xl: 36px;
  --ease: cubic-bezier(.2, .75, .2, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

html[data-theme="dark"] {
  --bg: #0c0d0f;
  --bg-soft: #131519;
  --surface: rgba(24, 26, 30, 0.72);
  --surface-solid: #17191d;
  --surface-hover: #1d2025;
  --text: #f3f4f5;
  --muted: #989ca4;
  --muted-strong: #bec1c7;
  --line: rgba(255, 255, 255, 0.08);
  --line-strong: rgba(255, 255, 255, 0.15);
  --accent: #f3f4f5;
  --accent-contrast: #0d0e10;
  --glass: rgba(15, 17, 20, 0.7);
  --glass-line: rgba(255, 255, 255, 0.09);
  --shadow-sm: 0 8px 30px rgba(0, 0, 0, 0.18);
  --shadow-md: 0 22px 64px rgba(0, 0, 0, 0.28);
  --shadow-lg: 0 40px 110px rgba(0, 0, 0, 0.55);
}

@media (prefers-color-scheme: dark) {
  html[data-theme="system"] {
    --bg: #0c0d0f;
    --bg-soft: #131519;
    --surface: rgba(24, 26, 30, 0.72);
    --surface-solid: #17191d;
    --surface-hover: #1d2025;
    --text: #f3f4f5;
    --muted: #989ca4;
    --muted-strong: #bec1c7;
    --line: rgba(255, 255, 255, 0.08);
    --line-strong: rgba(255, 255, 255, 0.15);
    --accent: #f3f4f5;
    --accent-contrast: #0d0e10;
    --glass: rgba(15, 17, 20, 0.7);
    --glass-line: rgba(255, 255, 255, 0.09);
    --shadow-sm: 0 8px 30px rgba(0, 0, 0, 0.18);
    --shadow-md: 0 22px 64px rgba(0, 0, 0, 0.28);
    --shadow-lg: 0 40px 110px rgba(0, 0, 0, 0.55);
  }
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  background: var(--bg);
  color-scheme: light dark;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-width: 320px;
  overflow-x: hidden;
  background:
    radial-gradient(circle at 84% 7%, rgba(130, 136, 150, 0.08), transparent 28rem),
    var(--bg);
  color: var(--text);
  font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 16px;
  line-height: 1.5;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  transition: background-color 260ms ease, color 260ms ease;
}

body.lightbox-open {
  overflow: hidden;
}

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

button,
a {
  -webkit-tap-highlight-color: transparent;
}

button {
  color: inherit;
  font: inherit;
}

img {
  display: block;
  max-width: 100%;
}

::selection {
  background: var(--text);
  color: var(--bg);
}

[hidden] {
  display: none !important;
}

/* -------------------------------------------------------------------------- */
/* Nav progress bar (astro:transitions lifecycle, see app.js)                */
/* -------------------------------------------------------------------------- */

.nav-progress {
  position: fixed;
  z-index: 10050;
  top: 0;
  left: 0;
  height: 3px;
  width: 0%;
  background: linear-gradient(90deg, var(--text), color-mix(in srgb, var(--text) 35%, transparent));
  opacity: 0;
  pointer-events: none;
  transition: width 320ms ease, opacity 220ms ease;
}

.nav-progress.is-active {
  opacity: 1;
}

.nav-progress.is-done {
  width: 100% !important;
  transition: width 200ms ease, opacity 380ms ease 160ms;
  opacity: 0;
}

/* -------------------------------------------------------------------------- */
/* Warm color grade overlay (toggle in header; persisted like theme)         */
/* -------------------------------------------------------------------------- */

.warmth-overlay {
  position: fixed;
  z-index: 9990;
  inset: 0;
  opacity: .16;
  mix-blend-mode: soft-light;
  pointer-events: none;
  background: #ff9d42;
}

html[data-warmth="off"] .warmth-overlay {
  display: none;
}

.skip-link {
  position: fixed;
  z-index: 10000;
  top: 12px;
  left: 12px;
  transform: translateY(-150%);
  padding: 10px 14px;
  border-radius: 999px;
  background: var(--text);
  color: var(--bg);
  font-size: 13px;
  font-weight: 700;
}

.skip-link:focus {
  transform: translateY(0);
}

.eyebrow {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 750;
  letter-spacing: .16em;
  line-height: 1;
  text-transform: uppercase;
}

/* -------------------------------------------------------------------------- */
/* Header                                                                     */
/* -------------------------------------------------------------------------- */

.site-header {
  position: fixed;
  z-index: 1000;
  top: 14px;
  left: 50%;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  width: min(calc(100% - 28px), 1180px);
  min-height: 58px;
  padding: 7px 8px 7px 18px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  background: rgba(12, 13, 15, 0.38);
  color: #fff;
  box-shadow: 0 12px 42px rgba(0, 0, 0, 0.12);
  backdrop-filter: blur(18px) saturate(135%);
  -webkit-backdrop-filter: blur(18px) saturate(135%);
  transform: translateX(-50%);
  transition:
    background 260ms ease,
    border-color 260ms ease,
    box-shadow 260ms ease,
    top 260ms var(--ease);
}

.site-header.is-scrolled {
  top: 9px;
  border-color: var(--glass-line);
  background: var(--glass);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}

.brand {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: 10px;
  width: max-content;
  font-size: 13px;
  font-weight: 760;
  letter-spacing: -.01em;
}

.brand-mark {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  /* url() resolves relative to this stylesheet, so it is base-path independent.
     Uses a dedicated full-bleed crop, not the PWA icons — those are padded
     for OS home-screen icon masking, which would leave this circular mark
     looking like a tiny eye floating in a mostly-empty dark disc. */
  background: url('logo-mark.png') center / cover no-repeat;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.22);
}

.site-header.is-scrolled .brand-mark {
  box-shadow: 0 0 0 1px var(--line-strong);
}

.main-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
}

.site-header.is-scrolled .main-nav {
  background: var(--line);
}

.main-nav a {
  padding: 7px 13px;
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.78);
  font-size: 12px;
  font-weight: 650;
  transition: background 180ms ease, color 180ms ease;
}

.site-header.is-scrolled .main-nav a {
  color: var(--muted-strong);
}

.main-nav a:hover,
.main-nav a:focus-visible {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  outline: none;
}

.site-header.is-scrolled .main-nav a:hover,
.site-header.is-scrolled .main-nav a:focus-visible {
  background: var(--surface-solid);
  color: var(--text);
}

.icon-button {
  display: inline-grid;
  place-items: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  justify-self: end;
}

.theme-toggle,
.warmth-toggle {
  position: relative;
  background: rgba(255, 255, 255, 0.11);
  color: #fff;
  transition: background 180ms ease, transform 180ms var(--ease);
}

.site-header.is-scrolled .theme-toggle,
.site-header.is-scrolled .warmth-toggle {
  background: var(--line);
  color: var(--text);
}

.theme-toggle:hover,
.warmth-toggle:hover {
  transform: scale(1.04);
}

.warmth-toggle svg {
  opacity: .55;
  transition: opacity 180ms ease;
}

html[data-warmth="off"] .warmth-toggle svg {
  opacity: .22;
}

.icon-button svg,
.hero-control svg,
.hero-scroll svg,
.lightbox-nav svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}

.theme-icon {
  position: absolute;
  transition: opacity 160ms ease, transform 220ms var(--ease);
}

html[data-resolved-theme="light"] .theme-icon-sun,
html[data-resolved-theme="dark"] .theme-icon-moon {
  opacity: 1;
  transform: scale(1) rotate(0deg);
}

html[data-resolved-theme="light"] .theme-icon-moon,
html[data-resolved-theme="dark"] .theme-icon-sun {
  opacity: 0;
  transform: scale(.65) rotate(-25deg);
}

/* -------------------------------------------------------------------------- */
/* Cinematic hero                                                             */
/* -------------------------------------------------------------------------- */

.hero {
  position: relative;
  isolation: isolate;
  min-height: 100svh;
  overflow: hidden;
  background: var(--hero-bg);
  color: var(--hero-text);
}

.hero-stage,
.hero-empty {
  position: absolute;
  inset: 0;
}

.hero-stage {
  z-index: -3;
  overflow: hidden;
  background: #090a0c;
}

.hero-frame {
  --hero-image: none;
  --hero-drift-duration: 8500ms;
  --hero-drift-x: -2.4%;
  --hero-drift-y: -1.5%;
  position: absolute;
  inset: -6%;
  opacity: 0;
  transform: scale(1.02) translate(0, 0);
  transition: opacity 1.1s ease;
}

.hero-frame::before,
.hero-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--hero-image);
  background-position: center;
  background-repeat: no-repeat;
}

.hero-frame::before {
  inset: -3%;
  background-size: cover;
  filter: blur(28px) brightness(.58) saturate(.9);
  transform: scale(1.09);
  opacity: .85;
}

.hero-frame::after {
  background-size: contain;
  filter: saturate(.96) contrast(1.01);
}

.hero-frame.is-active {
  opacity: 1;
  animation: heroDrift var(--hero-drift-duration) linear forwards;
}

/* A slow Ken Burns-style pan+zoom instead of a static frame. The extra
   -6% inset above (vs. the viewport) plus this zoom range together create
   enough surplus image outside the visible area that panning toward
   --hero-drift-x/-y never uncovers an edge. Direction varies per slide
   (set in app.js) so consecutive photos in the rotation don't all drift
   the same way. */
@keyframes heroDrift {
  from { transform: scale(1.03) translate(0, 0); }
  to { transform: scale(1.12) translate(var(--hero-drift-x), var(--hero-drift-y)); }
}

.hero-vignette {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(5, 6, 8, .34) 0%, transparent 30%, transparent 52%, rgba(5, 6, 8, .66) 100%),
    linear-gradient(90deg, rgba(5, 6, 8, .52) 0%, rgba(5, 6, 8, .08) 46%, rgba(5, 6, 8, .18) 100%);
  pointer-events: none;
}

.hero-content {
  position: absolute;
  z-index: 2;
  right: var(--page-x);
  bottom: clamp(58px, 8vh, 104px);
  left: var(--page-x);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 34px;
}

.hero-copy {
  width: min(720px, 74vw);
}

.hero-copy > .eyebrow {
  margin-bottom: 17px;
  color: rgba(255, 255, 255, .66);
}

.hero-copy > h1 {
  max-width: 780px;
  margin: 0;
  font-size: clamp(48px, 7.2vw, 112px);
  font-weight: 560;
  letter-spacing: -.065em;
  line-height: .88;
  text-wrap: balance;
}

.hero-photo-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  margin-top: clamp(26px, 4vw, 46px);
  transition: opacity 160ms ease, transform 260ms var(--ease);
}

.hero-photo-meta.is-changing {
  opacity: 0;
  transform: translateY(8px);
}

.hero-photo-title,
.hero-photo-detail {
  margin: 0;
}

.hero-photo-title {
  font-size: 15px;
  font-weight: 700;
}

.hero-photo-detail {
  color: rgba(255, 255, 255, .58);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.hero-photo-detail:empty {
  display: none;
}

.hero-photo-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
}

.hero-photo-tags .photo-tag {
  border-color: rgba(255, 255, 255, .22);
  background: rgba(255, 255, 255, .09);
  color: rgba(255, 255, 255, .82);
}

.hero-controls {
  display: grid;
  grid-template-columns: repeat(3, 46px) auto;
  align-items: center;
  gap: 7px;
  padding: 7px;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 999px;
  background: rgba(10, 11, 13, .35);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.hero-control {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .09);
  color: #fff;
  cursor: pointer;
  transition: background 180ms ease, transform 180ms var(--ease);
}

.hero-control:hover {
  background: rgba(255, 255, 255, .18);
  transform: scale(1.04);
}

.hero-pause .icon-play,
.hero-pause.is-paused .icon-pause {
  display: none;
}

.hero-pause.is-paused .icon-play {
  display: block;
}

.hero-count {
  display: flex;
  align-items: baseline;
  min-width: 76px;
  padding: 0 12px 0 8px;
  color: rgba(255, 255, 255, .55);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .08em;
}

.hero-current {
  color: #fff;
  font-size: 15px;
  font-weight: 750;
}

.hero-divider {
  padding: 0 5px;
}

.hero-progress {
  position: absolute;
  right: var(--page-x);
  bottom: 34px;
  left: var(--page-x);
  z-index: 2;
  height: 1px;
  overflow: hidden;
  background: rgba(255, 255, 255, .18);
}

.hero-progress span {
  display: block;
  width: 100%;
  height: 100%;
  background: #fff;
  transform: scaleX(0);
  transform-origin: left;
}

.hero-progress span.is-running {
  animation: heroProgress var(--hero-progress-duration, 7000ms) linear forwards;
}

@keyframes heroProgress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

.hero-scroll {
  position: absolute;
  z-index: 3;
  right: var(--page-x);
  top: 50%;
  display: none;
  align-items: center;
  gap: 8px;
  color: rgba(255, 255, 255, .66);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  transform: rotate(90deg) translateX(50%);
  transform-origin: right center;
}

.hero-scroll svg {
  width: 15px;
  height: 15px;
}

.hero-empty {
  z-index: 1;
  display: grid;
  place-items: center;
  padding: var(--page-x);
  background:
    radial-gradient(circle at 50% 32%, rgba(255, 255, 255, .08), transparent 34rem),
    #090a0c;
}

.hero-empty-inner {
  width: min(700px, 100%);
  text-align: center;
}

.hero-empty .eyebrow {
  color: rgba(255, 255, 255, .55);
}

.hero-empty h1 {
  margin: 0;
  font-size: clamp(36px, 6vw, 72px);
  font-weight: 580;
  letter-spacing: -.045em;
  line-height: .98;
}

.hero-empty p:last-child {
  margin: 22px auto 0;
  color: rgba(255, 255, 255, .58);
}

.hero-empty code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .82em;
}

/* -------------------------------------------------------------------------- */
/* Gallery                                                                    */
/* -------------------------------------------------------------------------- */

.gallery-section {
  position: relative;
  scroll-margin-top: 96px;
  padding: var(--section-y) var(--page-x) clamp(88px, 11vw, 170px);
}

.gallery-section::before {
  content: "";
  position: absolute;
  top: 0;
  right: var(--page-x);
  left: var(--page-x);
  height: 1px;
  background: var(--line);
}

.section-heading {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: clamp(34px, 5vw, 60px);
}

.section-heading h2 {
  margin: 0;
  font-size: clamp(44px, 6.8vw, 94px);
  font-weight: 560;
  letter-spacing: -.06em;
  line-height: .9;
}

.gallery-count {
  margin: 0 0 7px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.gallery-actions {
  display: flex;
  margin: 0 0 clamp(32px, 4vw, 48px);
}

.surprise-trigger {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 64px;
  padding: 0 20px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--surface);
  backdrop-filter: blur(18px) saturate(130%);
  -webkit-backdrop-filter: blur(18px) saturate(130%);
  box-shadow: var(--shadow-sm);
  color: var(--text);
  font-size: 14px;
  font-weight: 680;
  white-space: nowrap;
  cursor: pointer;
  transition: background 180ms ease, transform 180ms var(--ease), box-shadow 180ms ease;
}

.surprise-trigger:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 26px rgba(0, 0, 0, .12);
}

.surprise-trigger:active {
  transform: scale(.97);
}

.surprise-trigger svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 320ms var(--ease-out);
}

.surprise-trigger.is-shuffling svg {
  transform: rotate(180deg);
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-flow: dense;
  align-items: start;
  gap: clamp(12px, 1.5vw, 22px);
}

.gallery-card {
  --card-span: 4;
  --reveal-y: 22px;
  position: relative;
  grid-column: span var(--card-span);
  min-width: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: var(--radius-md);
  background: var(--surface-solid);
  box-shadow: 0 1px 0 var(--line);
  cursor: zoom-in;
  text-align: left;
  opacity: 0;
  transform: translateY(var(--reveal-y)) translateZ(0);
  transition:
    transform 420ms var(--ease-out),
    box-shadow 420ms var(--ease-out),
    opacity 480ms ease var(--reveal-delay, 0ms);
}

/* Reveal target class, added unconditionally in app.js right after each
   batch of cards is attached (a small stagger via --reveal-delay, set per
   card from its position in the grid). --reveal-y is what :hover below
   subtracts from, rather than a separate `transform: translateY(-5px)`
   rule — that would need higher specificity than `.is-visible` to win on
   hover, which is a fragile thing to keep true across edits. This way
   there's only ever one rule setting `transform` at a time. */
.gallery-card.is-visible {
  --reveal-y: 0px;
  opacity: 1;
}

.gallery-card-standard,
.gallery-card-squareish,
.gallery-card-portrait {
  --card-span: 4;
}

.gallery-card-panorama {
  --card-span: 8;
}

.gallery-card-ultrawide {
  --card-span: 12;
}

.gallery-card:hover {
  z-index: 2;
  box-shadow: var(--shadow-md);
  transform: translateY(calc(var(--reveal-y) - 5px)) translateZ(0);
}

.gallery-card:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 4px;
}

.gallery-image-wrap {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  /* Rounds and clips its own content instead of relying on .gallery-card's
     overflow:hidden to contain it. A 3D-transformed element (see the
     perspective/rotate below, for the cursor-tilt effect) isn't reliably
     clipped by an ancestor's border-radius in every engine — it can render
     past the parent's rounded corners with hard square edges. Matching the
     radius here too makes this element self-contained either way. */
  border-radius: inherit;
  aspect-ratio: var(--photo-ratio, 1.5);
  background: var(--bg-soft);
  /* --tilt-x/--tilt-y are set on .gallery-card by a delegated pointermove
     listener in app.js and inherited down to this element, so the photo
     itself tilts toward the cursor independent of the card's own hover-lift
     and the image's own hover-zoom (each is a different element/property). */
  transform: perspective(900px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  transition: transform 420ms var(--ease-out);
}

.gallery-image-wrap::before {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0;
  background: linear-gradient(180deg, transparent 53%, rgba(0, 0, 0, .05) 68%, rgba(0, 0, 0, .72) 100%);
  opacity: .72;
  pointer-events: none;
  transition: opacity 300ms ease;
}

.gallery-card:hover .gallery-image-wrap::before {
  opacity: .9;
}

.gallery-image-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.008);
  transition:
    opacity 360ms ease,
    transform 700ms var(--ease-out),
    filter 360ms ease;
}

.gallery-image-wrap img.is-loaded {
  opacity: 1;
}

.gallery-card:hover .gallery-image-wrap img {
  transform: scale(1.025);
}

.gallery-card-meta {
  position: absolute;
  z-index: 3;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: clamp(16px, 2vw, 24px);
  color: #fff;
  pointer-events: none;
}

.gallery-card-meta > span:first-child {
  width: 100%;
  min-width: 0;
}

.gallery-card-title,
.gallery-card-detail {
  display: block;
}

.gallery-card-title {
  overflow: hidden;
  font-size: clamp(15px, 1.2vw, 18px);
  font-weight: 720;
  letter-spacing: -.02em;
  line-height: 1.15;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gallery-card-detail {
  margin-top: 5px;
  color: rgba(255, 255, 255, .66);
  font-size: 11px;
}

.gallery-card-tags {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  justify-content: flex-start;
  width: 100%;
  gap: 5px;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 250ms ease, transform 350ms var(--ease-out);
}

.gallery-card:hover .gallery-card-tags,
.gallery-card:focus-visible .gallery-card-tags {
  opacity: 1;
  transform: translateY(0);
}

.photo-tag {
  display: inline-flex;
  align-items: center;
  min-height: 25px;
  padding: 0 9px;
  border: 1px solid rgba(255, 255, 255, .17);
  border-radius: 999px;
  background: rgba(0, 0, 0, .22);
  color: rgba(255, 255, 255, .82);
  font-size: 10px;
  font-weight: 650;
  white-space: nowrap;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.gallery-empty {
  display: grid;
  place-items: center;
  min-height: 250px;
  margin-top: 24px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  color: var(--muted);
}

.gallery-empty p {
  margin: 0;
}

.show-more-wrap {
  display: flex;
  justify-content: center;
  padding-top: 48px;
}

.show-more {
  position: relative;
  min-width: 150px;
  min-height: 48px;
  padding: 0 22px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background 180ms ease, color 180ms ease, transform 180ms var(--ease);
}

.show-more:hover {
  background: var(--text);
  color: var(--bg);
  transform: translateY(-1px);
}

/* A slow, continuous "breathing" glow on its own layer, behind the button.
   Only `opacity` is animated — box-shadow built from color-mix() doesn't
   reliably tween between keyframes in every engine, which read as a sudden
   flash instead of a fade; opacity always interpolates smoothly. */
.show-more::after {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: -1;
  border-radius: inherit;
  box-shadow: 0 0 0 1px color-mix(in srgb, currentColor 55%, transparent), 0 0 28px 7px color-mix(in srgb, currentColor 42%, transparent);
  opacity: 0;
  pointer-events: none;
  animation: showMoreBreathe 4.5s ease-in-out infinite;
  transition: opacity 220ms ease;
}

.show-more:hover::after {
  opacity: 0 !important;
  animation-play-state: paused;
}

@keyframes showMoreBreathe {
  0%, 100% { opacity: 0; }
  50% { opacity: 1; }
}

/* -------------------------------------------------------------------------- */
/* Locations map                                                              */
/* -------------------------------------------------------------------------- */

.map-section {
  padding: 0 var(--page-x) clamp(60px, 8vw, 120px);
}

.location-map {
  width: 100%;
  height: clamp(320px, 45vw, 520px);
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  background: var(--bg-soft);
}

/* Fakes a dark basemap from OSM's single light tile style. Scoped to just
   the tile pane (not the whole map) so markers and popup photo thumbnails,
   which live in separate Leaflet panes, keep their real colors. */
.location-map.is-dark-tiles .leaflet-tile-pane {
  filter: invert(100%) hue-rotate(180deg) brightness(95%) contrast(90%);
}

/* Leaflet ships its own light-chrome UI; re-skin the pieces that show
   through to match the site's theme variables instead of looking like a
   pasted-in third-party widget. */
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
  background: var(--surface-solid);
  color: var(--text);
  box-shadow: var(--shadow-md);
}

.leaflet-popup-close-button {
  color: var(--muted) !important;
}

.leaflet-control-zoom a {
  background: var(--surface-solid) !important;
  color: var(--text) !important;
  border-color: var(--line) !important;
}

.leaflet-control-zoom a:hover {
  background: var(--surface-hover) !important;
}

.leaflet-control-attribution {
  background: var(--surface) !important;
  color: var(--muted) !important;
}

.leaflet-control-attribution a {
  color: var(--muted-strong) !important;
}

.map-popup-title {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 720;
}

.map-popup-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-width: 180px;
}

.map-popup-thumbs a {
  display: block;
  width: 52px;
  height: 52px;
  border-radius: 8px;
  overflow: hidden;
}

.map-popup-thumbs img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.map-popup-more {
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  background: var(--bg-soft);
}

/* Custom marker dot — echoes .brand-mark's dot motif instead of Leaflet's
   stock blue pin, so the map reads as part of this site, not a pasted-in
   widget. */
.map-marker-dot {
  display: grid;
  place-items: center;
}

.map-marker-dot span {
  display: block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--text);
  border: 3px solid var(--bg);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .4);
  transition: transform 180ms var(--ease);
}

.map-marker-dot:hover span {
  transform: scale(1.25);
}

/* -------------------------------------------------------------------------- */
/* About                                                                      */
/* -------------------------------------------------------------------------- */

.about-section {
  position: relative;
  scroll-margin-top: 96px;
  display: grid;
  grid-template-columns: minmax(80px, .38fr) minmax(320px, 1.15fr) minmax(260px, .65fr);
  gap: clamp(24px, 5vw, 80px);
  margin: 0 var(--page-x) var(--section-y);
  padding: clamp(34px, 6vw, 72px);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  background:
    radial-gradient(circle at 95% 0%, rgba(125, 132, 145, .11), transparent 24rem),
    var(--surface);
  box-shadow: var(--shadow-sm);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.about-index {
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: .12em;
}

.about-copy h2 {
  margin: 0;
  max-width: 620px;
  font-size: clamp(38px, 5.2vw, 74px);
  font-weight: 560;
  letter-spacing: -.055em;
  line-height: .94;
}

.about-copy > p:not(.eyebrow) {
  max-width: 650px;
  margin: 22px 0 0;
  color: var(--muted-strong);
  font-size: clamp(15px, 1.25vw, 18px);
  line-height: 1.7;
}

.about-meta {
  align-self: end;
}

.about-meta > div {
  display: grid;
  gap: 5px;
  padding: 17px 0;
  border-bottom: 1px solid var(--line);
}

.about-meta > div:last-child {
  border-bottom: 0;
}

.about-meta span {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.about-meta strong,
.about-meta a {
  font-size: 14px;
  font-weight: 650;
}

.about-meta a:hover {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.about-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
}

.about-specialties {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
}

.about-chip {
  display: inline-flex;
  align-items: center;
  min-height: 27px;
  padding: 0 11px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 620;
}

/* -------------------------------------------------------------------------- */
/* Footer                                                                     */
/* -------------------------------------------------------------------------- */

.site-footer {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 20px;
  margin: 0 var(--page-x);
  padding: 28px 0 34px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 11px;
}

.footer-brand {
  color: var(--text);
}

.site-footer p {
  margin: 0;
  text-align: center;
}

.back-to-top {
  justify-self: end;
  color: var(--text);
  font-weight: 650;
}

.back-to-top span {
  display: inline-block;
  margin-left: 5px;
  transition: transform 180ms var(--ease);
}

.back-to-top:hover span {
  transform: translateY(-3px);
}

/* -------------------------------------------------------------------------- */
/* Story page (src/pages/photo/[slug].astro)                                  */
/* -------------------------------------------------------------------------- */

.story-page {
  min-height: 100vh;
}

.story-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px var(--page-x);
}

.story-header .brand {
  color: var(--text);
}

.story-header-link {
  color: var(--muted-strong);
  font-size: 13px;
  font-weight: 650;
}

.story-header-link:hover {
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.story-main {
  max-width: 980px;
  margin: 0 auto;
  padding: 0 var(--page-x) clamp(60px, 8vw, 100px);
}

.story-figure {
  margin: 0 0 clamp(28px, 4vw, 44px);
}

.story-figure picture,
.story-figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

.story-body {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  justify-content: space-between;
  margin-bottom: clamp(40px, 6vw, 64px);
}

.story-copy {
  max-width: 640px;
}

.story-copy h1 {
  margin: 0;
  font-size: clamp(30px, 4.2vw, 46px);
  font-weight: 620;
  letter-spacing: -.03em;
  line-height: 1.08;
}

.story-description {
  margin: 16px 0 0;
  color: var(--muted-strong);
  font-size: 16px;
  line-height: 1.65;
}

.story-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 18px;
}

.story-tags .photo-tag {
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--muted-strong);
}

.story-actions {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  gap: 8px;
  align-self: flex-start;
  min-width: 220px;
}

.story-action {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 0 20px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
  font-weight: 680;
  text-align: center;
  transition: background 180ms ease, transform 180ms var(--ease), box-shadow 180ms ease;
}

.story-action:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}

.story-action-primary {
  border-color: transparent;
  background: var(--text);
  color: var(--bg);
}

.story-action-inquiry {
  border-color: color-mix(in srgb, var(--text) 20%, transparent);
}

.story-pager {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: clamp(48px, 7vw, 80px);
}

.story-pager-link {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
  transition: background 180ms ease, transform 180ms var(--ease);
}

.story-pager-link:hover {
  transform: translateY(-2px);
  background: var(--surface-hover);
}

.story-pager-next {
  align-items: flex-end;
  text-align: right;
}

.story-pager-eyebrow {
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.story-pager-title {
  overflow: hidden;
  color: var(--text);
  font-size: 14px;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.story-related-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-top: 20px;
}

.story-related-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  color: var(--text);
}

.story-related-card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-md);
  object-fit: cover;
  background: var(--bg-soft);
  transition: transform 300ms var(--ease-out);
}

.story-related-card:hover img {
  transform: scale(1.03);
}

.story-related-card span {
  overflow: hidden;
  font-size: 13px;
  font-weight: 620;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.story-footer {
  grid-template-columns: 1fr;
  justify-items: center;
  gap: 10px;
  text-align: center;
}

.story-footer p {
  order: 2;
}

@media (max-width: 640px) {
  .story-body {
    flex-direction: column;
  }

  .story-actions {
    width: 100%;
    min-width: 0;
  }

  .story-pager {
    grid-template-columns: 1fr;
  }

  .story-pager-next {
    align-items: flex-start;
    text-align: left;
  }

  .story-related-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* -------------------------------------------------------------------------- */
/* Toast                                                                       */
/* -------------------------------------------------------------------------- */

.toast {
  position: fixed;
  z-index: 1200;
  left: 50%;
  bottom: clamp(24px, 6vh, 56px);
  padding: 12px 20px;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 999px;
  background: rgba(20, 21, 24, .92);
  color: #fff;
  font-size: 13px;
  font-weight: 650;
  white-space: nowrap;
  box-shadow: var(--shadow-md);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 10px);
  transition: opacity 220ms ease, transform 220ms var(--ease-out);
}

.toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* -------------------------------------------------------------------------- */
/* Share dialog                                                                */
/* -------------------------------------------------------------------------- */

.share-dialog {
  z-index: 1100;
  width: min(420px, calc(100% - 32px));
  max-width: none;
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--radius-lg);
  background: transparent;
  color: #fff;
}

.share-dialog::backdrop {
  background: rgba(0, 0, 0, .72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.share-dialog-backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
}

.share-dialog-panel {
  padding: 22px;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--radius-lg);
  background: rgba(20, 21, 24, .96);
  box-shadow: var(--shadow-lg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

.share-dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.share-dialog-title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
}

.share-dialog-close {
  width: 34px;
  height: 34px;
  background: rgba(255, 255, 255, .09);
  color: #fff;
}

.share-dialog-close svg {
  width: 15px;
  height: 15px;
}

.share-link-row {
  display: flex;
  gap: 8px;
  margin-bottom: 18px;
}

.share-link-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;
  padding: 0 14px;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 12px;
  background: rgba(255, 255, 255, .06);
  color: #fff;
  font-size: 13px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.share-copy-btn {
  flex: 0 0 auto;
  height: 44px;
  padding: 0 18px;
  border: 0;
  border-radius: 12px;
  background: #fff;
  color: #0b0c0e;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 160ms var(--ease);
}

.share-copy-btn:hover {
  transform: translateY(-1px);
}

.share-targets {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.share-target {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px 4px;
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 14px;
  color: #fff;
  font-size: 11px;
  font-weight: 620;
  transition: background 160ms ease, transform 160ms var(--ease);
}

.share-target:hover {
  background: rgba(255, 255, 255, .08);
  transform: translateY(-1px);
}

.share-target-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .1);
}

.share-target-icon svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

/* -------------------------------------------------------------------------- */
/* Install (PWA) prompt                                                        */
/* -------------------------------------------------------------------------- */

.install-prompt {
  position: fixed;
  z-index: 950;
  right: clamp(16px, 4vw, 28px);
  bottom: clamp(16px, 4vw, 28px);
  display: flex;
  align-items: center;
  gap: 14px;
  width: min(380px, calc(100% - 32px));
  padding: 13px 15px;
  border: 1px solid var(--glass-line);
  border-radius: 18px;
  background: var(--glass);
  box-shadow: var(--shadow-md);
  color: var(--text);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  animation: installIn 360ms var(--ease-out);
}

@keyframes installIn {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

.install-icon {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  border-radius: 12px;
}

.install-text {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.install-text strong {
  font-size: 14px;
  font-weight: 720;
}

.install-text span {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.4;
}

.install-actions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 6px;
}

.install-accept {
  min-height: 38px;
  padding: 0 16px;
  border: 0;
  border-radius: 999px;
  background: var(--text);
  color: var(--bg);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 160ms var(--ease);
}

.install-accept:hover {
  transform: translateY(-1px);
}

.install-dismiss {
  min-height: 38px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted-strong);
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
}

.install-dismiss:hover {
  background: var(--line);
}

/* -------------------------------------------------------------------------- */
/* Mobile tab bar (shown only on small screens)                               */
/* -------------------------------------------------------------------------- */

.mobile-tabbar {
  display: none;
}

/* -------------------------------------------------------------------------- */
/* Lightbox                                                                   */
/* -------------------------------------------------------------------------- */

.lightbox {
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 0;
  background: transparent;
  color: #fff;
}

.lightbox::backdrop {
  background: rgba(0, 0, 0, .9);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.lightbox-backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: rgba(4, 5, 6, .93);
}

.lightbox-shell {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  width: 100%;
  height: 100%;
  padding: 14px clamp(12px, 2vw, 28px) clamp(16px, 2vw, 30px);
}

.lightbox-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 54px;
  padding: 0 2px;
}

.lightbox-counter {
  color: rgba(255, 255, 255, .52);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: .13em;
}

.lightbox-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.lightbox-share,
.lightbox-close {
  background: rgba(255, 255, 255, .09);
  color: #fff;
  transition: background 180ms ease, transform 180ms var(--ease);
}

.lightbox-share:hover {
  background: rgba(255, 255, 255, .16);
  transform: scale(1.05);
}

.lightbox-close:hover {
  background: rgba(255, 255, 255, .16);
  transform: rotate(4deg) scale(1.03);
}

.lightbox-media {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 0;
  overflow: hidden;
  border-radius: var(--radius-md);
}

.lightbox-image {
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: contain;
  object-position: center;
  /* drop-shadow follows the letterboxed photo's shape; box-shadow would draw
     around the full element box including the empty bars. */
  filter: drop-shadow(0 24px 60px rgba(0, 0, 0, .5));
  transition: opacity 240ms ease;
}

/* While a swipe is in progress, keep the eye on the photo — the header and
   caption fade back so they don't compete with the drag. */
.lightbox-shell.is-dragging .lightbox-header,
.lightbox-shell.is-dragging .lightbox-caption {
  transition: opacity 150ms ease;
  opacity: .3;
  pointer-events: none;
}

.lightbox-image.is-loading-full {
  opacity: .92;
}

.lightbox-nav {
  position: absolute;
  z-index: 3;
  top: 50%;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .11);
  border-radius: 50%;
  background: rgba(0, 0, 0, .34);
  color: #fff;
  cursor: pointer;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transform: translateY(-50%);
  transition: background 180ms ease, transform 180ms var(--ease);
}

.lightbox-nav:hover {
  background: rgba(255, 255, 255, .14);
}

.lightbox-prev {
  left: 14px;
}

.lightbox-next {
  right: 14px;
}

.lightbox-prev:hover {
  transform: translateY(-50%) translateX(-2px);
}

.lightbox-next:hover {
  transform: translateY(-50%) translateX(2px);
}

.lightbox-caption {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px;
  min-height: 92px;
  padding: 18px 2px 0;
}

.lightbox-caption p {
  margin: 0;
}

.lightbox-caption-main {
  min-width: 0;
}

.lightbox-title {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.02em;
}

.lightbox-description {
  margin: 10px 0 0 !important;
  max-width: 62ch;
  color: rgba(255, 255, 255, .84);
  font-size: 14px;
  line-height: 1.55;
}

.lightbox-description:empty {
  display: none;
}

.lightbox-detail,
.lightbox-technical {
  margin-top: 6px !important;
  color: rgba(255, 255, 255, .5);
  font-size: 11px;
}

.lightbox-caption-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
}

.lightbox-tags {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}

.lightbox-tags .photo-tag {
  background: rgba(255, 255, 255, .08);
}

.lightbox-inquiry {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 0 16px;
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: 999px;
  background: rgba(255, 255, 255, .08);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  transition: background 180ms ease, transform 180ms var(--ease);
}

.lightbox-inquiry:hover {
  background: rgba(255, 255, 255, .16);
  transform: translateY(-1px);
}

/* -------------------------------------------------------------------------- */
/* Responsive                                                                 */
/* -------------------------------------------------------------------------- */

@media (min-width: 1500px) {
  .gallery-section {
    max-width: 1720px;
    margin: 0 auto;
  }

  .about-section,
  .site-footer {
    max-width: calc(1720px - (var(--page-x) * 2));
    margin-right: auto;
    margin-left: auto;
  }
}

@media (max-width: 1100px) {
  .gallery-card-standard,
  .gallery-card-squareish,
  .gallery-card-portrait {
    --card-span: 6;
  }

  .gallery-card-panorama,
  .gallery-card-ultrawide {
    --card-span: 12;
  }

  .about-section {
    grid-template-columns: 70px 1fr;
  }

  .about-meta {
    grid-column: 2;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 24px;
    align-self: auto;
  }

  .about-meta > div {
    border-bottom: 0;
    border-top: 1px solid var(--line);
  }
}

@media (max-width: 760px) {
  :root {
    --page-x: 16px;
    --section-y: 74px;
    --tabbar-h: 62px;
  }

  body {
    padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px));
  }

  .site-header {
    top: calc(9px + env(safe-area-inset-top, 0px));
    width: calc(100% - 18px);
    min-height: 54px;
    padding-left: 14px;
  }

  .site-header.is-scrolled {
    top: calc(7px + env(safe-area-inset-top, 0px));
  }

  .main-nav {
    display: none;
  }

  .site-header {
    grid-template-columns: 1fr auto;
  }

  .theme-toggle {
    grid-column: 2;
  }

  .hero {
    min-height: 100svh;
  }

  .hero-frame::before {
    filter: blur(22px) brightness(.55) saturate(.9);
  }

  /* Anchor the contained photo above dead-center instead of exactly centering
     it: shifts the letterbox gap mostly below the image (behind the caption)
     rather than splitting it evenly above and below, without pinning the
     photo flush to the header. */
  .hero-frame::after {
    background-position: center var(--hero-photo-pos, 30%);
  }

  /* Keep the whole photo visible on phones (contain, from the base rule) —
     the blurred ::before backdrop already fills the space above/below it,
     so nothing is empty and nothing crops the composition beyond recognition. */
  .hero-vignette {
    background:
      linear-gradient(180deg, rgba(5, 6, 8, .34) 0%, transparent 26%, transparent 40%, rgba(5, 6, 8, .82) 100%);
  }

  .hero-content {
    right: max(18px, env(safe-area-inset-right, 0px));
    bottom: calc(22px + var(--tabbar-h) + env(safe-area-inset-bottom, 0px));
    left: max(18px, env(safe-area-inset-left, 0px));
    display: block;
  }

  .hero-copy {
    width: 100%;
  }

  .hero-copy > h1 {
    max-width: 100%;
    font-size: clamp(30px, 8.6vw, 50px);
    line-height: .98;
  }

  .hero-photo-meta {
    margin-top: 24px;
  }

  .hero-controls {
    width: max-content;
    margin: 24px auto 0;
    grid-template-columns: repeat(3, 44px) auto;
  }

  .hero-control {
    width: 44px;
    height: 44px;
  }

  /* On short phone screens the bottom-anchored bar can get squeezed out
     by the tab bar. Move it to the top of the hero instead — below the
     header, spanning full width, like a stories-style progress indicator —
     where it's never at risk of being hidden regardless of viewport height. */
  .hero-progress {
    top: 0;
    right: 0;
    bottom: auto;
    left: 0;
    height: 2px;
    background: rgba(255, 255, 255, .14);
  }

  .section-heading {
    align-items: flex-start;
  }

  .section-heading h2 {
    font-size: clamp(42px, 13vw, 64px);
  }

  .gallery-count {
    margin-top: 4px;
    white-space: nowrap;
  }

  .gallery-grid {
    grid-template-columns: 1fr;
    gap: 12px;
  }

  .gallery-card,
  .gallery-card-standard,
  .gallery-card-squareish,
  .gallery-card-portrait,
  .gallery-card-panorama,
  .gallery-card-ultrawide {
    grid-column: 1 / -1;
    border-radius: 17px;
  }

  .gallery-card-meta {
    padding: 15px;
  }

  .gallery-card-tags {
    display: none;
  }

  .gallery-card-title {
    font-size: 15px;
  }

  .about-section {
    grid-template-columns: 1fr;
    gap: 24px;
    margin-right: 12px;
    margin-left: 12px;
    padding: 26px 22px;
    border-radius: 24px;
  }

  .about-index {
    display: none;
  }

  .about-copy,
  .about-meta {
    grid-column: auto;
  }

  .about-meta {
    display: block;
  }

  .about-meta > div {
    border-top: 0;
    border-bottom: 1px solid var(--line);
  }

  .site-footer {
    grid-template-columns: 1fr auto;
    gap: 12px;
    padding-bottom: calc(34px + env(safe-area-inset-bottom, 0px));
  }

  .site-footer p {
    grid-column: 1 / -1;
    grid-row: 2;
    text-align: left;
  }

  .lightbox-shell {
    padding:
      calc(8px + env(safe-area-inset-top, 0px))
      calc(8px + env(safe-area-inset-right, 0px))
      calc(16px + env(safe-area-inset-bottom, 0px))
      calc(8px + env(safe-area-inset-left, 0px));
  }

  .lightbox-media {
    border-radius: 14px;
  }

  .lightbox-nav {
    width: 44px;
    height: 44px;
  }

  .lightbox-prev {
    left: 8px;
  }

  .lightbox-next {
    right: 8px;
  }

  /* Modern floating share button, detached from the header and pinned to
     the bottom-right corner of the screen — out of the way of the swipe
     gesture area and always reachable with a thumb. */
  .lightbox-share {
    position: fixed;
    z-index: 60;
    right: calc(16px + env(safe-area-inset-right, 0px));
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    width: 54px;
    height: 54px;
    background: rgba(20, 21, 24, .78);
    border: 1px solid rgba(255, 255, 255, .14);
    box-shadow: var(--shadow-md);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
  }

  .lightbox-share svg {
    width: 21px;
    height: 21px;
  }

  .lightbox-header-actions {
    gap: 0;
  }

  .lightbox-caption {
    display: block;
    min-height: 112px;
    padding: 16px 6px 0;
  }

  .lightbox-caption-side {
    align-items: flex-start;
    margin-top: 12px;
  }

  .lightbox-tags {
    justify-content: flex-start;
  }

  .mobile-tabbar {
    position: fixed;
    z-index: 900;
    right: 0;
    bottom: 0;
    left: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4px;
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--glass-line);
    background: var(--glass);
    backdrop-filter: blur(20px) saturate(140%);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
  }

  .tab {
    display: grid;
    justify-items: center;
    gap: 4px;
    padding: 6px 0;
    border-radius: 14px;
    color: var(--muted);
    font-size: 10px;
    font-weight: 680;
    letter-spacing: .02em;
    transition: color 160ms ease, background 160ms ease;
  }

  .tab svg {
    width: 23px;
    height: 23px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .tab.is-active {
    color: var(--text);
  }

  .tab:active {
    background: var(--line);
  }

  .install-prompt {
    right: 12px;
    left: 12px;
    bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 12px);
    width: auto;
    flex-wrap: wrap;
  }

  .toast {
    bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 16px);
  }

  .install-actions {
    width: 100%;
    justify-content: flex-end;
  }
}

@media (hover: none) {
  .gallery-card:hover {
    box-shadow: 0 1px 0 var(--line);
    transform: translateY(var(--reveal-y)) translateZ(0);
  }

  .gallery-card:hover .gallery-image-wrap img {
    transform: none;
  }

  .gallery-card-tags {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }

  .hero-frame.is-active {
    animation: none;
  }
}
