:root{
  --bg:#3B3934;
  --bg-elevated:#454239;
  --text:#EDE8DD;
  --text-muted:#B3ACA0;
  --accent:#BE8C4A;
  --border:#4E4A40;
}
body{ background:var(--bg); color:var(--text); }

.site-header{
  display:flex;
  justify-content:space-between;
  align-items:center;
  padding-top: var(--header-pad, 14px);      /* headerPadding in PAGE_LAYOUT */
  padding-bottom: var(--header-pad, 14px);
  border-bottom:1px solid var(--border);
}
/* Same typeface as "Antonio Sbrolli" everywhere else it appears — the
   landing page's big name and the Biography dialog's name (see
   .center-mark .name in index.html and .bio-name in base.css). */
.site-title{
  font-family: var(--font-body);
  font-weight:500;
  font-size:1.2rem;
}
.site-nav{
  display:flex;
  align-items:center;
  gap: var(--space-3);
}
.site-nav a, .site-nav button{
  background:none;
  border:none;
  padding:0;
  font-family: inherit;
  color: var(--text-muted);
  font-size:0.95rem;
  border-bottom:1px solid transparent;
  cursor:pointer;
}
.site-nav a:hover, .site-nav button:hover{ color:var(--accent); border-color:var(--accent); }

.location-filter{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap: var(--space-1);
  padding-top: var(--filter-pad, 12px);      /* filterPadding in PAGE_LAYOUT */
  padding-bottom: var(--filter-pad, 12px);
  border-bottom:1px solid var(--border);
}
.filter-btn{
  background:none;
  border:1px solid var(--border);
  color: var(--text-muted);
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  font-size:0.85rem;
}
.filter-btn:hover{ color: var(--text); border-color: var(--text-muted); }
.filter-btn.active{
  color: var(--bg);
  background: var(--accent);
  border-color: var(--accent);
}
.filter-btn-more{ font-style:italic; }
/* The gallery filter ("All galleries", "Choose galleries…", "Showing: …
   Clear" — the class names still say "location", from the old filter by
   place). On phones and smartwatches (filterWrap: true in their
   PAGE_LAYOUT row) the "Showing" line goes underneath the buttons. */
html[data-filter-wrap="on"] .location-status{ flex-basis:100%; margin-left:0; }
.photo-thumb.hidden{ display:none; }

.location-status{
  display:inline-flex;
  align-items:center;
  gap:0.5rem;
  font-size:0.85rem;
  color: var(--text-muted);
  margin-left: var(--space-1);
}
.location-status[hidden]{ display:none; }
.location-status-clear{
  background:none; border:none;
  color: var(--accent);
  border-bottom:1px solid var(--accent);
  font-size:0.8rem;
  padding:0;
}

.location-dialog{
  border:1px solid var(--border);
  border-radius:10px;
  background: var(--bg-elevated);
  color: var(--text);
  padding: var(--space-3);
  width: min(28rem, 90vw);
  max-height: 70vh;
}
.location-dialog::backdrop{ background: rgba(20,19,17,0.6); }
.location-dialog-header{
  display:flex;
  justify-content:space-between;
  align-items:center;
  margin-bottom: var(--space-2);
  font-family: var(--font-display);
}
.location-dialog-header h3{ font-weight:500; font-size:1.2rem; }
.location-dialog-close{
  background:none; border:none; color: var(--text);
  font-size:1.4rem; line-height:1;
}
.location-dialog-list{
  display:flex;
  flex-direction:column;
  gap: 2px;
  overflow-y:auto;
  max-height: 55vh;
}
.location-dialog-item{
  text-align:left;
  background:none;
  border:none;
  color: var(--text);
  padding: 0.6rem 0.4rem;
  border-radius:6px;
  font-size:0.95rem;
}
.location-dialog-item:hover{ background: var(--bg); color: var(--accent); }
.location-dialog-item.selected{ color: var(--accent); font-weight:500; }
.location-dialog-item.selected::after{ content:' ✓'; }
.location-dialog-item:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }

/* Space between one gallery and the next (--gallery-gap, from PAGE_LAYOUT in
   constants.js): half above the dividing line, half below. The left/right
   padding is set in css/base.css. */
.gallery-section{
  padding-top: calc(var(--gallery-gap, 160px) / 2);
  padding-bottom: calc(var(--gallery-gap, 160px) / 2);
  /* galleryDivider in PAGE_LAYOUT: thickness of the line (0 = no line) */
  border-bottom: var(--gallery-divider, 1px) solid var(--border);
}
.gallery-header{
  max-width: 40rem;
  margin-top: var(--gallery-header-top, 0px);         /* galleryHeaderTop in PAGE_LAYOUT */
  margin-bottom: var(--gallery-header-gap, 48px);     /* galleryHeaderBottom in PAGE_LAYOUT */
}
.gallery-title{
  font-family: var(--font-display);
  font-weight:500;
  /* galleryTitleSize in PAGE_LAYOUT, or by default growing with the window */
  font-size: var(--gallery-title-size, clamp(2rem, 3.4vw, 2.8rem));
  line-height:1.2;
  margin-bottom: var(--gallery-title-gap, 8px);   /* galleryTitleGap in PAGE_LAYOUT */
}
/* galleryTextIndent in PAGE_LAYOUT: title and description indented from
   the photos' left edge. */
.gallery-header-text{
  padding-left: var(--gallery-text-indent, 0px);
}
/* a gallery still in progress (status "wip" in data/photos.js) */
.gallery-status{ margin: 0 0 var(--gallery-title-gap, 8px); font-size:0.85rem; line-height:1.4; }
.gallery-status-label{
  display:inline-block;
  color: var(--accent);
  border:1px solid var(--accent);
  border-radius:999px;
  padding:0.1rem 0.6rem;
  font-size:0.72rem; letter-spacing:0.06em; text-transform:uppercase;
}
.gallery-status-note{ color: var(--text-muted); margin-left:0.35rem; }
/* a draft, seen only when the site is opened from this computer (photos-data.js) */
.gallery-status-label.is-draft{ color: var(--text-muted); border-color: var(--text-muted); border-style:dashed; }
.gallery-desc{
  color: var(--text-muted);
  font-size: var(--gallery-desc-size, 1.05rem);   /* galleryDescSize in PAGE_LAYOUT */
  line-height:1.4;
}

/* Gallery with a map of its "points": title and description on the left
   (starting at the first photo's left edge), the map on the right. The
   map's size — GALLERY_MAP_WIDTH / GALLERY_MAP_HEIGHT percent of a photo's
   width / height — is worked out from the photo grid below by
   layoutGalleryMap in photography.js and set on it as --map-w / --map-h; its right edge sits
   GALLERY_MAP_RIGHT_MARGIN px in from the photos' right edge. */
.gallery-header.has-map{
  max-width:none;
  display:flex;
  align-items:center;
  gap: var(--photo-spacing, 16px);
}
.gallery-header.has-map .gallery-header-text{ flex: 1 1 auto; min-width:0; max-width:40rem; }
.gallery-header.has-map .gallery-map{
  flex: 0 0 auto;
  width: var(--map-w, 16rem);
  height: var(--map-h, auto);   /* set together, they override the aspect-ratio */
  max-width: calc(100% - 10rem);
  order:2;   /* after the title and description, on the right */
  margin-left:auto;
  margin-right: var(--map-right-margin, 0px);
}
/* Photos one per row, or in a sideways-scrolling row (.one-col, set by
   markGalleryColumns in photography.js): a map as wide as a full-width
   photo would push the photos far down — so it shrinks to a small strip
   on the right of the title instead. */
.gallery-section.one-col .gallery-header.has-map .gallery-map{ width:10rem; }
/* Smartwatch (the "watch" row of PAGE_LAYOUT): a smaller map, title and
   description, so they fit the tiny screen. */
html[data-layout="watch"] .filter-btn{ font-size:0.72rem; padding:0.25rem 0.6rem; }
.gallery-map{
  aspect-ratio: var(--map-aspect, 5/2);   /* GALLERY_MAP_ASPECT in constants.js */
  border-radius:10px;
  overflow:hidden;
  border:1px solid var(--border);
  box-shadow: 0 12px 30px -18px rgba(0,0,0,0.6);
}
.gallery-map svg{ display:block; width:100%; height:100%; }

/* Screens whose PAGE_LAYOUT row has galleryMap: 'below' (phones and
   smartwatches by default), or every screen with GALLERY_MAPS_INLINE:
   false: the map isn't beside the title but always shown underneath the
   title and description, full width (up to 26rem). */
html[data-gallery-map="below"] .gallery-section .gallery-header.has-map{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  max-width:none;
  padding-right:0;
}
html[data-gallery-map="below"] .gallery-header.has-map .gallery-header-text{ width:100%; max-width:none; }
html[data-gallery-map="below"] .gallery-section .gallery-header.has-map .gallery-map{
  display:block;
  order:2;
  width:100%;
  max-width:26rem;
  margin:0;   /* the header's own gap (photoGap) already separates it from the text */
}
.map-sea{ fill:#302E2A; }
.map-land{ fill:#5A564C; stroke:#5A564C; stroke-width:0.5px; }
.map-borders{ stroke:#3B3934; stroke-width:0.8px; stroke-linejoin:round; }
/* thematic galleries (GALLERY_SKETCHES in gallery-map.js) are drawn with the map's own classes: .map-sea, .map-land, .map-borders, .map-point */
.map-point-halo{ fill: var(--accent); opacity:0.28; }
.map-point-dot{ fill: var(--accent); stroke:#EDE8DD; stroke-width:1px; vector-effect:non-scaling-stroke; }
.map-point.has-photos{ cursor:pointer; }
.map-point.has-photos:hover .map-point-halo,
.map-point.has-photos:focus-visible .map-point-halo{ opacity:0.6; }
.map-point.has-photos:focus{ outline:none; }
/* a thematic gallery's sketch: its gold dot opens the map of the photos; "×" goes back */
.map-point.show-map{ cursor:pointer; }
.map-point.show-map:hover .map-point-halo,
.map-point.show-map:focus-visible .map-point-halo{ opacity:0.6; }
.map-point.show-map:focus{ outline:none; }
.gallery-sketch{ position:relative; }
.gallery-sketch .map-back{
  position:absolute; top:6px; right:6px;
  width:26px; height:26px; border-radius:50%;
  border:1px solid var(--border); background: rgba(42,40,35,0.85); color: var(--text);
  font-size:1rem; line-height:1; padding:0; cursor:pointer;
}
.gallery-sketch .map-back:hover{ border-color: var(--accent); color: var(--accent); }
.map-point.has-photos:focus-visible .map-point-dot{ stroke-width:2.5px; }

/* ‹ 2 / 14 ›: steps through the gallery (also ← → on the keyboard, a
   swipe on a touchscreen). Always in the same place, whatever the photo and
   its text: ‹ and › at the window's left and right edges, halfway down, the
   count at the bottom in the middle; on phones all three at the bottom. */
.lightbox-nav{
  position:fixed; left:0; right:0; top:calc(50% - 1.6rem);
  display:flex; align-items:center; justify-content:space-between;
  padding:0 1rem;
  pointer-events:none;
  color: var(--text-muted); font-size:0.85rem;
  z-index:2;
}
.lightbox-nav[hidden]{ display:none; }
.lightbox-nav-btn{
  pointer-events:auto;
  /* clearly visible over the dark halftone background */
  background: rgba(20,19,17,0.92); border:1.5px solid rgba(237,232,221,0.7); border-radius:999px;
  color: var(--text); width:3.2rem; height:3.2rem; font-size:1.7rem; line-height:1;
  box-shadow: 0 4px 16px rgba(0,0,0,0.6);
  touch-action: manipulation;
}
.lightbox-nav-btn:hover{ border-color: var(--accent); color: var(--accent); }
.lightbox-nav-count{
  position:fixed; left:0; right:0; bottom:1.2rem;
  text-align:center; letter-spacing:0.05em;
  color: var(--text); text-shadow: 0 1px 8px rgba(0,0,0,0.9);
  pointer-events:none;
}
@media (max-width: 720px), (orientation: portrait){
  .lightbox-nav{ top:auto; bottom:0.8rem; justify-content:center; gap: var(--space-3); }
  .lightbox-nav-count{ position:static; min-width:4rem; }
}

.gallery-grid-wrap{ position:relative; }
/* How many photos sit side by side: as many as fit at --photo-min-width
   or wider, but never fewer than --photos-min nor more than --photos-max
   (GALLERY_PHOTO_MIN_WIDTH, photosPerRowMin and photosPerRowMax in
   constants.js). The clamp() turns those two counts into the narrowest
   and widest a column may be; the -0.1px absorbs rounding so exactly
   that many columns always fit. The gallery header (map + title) uses
   the very same columns, so the map lines up with the first photo. */
.photo-grid,
.gallery-header.has-map{
  --photo-gap: var(--photo-spacing, 16px);   /* photoGap in PAGE_LAYOUT */
  --photo-col: clamp(
    calc((100% - (var(--photos-max, 99) - 1) * var(--photo-gap)) / var(--photos-max, 99) - 0.1px),
    var(--photo-min-width, 260px),
    calc((100% - (var(--photos-min, 1) - 1) * var(--photo-gap)) / var(--photos-min, 1) - 0.1px)
  );
}
.photo-grid{
  position:relative;
  display:grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--photo-col), 1fr));
  gap: var(--photo-gap);
}
/* A single row of photos that scrolls sideways (galleryMode
   'showAllScroll' after "Show", or always in 'scroll'). After "Show
   all", each photo keeps the same size as in the collapsed first row
   (--scroll-tile-w, measured by setScrollRow in photography.js), so the
   row doesn't change height. In 'scroll' mode each photo is as wide as
   the narrowest allowed grid photo and never more than 85% of the row,
   so the edge of the next one peeks in as a hint to swipe. */
.photo-grid.scroll-row{
  display:flex;
  overflow-x:auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
/* No visible scrollbar (it would add a few pixels under the photos and
   change the row's height); the swipe itself is the control. */
.photo-grid.scroll-row::-webkit-scrollbar{ display:none; }
/* An open gallery on computers and tablets: every photo whole, at its own
   proportions, in rows that fill the width (sizes --jw / --jh worked out by
   layoutJustified in photography.js); a sub-gallery heading starts a new row. */
.photo-grid.justified{ display:flex; flex-wrap:wrap; align-items:flex-start; }
.photo-grid.justified .photo-thumb{ flex:0 0 auto; width:var(--jw, 240px); height:var(--jh, 240px); aspect-ratio:auto; }
.photo-grid.justified .subgallery-header{ flex:0 0 100%; }
.photo-grid.justified .photo-thumb img{ object-position:center; }
.photo-grid.scroll-row .photo-thumb{
  flex: 0 0 var(--scroll-tile-w, min(var(--photo-min-width, 260px), 85%));
  scroll-snap-align: start;
}
/* Collapsing a gallery down to its first row no longer clips a container
   with max-height — that relied on measuring a pixel height and animating
   toward/away from it, which was never reliably interpolated whenever the
   starting point was max-height's own "none" default (see the long
   comment above collapseGallery in photography.js for the history of bugs
   that caused, across several rounds). Instead, photography.js just adds
   this class directly to each .photo-thumb past the first row, so a
   collapsed gallery simply doesn't have those elements in the rendered
   layout at all — nothing to clip, nothing to animate, nothing that can
   get stuck partway. */
.photo-thumb.row-hidden{ display:none; }
/* Sub-galleries (photography.js, galleryGridHTML): inside the gallery's
   grid, a smaller heading — name and short description, no map, no line —
   across the whole row before its photos. Hidden when none of its photos is
   showing (collapsed gallery, location filter). In the sideways-scrolling
   row (phones) the heading is a card as wide as a photo. */
.subgallery-header{
  grid-column: 1 / -1;
  padding-top: calc(var(--photo-gap, 16px) * 1.5);
}
.subgallery-header:first-child{ padding-top:0; }
.subgallery-header.sub-empty{ display:none; }
/* a closed gallery showing its "highlights" first: no sub-gallery headings in that first row */
.photo-grid.closed-order .subgallery-header{ display:none; }
/* the sub-gallery's own "Hide" / "Show N photos" (setSubgalleryOpen in
   photography.js), beside its title. Its photos are hidden only while the
   gallery is open (a closed gallery shows its first row of photos as usual). */
.subgallery-title-row{ display:flex; align-items:baseline; flex-wrap:wrap; gap:0.3rem 1rem; }
/* the gallery's title, with its "Hide" beside it while the gallery is open (as a sub-gallery's) */
.gallery-title-row{ display:flex; align-items:baseline; flex-wrap:wrap; gap:0.3rem 1rem; margin-bottom: var(--gallery-title-gap, 8px); }
.gallery-title-row .gallery-title{ margin-bottom:0; }
.gallery-hide{ font-size:0.9rem; }
.sub-toggle{
  background:none; border:none; padding:0;
  color: var(--accent);
  border-bottom:1px solid var(--accent);
  font-family: var(--font-body);
  font-size:0.8rem;
  line-height:1.3;
  white-space:nowrap;
  touch-action: manipulation;
}
.sub-toggle:hover{ color: var(--text); border-color: var(--text); }
.photo-grid:not(.collapsed):not(.closed-order) .photo-thumb.sub-hidden{ display:none; }
.subgallery-header.sub-closed .subgallery-desc{ margin-bottom:0; }
.subgallery-title{
  font-family: var(--font-display);
  font-weight:500;
  font-size: calc(var(--gallery-title-size, clamp(2rem, 3.4vw, 2.8rem)) * 0.6);
  line-height:1.2;
  margin:0 0 0.25rem;
}
.subgallery-desc{
  color: var(--text-muted);
  font-size: calc(var(--gallery-desc-size, 1.05rem) * 0.9);
  line-height:1.4;
  margin:0;
}
.photo-grid.scroll-row .subgallery-header{
  flex: 0 0 var(--scroll-tile-w, min(var(--photo-min-width, 260px), 85%));
  display:flex; flex-direction:column; justify-content:flex-end;
  padding: var(--space-2, 16px);
  scroll-snap-align: start;
  border-left: 2px solid var(--accent);
}
.photo-grid.scroll-row .subgallery-header.sub-empty{ display:none; }
.gallery-toggle{
  display:block;
  margin: var(--gallery-toggle-gap, 16px) auto 0;   /* galleryToggleGap in PAGE_LAYOUT */
  background:none;
  border:1px solid var(--border);
  border-radius:999px;
  padding:0.5rem 1.3rem;
  font-family: var(--font-body);
  font-size:0.85rem;
  color: var(--text);
  cursor:pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.gallery-toggle:hover{ border-color: var(--accent); color: var(--accent); }
/* The display:block above would otherwise override the HTML "hidden"
   attribute, leaving an empty pill under galleries that fit on one row. */
.gallery-toggle[hidden]{ display:none; }
/* An open gallery: "Hide" stays at the bottom of the screen while the
   gallery is scrolled through, and settles under its last photos at the
   end (position: sticky — .is-open is set by setGalleryToggleLabel). */
.gallery-grid-wrap.is-open > .gallery-toggle{
  position:sticky;
  bottom: 1rem;
  z-index:5;
  background: var(--bg);
  box-shadow: 0 6px 18px -6px rgba(0,0,0,0.55);
}
/* Phones ('showAllScroll', see placeGalleryToggle in photography.js): the
   button is a narrow tile beside the photos — right of the first row, and
   at the end of the sideways-scrolling row once it's open — with its text
   running vertically. */
.gallery-grid-wrap.inline-toggle{ display:flex; align-items:stretch; gap: var(--photo-spacing, 16px); }
.gallery-grid-wrap.inline-toggle > .photo-grid{ flex:1 1 auto; min-width:0; }
.gallery-grid-wrap.inline-toggle .gallery-toggle{
  flex: 0 0 2.6rem;
  margin:0;
  padding: 0.6rem 0;
  border-radius:10px;
  display:flex; align-items:center; justify-content:center;
  writing-mode: vertical-rl;
  white-space:nowrap;
  letter-spacing:0.02em;
}
.gallery-grid-wrap.inline-toggle .gallery-toggle[hidden]{ display:none; }
.photo-grid.scroll-row > .gallery-toggle{ scroll-snap-align:end; }
.gallery-section.toggle-beside .gallery-header.has-map{ padding-right: calc(2.6rem + var(--photo-spacing, 16px)); }
.photo-thumb{
  position:relative;
  aspect-ratio: var(--photo-aspect, 4/5);   /* GALLERY_PHOTO_ASPECT in constants.js */
  overflow:hidden;
  background: var(--bg-elevated);
  border:1px solid var(--border);
}
.photo-thumb img{
  width:100%; height:100%; object-fit:cover;
  transition: transform 0.6s ease;
}
.photo-thumb:hover img{ transform: scale(1.04); }
.photo-thumb.placeholder::after{
  content: attr(data-label);
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  text-align:center; padding: var(--space-2);
  font-family: var(--font-display);
  font-style:italic;
  color: var(--text-muted);
}
/* Lightbox */
.lightbox{
  position:fixed; inset:0;
  background: #141311;            /* the halftone background's colour (as in featured/featured.css) */
  display:none;
  align-items:center; justify-content:center;
  padding: var(--space-3) 5rem;     /* room at the sides for ‹ › (.lightbox-nav) */
  z-index:50;
}
.lightbox.open{ display:flex; }
/* Sized to what's actually inside it — a portrait-oriented or otherwise
   small photo shouldn't force a wide dialog with a mostly-empty text
   column next to it. The image sizes to its own intrinsic shape (capped so
   it always fits the viewport) and the text column has its own comfortable
   width; the two only wrap onto separate lines once they no longer fit
   side by side. */
.lightbox-content{
  position:relative;
  display:flex;
  flex-wrap:wrap;
  align-items:flex-start;     /* the details (map first) start level with the photo's top */
  justify-content:center;
  gap: var(--space-4);
  max-width:92vw;
  max-height:90vh;
}
.lightbox-image{
  position:relative;
  background: var(--bg-elevated);
  border:1px solid var(--border);
  /* No fixed aspect-ratio here: that would force a crop on any photo
     that isn't exactly that shape. Instead the box just caps how tall
     (and wide) the image can get, and the image itself always shows in
     full, at its own natural proportions. */
  max-width:min(54rem, 62vw);
  max-height: 70vh;
  display:flex; align-items:center; justify-content:center;
  overflow:hidden;
}
.lightbox-image img{ max-width:100%; max-height:70vh; width:auto; height:auto; object-fit:contain; }
/* max-width only (no fixed width): a photo with little or no location,
   description or related tracks gets a narrower column that hugs that
   little bit of text, instead of always reserving a full 22rem next to
   the photo regardless of how much is actually in it. */
.lightbox-info{ max-width:min(22rem, 85vw); max-height:70vh; overflow-y:auto; }
/* Sits in the corner of the whole dialog, not on the photo itself — kept
   just barely legible (low opacity, no background, same muted tone as the
   surrounding text) so it doesn't draw the eye. */
.lightbox-photo-id{
  position:absolute;
  right:0.1rem; bottom:-1.4rem;
  font-family: var(--font-body);
  font-size:0.68rem;
  letter-spacing:0.02em;
  color: var(--text-muted);
  opacity:0.4;
  pointer-events:none;
}
/* With no real image to size against, fall back to a fixed box so a
   missing photo still reserves a sensible, consistent amount of space. */
/* A fixed width here (not 100%) matters: 100% would resolve against
   .lightbox-content's own width, which is itself sized to fit its
   children — that circular sizing is what was making the whole dialog
   balloon out to its maximum possible size while a photo failed to load,
   instead of just reserving a normal, modest box for the missing-photo
   label. */
.lightbox-image.placeholder{ aspect-ratio: 4/5; min-height:240px; width:16rem; }
.lightbox-image.placeholder::after{
  content: attr(data-label);
  font-family: var(--font-display);
  font-style:italic;
  color: var(--text-muted);
  padding: var(--space-3);
  text-align:center;
}
.lightbox-location{
  color: var(--accent);
  font-size:0.9rem;
  margin-bottom: var(--space-2);
}
.lightbox-desc{ color: var(--text-muted); margin-bottom: var(--space-3); }
.lightbox-related-label{
  font-size:0.85rem;
  color: var(--text-muted);
  margin-bottom: var(--space-1);
}
.lightbox-track{
  display:flex;
  align-items:center;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}
.lightbox-track-title{ font-size:0.9rem; }
.lightbox-track-embed[hidden]{ display:none; }
.lightbox-track-embed{ margin-bottom: var(--space-2); }
.track-embed-missing{
  font-size:0.85rem;
  color: var(--text-muted);
  padding: var(--space-1) 0;
}
.track-preview-buttons{ display:flex; gap: var(--space-1); }
.track-preview-missing{
  font-size:0.8rem;
  color: var(--text-muted);
  white-space:nowrap;
}
.track-preview-btn, .track-link-btn{
  display:inline-flex; align-items:center; gap:0.4rem;
  border:1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text);
  font-size:0.8rem;
  line-height:1.2;
  padding:0.3rem 0.75rem 0.3rem 0.4rem;
  border-radius:999px;
  white-space:nowrap;
  text-decoration:none;
}
.track-preview-btn .brand-logo, .track-link-btn .brand-logo{ width:1.3em; height:1.3em; flex:none; }
.track-preview-btn:hover, .track-link-btn:hover{ border-color: var(--accent); color: var(--accent); }
.track-preview-btn.active{ background: var(--accent); color:#fff; border-color: var(--accent); }
/* Sits just outside the dialog's own box (which now sizes to its content,
   not to a fixed full-width panel), so it's always right at its corner
   instead of pinned to a distant corner of the screen. */
.lightbox-close{
  position:absolute; top:-2.4rem; right:-0.4rem;
  background:none; border:none; color:#fff;
  font-size:1.6rem; line-height:1;
}

/* Narrow screens (phones): photo on top, details underneath, in one
   column that never wraps into a second, off-screen column. If photo +
   details (+ the map, once opened) are taller than the screen, the
   lightbox itself scrolls, so the details are always reachable. */
@media (max-width: 720px), (orientation: portrait){
  .lightbox{
    align-items:flex-start;
    overflow-y:auto;
    overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch;
    padding-top: calc(var(--space-3) + 2.4rem);
    padding-left: var(--space-3); padding-right: var(--space-3);
    padding-bottom: 5rem;            /* room for ‹ 2 / 14 › at the bottom */
  }
  .lightbox-content{
    flex-direction:column;
    flex-wrap:nowrap;
    align-items:stretch;
    gap: var(--space-2);
    max-height:none;
    margin: auto 0;
  }
  .lightbox-image{ max-width:100%; align-self:center; }
  .lightbox-image img{ max-height:62vh; }
  .lightbox-info{ width:100%; max-width:none; max-height:none; overflow:visible; }
  .lightbox-photo-id{ position:static; display:block; text-align:right; }
}

/* The map under the photo's details in the lightbox: just the open photo's
   own point (see updateLightboxMap in photography.js). */
.lightbox-map{ margin-bottom: var(--space-2); width:100%; max-width:16rem; }
.lightbox-map[hidden]{ display:none; }
.lightbox-map .gallery-map{ box-shadow:none; }
.map-point.is-current .map-point-dot{ fill: var(--text); stroke: var(--accent); stroke-width:2px; }
.map-point.is-current .map-point-halo{ fill: var(--text); opacity:0.35; }

/* The map inside the lightbox is only a picture of where the photo was
   taken: nothing on it reacts to the pointer, except the point, which
   shows the place's name in a tooltip (setupMapTooltip in photography.js). */
.lightbox-map{ pointer-events:none; position:relative; }
.lightbox-map .map-point.is-current{ pointer-events:auto; cursor:default; }
.map-tooltip{
  position:absolute;
  transform: translate(-50%, calc(-100% - 6px));
  background: var(--text);
  color: var(--bg);
  font-size:0.75rem;
  line-height:1.2;
  padding:0.25rem 0.55rem;
  border-radius:6px;
  white-space:nowrap;
  pointer-events:none;
  box-shadow: 0 2px 8px rgba(0,0,0,0.25);
  z-index:2;
}
.map-tooltip[hidden]{ display:none; }

/* "World map" (world-view.js): every photo with a map point on one map
   that fills the window, above the page and below the lightbox. */
.filter-btn-map{ margin-left:auto; }
html.world-open{ overflow:hidden; }
.world-view{
  position:fixed; inset:0;
  z-index:45;
  display:flex; flex-direction:column;
  background: var(--bg);
}
.world-view[hidden]{ display:none; }
.world-bar{
  display:flex; flex-wrap:wrap; align-items:center;
  gap: 0.4rem var(--space-2);
  padding: 0.6rem max(var(--page-margin, 56px), calc((100% - var(--content-max-width, 1304px)) / 2));
  border-bottom:1px solid var(--border);
}
.world-title{ font-family: var(--font-display); font-weight:500; font-size:1.3rem; }
.world-hint{ font-size:0.8rem; color: var(--text-muted); }
.world-buttons{ display:flex; gap:0.4rem; margin-left:auto; }
.world-btn{
  min-width:2.2rem; height:2.2rem;
  background:none;
  border:1px solid var(--border);
  border-radius:999px;
  color: var(--text);
  font-size:1.1rem; line-height:1;
  padding:0 0.6rem;
  touch-action: manipulation;
}
.world-btn:hover{ border-color: var(--accent); color: var(--accent); }
.world-btn-text{ font-size:0.8rem; }
.world-close{ font-size:1.4rem; }
.world-box{
  position:relative;
  flex:1 1 auto;
  min-height:0;
  overflow:hidden;
  background:#302E2A;            /* the map's sea (.map-sea) */
  touch-action:none;
  cursor:grab;
  user-select:none;
}
.world-box.dragging{ cursor:grabbing; }
.world-land-layer, .world-dots-layer{ position:absolute; inset:0; width:100%; height:100%; }
.world-dots-layer{ overflow:visible; }
.world-count{
  fill: var(--bg);
  font: 600 10px var(--font-body);
  text-anchor:middle;
  dominant-baseline:central;
  pointer-events:none;
}
@media (max-width: 600px){
  .world-hint{ display:none; }
  .world-bar{ padding-left:16px; padding-right:16px; }
}

/* Behind the lightbox: the photos it steps through as halftone thumbnails —
   grey, dimmed, seen through a grid of dots — the same as "Featured"
   (featured/featured.css). The details get a dark panel to stay readable. */
.lightbox-bg{
  position:fixed; inset:0; z-index:0;
  display:grid;
  grid-template-columns: repeat(var(--cols, 6), 1fr);
  grid-template-rows: repeat(var(--rows, 4), 1fr);
}
.lightbox-tile{ position:relative; overflow:hidden; background:#141311; }
.lightbox-tile img{
  display:block; width:100%; height:100%; object-fit:cover;
  filter: var(--ht-filter, grayscale(1) contrast(1.15) brightness(0.48));   /* HALFTONE_* in constants.js */
}
.lightbox-tile::after{
  content:''; position:absolute; inset:0; pointer-events:none;
  background-image: var(--ht-screen, radial-gradient(circle, transparent 0 1.7px, rgba(20,19,17,0.7) 2.4px));
  background-size: var(--ht-spacing, 5px) var(--ht-spacing, 5px);
}
/* a veil over it: only PAGE_HALFTONE_STRENGTH shows through (--pht-veil, constants.js) */
.lightbox-bg::after{
  content:''; position:absolute; inset:0; pointer-events:none;
  background:#141311; opacity: var(--pht-veil, 0);
}
.lightbox-content{ z-index:1; }
.lightbox-info{
  background: rgba(20,19,17,0.68);   /* a little transparent: the halftone shows through */
  border-radius:10px;
  padding: var(--space-2);
}
/* "▶ Slideshow": these photos in the "Featured" page, changing by themselves */
.lightbox-slideshow{
  position:fixed; top: clamp(10px, 2vh, 20px); left: clamp(12px, 2vw, 24px); z-index:3;
  background: rgba(20,19,17,0.8); color: var(--text);
  border:1px solid var(--border); border-radius:999px;
  padding: 0.4rem 1rem;
  font-size:0.85rem;
}
.lightbox-slideshow:hover{ border-color: var(--accent); color: var(--accent); }
.lightbox-slideshow[hidden]{ display:none; }

/* Screens wider than tall (computers, tablets held sideways): a column fixed
   against the screen's right edge, built around "›" (halfway down the
   screen, like "‹" on the left): the map just above it, the words (place,
   description, tracks) just below it — nothing moves from one photo to the
   next. The photo takes all the rest of the screen, from "‹" to the column
   and from the top edge to the bottom one, as large as in the slideshow;
   "▶ Slideshow" and × sit at the top right, over the column. (Phones and
   screens taller than wide: everything underneath the photo.) */
@media (min-width: 721px) and (orientation: landscape){
  .lightbox{
    --lb-panel: min(22rem, 30vw);
    --lb-edge: clamp(12px, 2vw, 24px);
    --lb-gap: 2.4rem;                       /* from the middle of the screen to the map / the words */
    --lb-left: 5rem;                        /* room for "‹" */
    padding: var(--lb-edge) calc(var(--lb-panel) + var(--lb-edge) * 2) calc(var(--lb-edge) + 1.8rem) var(--lb-left);
  }
  .lightbox-content{ max-width:none; max-height:none; }
  .lightbox-info{ position:static; background:none; padding:0; width:auto; max-width:none; max-height:none; overflow:visible; }
  .lightbox-info .lightbox-map{
    position:fixed;
    right: var(--lb-edge);
    bottom: calc(50% + var(--lb-gap));
    width: var(--lb-panel); max-width:none;
    margin:0;
    z-index:3;
  }
  .lightbox-text{
    position:fixed;
    right: var(--lb-edge);
    top: calc(50% + var(--lb-gap));
    width: var(--lb-panel);
    max-height: calc(50% - var(--lb-gap) - var(--lb-edge));
    overflow-y:auto;
    background: rgba(20,19,17,0.68);   /* a little transparent: the halftone shows through */
    border-radius:10px;
    padding: var(--space-2);
    z-index:3;
  }
  /* the photo: as large as the space left allows */
  .lightbox-image{
    max-width: calc(100vw - var(--lb-left) - var(--lb-panel) - var(--lb-edge) * 3);
    max-height: calc(100vh - var(--lb-edge) * 2 - 1.8rem);
  }
  .lightbox-image img{
    max-width:100%;
    max-height: calc(100vh - var(--lb-edge) * 2 - 1.8rem);
  }
  /* "▶ Slideshow" and × at the top right, over the column */
  .lightbox-close{ position:fixed; top: var(--lb-edge); right: var(--lb-edge); z-index:4; }
  .lightbox-slideshow{ left:auto; right: calc(var(--lb-edge) + 2.6rem); top: var(--lb-edge); }
  /* "›" in the middle of the column; the count under the photo's space */
  .lightbox-nav{ padding-right: calc(var(--lb-edge) + (var(--lb-panel) - 3.2rem) / 2); }
  .lightbox-nav-count{ right: calc(var(--lb-panel) + var(--lb-edge) * 2); left: var(--lb-left); bottom: calc(var(--lb-edge) * 0.6); }
}

/* Under the photo (phones, screens taller than wide): when there's room,
   the map and the words side by side on one row — the map on the left. */
@media (min-width: 520px) and (max-width: 720px), (min-width: 520px) and (orientation: portrait){
  .lightbox-info{ display:flex; align-items:flex-start; gap: var(--space-2); }
  .lightbox-info .lightbox-map{ flex: 0 0 min(42%, 18rem); max-width:none; margin:0; }
  .lightbox-text{ flex:1 1 auto; min-width:0; }
}
/* The frame around the photo (also in featured/featured.css): drawn
   outside it (outline), so it neither takes room from the photo nor
   changes its proportions. */
.lightbox-image{
  border:0;
  outline: var(--photo-frame, 2px) solid var(--photo-frame-color, #D8B36E);   /* PHOTO_FRAME_SIZE / PHOTO_FRAME_COLOR in constants.js */
}

/* The photo's left and right margins: the same as in the "Featured"
   slideshow — 3% of the screen's shorter side, at least 12px (featured.js,
   targetRect). On screens wider than tall: from the left edge to the photo
   and from the photo to the column ("‹" lies over the photo's edge). */
.lightbox{ --lb-m: max(12px, 3vmin); }
@media (max-width: 720px), (orientation: portrait){
  .lightbox{ padding-left: var(--lb-m); padding-right: var(--lb-m); }
  .lightbox-image{ max-width:100%; }
}
@media (min-width: 721px) and (orientation: landscape){
  .lightbox{
    --lb-left: var(--lb-m);
    padding-left: var(--lb-m);
    padding-right: calc(var(--lb-panel) + var(--lb-edge) + var(--lb-m));
  }
  .lightbox-image{ max-width: calc(100vw - var(--lb-m) * 2 - var(--lb-panel) - var(--lb-edge)); }
  .lightbox-nav-count{ left: var(--lb-m); right: calc(var(--lb-panel) + var(--lb-edge) + var(--lb-m)); }
}

/* Phones (galleryMap 'small' in PAGE_LAYOUT): a small map on the right of
   the title and description; touching it opens a large one in a window
   (openMapDialog in photography.js), whose points open their photos. */
html[data-gallery-map="small"] .gallery-section .gallery-header.has-map{
  display:flex; flex-direction:row; align-items:flex-start;
  gap: 12px; max-width:none; padding-right:0;
}
html[data-gallery-map="small"] .gallery-header.has-map .gallery-header-text{ flex:1 1 auto; min-width:0; max-width:none; }
html[data-gallery-map="small"] .gallery-section .gallery-header.has-map .gallery-map{
  flex: 0 0 auto;
  order:2;
  width: min(38%, 9.5rem); height:auto; max-width:none;
  aspect-ratio: 4 / 3;                 /* = SMALL_MAP_ASPECT in photography.js */
  margin:0;
  cursor: zoom-in;
}
.map-dialog{ width: min(40rem, 94vw); }
.map-dialog-box{ width:100%; border-radius:10px; overflow:hidden; }
.map-dialog-box .gallery-map{ width:100%; height:100%; aspect-ratio:auto; border:0; box-shadow:none; }

/* The copyright line in the lightbox, as on the other pages (small, at the
   bottom); the count and, on phones, ‹ › sit just above it. */
.lightbox-rights{
  position:fixed; left:0; right:0; bottom:4px; z-index:3;
  text-align:center;
  font-size:0.62rem; letter-spacing:0.03em;
  color: rgba(237,232,221,0.45);
  pointer-events:none;
}
@media (min-width: 721px) and (orientation: landscape){
  .lightbox-nav-count{ bottom: calc(var(--lb-edge) * 0.6 + 0.8rem); }
  .lightbox{ padding-bottom: calc(var(--lb-edge) + 2.6rem); }
  .lightbox-image, .lightbox-image img{ max-height: calc(100vh - var(--lb-edge) * 2 - 2.6rem); }
}
@media (max-width: 720px), (orientation: portrait){
  .lightbox-nav{ bottom: 1.4rem; }
  .lightbox{ padding-bottom: 5.6rem; }
}

/* Full screen: a click or a tap on the photo in the lightbox shows it alone,
   on the whole screen, with ‹ 3 / 14 › over it (photography.js); another
   click or tap goes back. */
.lightbox-full{
  position:fixed; inset:0; z-index:10;
  background:#000;
  display:flex; align-items:center; justify-content:center;
}
.lightbox-full[hidden]{ display:none; }
.lightbox-full img{ max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain; }
.lightbox-image img{ cursor: zoom-in; }
.lightbox-full{ cursor: zoom-out; }
/* over the photo: ‹ › at the screen's edges, the count at the bottom (on phones all three at the bottom) */
.lightbox.full-open .lightbox-nav{ z-index:11; padding-left:1rem; padding-right:1rem; }
.lightbox.full-open .lightbox-nav-count{ left:0; right:0; }
.lightbox.full-open .lightbox-nav-btn{ background: rgba(20,19,17,0.55); }