/* site/assets/css/gallery.css */

/* Thumbnail size levels and their custom property, set by data-size on .gallery. */
.gallery {
  --thumb-min: 160px;
  /* Small text on white or cream: #5a553d is about 7:1, more margin than the site muted. */
  --gallery-muted: #5a553d;
}
.gallery[data-size="small"] { --thumb-min: 96px; }
.gallery[data-size="medium"] { --thumb-min: 160px; }
.gallery[data-size="large"] { --thumb-min: 260px; }

/* Toolbar: a calm cream panel with soft rounded controls and no hard edges. Fine pointers
   get the compact sizes below; touch and phone widths grow them back to 44px hit areas
   further down. Colours below are the site palette mixed with cream, checked for contrast:
   brown on the tinted track is 6.1:1, cream on the pressed fill is 5.5:1 (4.7:1 against the
   track), dark text on the chips is 11:1. */
.gallery {
  --gallery-track: #eee4d9;       /* sand at 35% over cream, the segmented control's tray */
  --gallery-hover: #e3d7cc;       /* sand at 60% over cream, hover tint */
  --gallery-chip: #f0e6dc;        /* very light sand for the jump chips */
  --gallery-pressed: #845a45;     /* soft brown for the selected segment */
  --gallery-hairline: #e7dcd2;    /* light sand divider between sections */
}

.gallery-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 32px;
  padding: 22px clamp(16px, 3vw, 32px);
  border-radius: 16px;
  background: var(--color-cream);
}

.gallery-toolbar-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.gallery-toolbar-label {
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gallery-muted);
}

/* Size and View: a lightly tinted rounded tray that holds pill buttons. */
.gallery-segmented {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--gallery-track);
}

.gallery-toolbar-button,
.gallery-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.gallery-toolbar-button {
  min-height: 27px;
  padding: 0 13px;
  background: transparent;
  color: var(--color-brown);
}

.gallery-toolbar-button:hover {
  background: var(--gallery-hover);
}

/* Pressed is a filled soft-brown pill with cream type, never colour alone.
   The weight stays the same so the buttons do not shift when toggled. */
.gallery-toolbar-button[aria-pressed="true"],
.gallery-toolbar-button[aria-pressed="true"]:hover {
  background: var(--gallery-pressed);
  color: var(--color-cream);
}

.gallery-toolbar-button:focus-visible,
.gallery-chip:focus-visible,
.gallery-summary:focus-visible,
.gallery-thumb:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .gallery-toolbar-button,
  .gallery-chip { transition: none; }
}

/* The Size group does not apply to the list view: it stays, greyed out and inert. */
.gallery[data-view="list"] .gallery-size-group { opacity: 0.4; }
.gallery-toolbar-button:disabled { cursor: default; }
.gallery-toolbar-button:disabled:hover { background: transparent; }
.gallery-toolbar-button[aria-pressed="true"]:disabled:hover { background: var(--gallery-pressed); }

/* Jump chips: soft sand pills in one row that scrolls sideways instead of wrapping. */
.gallery-jump-row {
  display: flex;
  flex: 1 1 100%;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.gallery-jump-row .gallery-toolbar-label { flex: none; }

.gallery-jump {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: nowrap;
  gap: 10px;
  overflow-x: auto;
  /* Room on every side so a focused chip's 2px ring is not clipped by the scroller. */
  padding: 4px;
  margin: 0 -4px;
  scrollbar-width: thin;
}

/* While more chips are off-screen to the right, fade the last 28px so the row reads as scrollable.
   gallery-view.js adds .has-more only in that case and removes it at the end of the row, so the
   last chip is never faded. Without JS there is no fade. */
.gallery-jump.has-more {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}

/* A chip that has keyboard focus must never sit under the fade. */
.gallery-jump.has-more:focus-within {
  -webkit-mask-image: none;
  mask-image: none;
}

.gallery-chip {
  flex: none;
  white-space: nowrap;
  min-height: 26px;
  padding: 4px 13px;
  background: var(--gallery-chip);
  color: var(--color-text);
}

.gallery-chip:hover {
  background: var(--gallery-hover);
}

/* Touch and phones: bring the 44px hit areas back. */
@media (pointer: coarse), (max-width: 640px) {
  .gallery-toolbar { padding: 18px clamp(14px, 3vw, 24px); }
  .gallery-toolbar-button { min-height: 44px; font-size: 15px; }
  .gallery-chip { min-height: 44px; padding: 0 16px; font-size: 14px; }
  .gallery-toolbar-label { font-size: 12.5px; }
}

/* Phones: drop the Size and View captions (the groups keep their aria-labels)
   and tighten the buttons so both groups share one row. */
@media (max-width: 480px) {
  .gallery-toolbar { gap: 14px 10px; padding: 16px 12px; }
  .gallery-toolbar-label { display: none; }
  .gallery-jump-row { gap: 10px; }
  .gallery-jump-row .gallery-toolbar-label { display: inline; }
  .gallery-toolbar-group { gap: 4px; }
  .gallery-toolbar-button { padding: 0 9px; }
  .gallery-chip { padding: 0 14px; }
}

/* Sections */
.gallery-section {
  padding: 0;
  scroll-margin-top: 16px;
}

.gallery-summary {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 44px;
  padding: 34px 0 18px;
  cursor: pointer;
  list-style: none;
}

.gallery-summary::-webkit-details-marker { display: none; }
.gallery-summary::marker { content: ''; }

/* Chevron: points right when closed, rotates down when open. */
.gallery-summary::before {
  content: '';
  flex: none;
  width: 8px;
  height: 8px;
  border-right: 1.5px solid var(--color-brown);
  border-bottom: 1.5px solid var(--color-brown);
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}

.gallery-section[open] > .gallery-summary::before { transform: rotate(45deg); }

@media (prefers-reduced-motion: reduce) {
  .gallery-summary::before { transition: none; }
}

/* Section headings: FM Medium Italic, kept modest so they do not shout over the photos. */
.gallery-heading {
  margin: 0;
  font-weight: 500;
  font-style: italic;
  font-size: clamp(22px, 2vw, 28px);
  line-height: 1.15;
  text-align: left;
  color: var(--color-text);
}

.gallery-count {
  font-weight: 300;
  font-style: normal;
  font-size: 0.55em;
  letter-spacing: 0.08em;
  color: var(--gallery-muted);
}

/* The sentence under the page title: light italic, muted. */
.gallery-intro {
  max-width: 620px;
  margin: 26px auto 0;
  font-weight: 300;
  font-style: italic;
  font-size: clamp(18px, 2.2vw, 21px);
  line-height: 1.5;
  color: var(--gallery-muted);
  text-wrap: balance;
}

/* A one-line description under a section heading, then the credit line below it. */
.gallery-desc {
  margin: -8px 0 4px;
  font-size: 16px;
  line-height: 1.4;
  text-align: left;
  color: var(--color-text);
}

.gallery-desc + .gallery-credit { margin-top: 0; }

/* Photographer credit under a section heading: small, light, quiet. */
.gallery-credit {
  margin: -8px 0 16px;
  font-weight: 300;
  font-style: italic;
  font-size: 15px;
  line-height: 1.4;
  text-align: left;
  color: var(--gallery-muted);
}

/* Each section's grid skips layout and paint work while it is off screen (content-visibility:
   auto), so an open section far down the page costs nothing until it is scrolled near. Every
   photo link stays in the DOM, so the lightbox order and keyboard focus are unchanged.
   Paint containment clips to the box, so the 4px of padding (cancelled by the negative margin)
   keeps the thumbnails' focus rings from being cut off at the edges. While skipped the grid
   reserves --count times a per-photo height estimate (below), and once it has been drawn the
   browser remembers its real height ("auto"). */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--thumb-min), 1fr));
  gap: 8px;
  padding: 4px 4px 32px;
  margin: -4px -4px 0;
  content-visibility: auto;
  contain-intrinsic-block-size: auto calc(var(--count, 100) * var(--photo-h));
}

/* gallery.js sets this for a moment when it scrolls to a far-away thumbnail (closing the
   lightbox on a photo reached by the arrows), so the scroll uses real heights, not estimates. */
.gallery.is-measuring .gallery-grid { content-visibility: visible; }

/* Average height one photo adds to a section, for the reserved space above. Measured on a real
   1,251 photo gallery (a grid's height divided by its photo count, padding included) at desktop,
   tablet and phone widths. A list row is always 57px. Only the first draw of a far-off grid
   uses these numbers, after that the browser remembers the real height. */
.gallery { --photo-h: 27px; }
.gallery[data-size="small"] { --photo-h: 9.5px; }
.gallery[data-size="large"] { --photo-h: 82px; }
@media (max-width: 1100px) {
  .gallery { --photo-h: 36px; }
  .gallery[data-size="small"] { --photo-h: 14px; }
  .gallery[data-size="large"] { --photo-h: 98px; }
}
@media (max-width: 700px) {
  .gallery { --photo-h: 92px; }
  .gallery[data-size="small"] { --photo-h: 41px; }
  .gallery[data-size="large"] { --photo-h: 366px; }
}
.gallery[data-view="list"] { --photo-h: 57px; }

.gallery-thumb {
  background: var(--color-sand);
}

.gallery-thumb img {
  width: 100%;
  height: auto; /* the height attribute is only there to reserve space; aspect-ratio sets the real height */
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* The row label only exists in the list view. */
.gallery-thumb-label { display: none; }

/* List view: one compact row per photo, the whole row is the link. */
.gallery[data-view="list"] .gallery-grid {
  display: block;
  padding-bottom: 16px;
}

.gallery[data-view="list"] .gallery-thumb {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 56px;
  padding: 0;
  border-bottom: 1px solid var(--gallery-hairline);
  background: none;
  color: var(--color-text);
  text-decoration: none;
}

.gallery[data-view="list"] .gallery-thumb:last-child { border-bottom: none; }

.gallery[data-view="list"] .gallery-thumb:hover .gallery-thumb-label {
  color: var(--color-brown);
}

.gallery[data-view="list"] .gallery-thumb img {
  flex: none;
  width: 56px;
  height: 56px;
  aspect-ratio: auto;
  object-fit: cover;
}

.gallery[data-view="list"] .gallery-thumb-label {
  display: block;
  font-family: var(--font-body);
  font-size: 18px;
}

.gallery-empty {
  text-align: center;
  color: var(--gallery-muted);
  padding: 64px 0;
}

.lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.92);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 24px;
}

.lightbox-overlay.is-open { display: flex; }

.lightbox-image {
  max-width: 100%;
  /* Short of the full height, because the strip of neighbours sits under it. */
  max-height: 64vh;
  object-fit: contain;
}

.lightbox-close {
  position: absolute;
  top: 16px;
  right: 24px;
  background: none;
  border: none;
  color: #fff;
  font-size: 32px;
  padding: 6px 10px;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
}

.lightbox-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
  margin-top: 16px;
}

.lightbox-actions a,
.lightbox-actions button {
  color: #fff;
  font-family: var(--font-body);
  font-size: 1rem;
  text-decoration: underline;
}

.lightbox-actions button {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.lightbox-actions [hidden] { display: none; }

.lightbox-message {
  min-height: 1.5em;
  margin-top: 8px;
  color: #fff;
  font-family: var(--font-body);
  text-align: center;
}

.lightbox-actions button:disabled {
  opacity: 0.6;
  cursor: default;
}

/* Lightbox navigation */
.lightbox-overlay { touch-action: pan-y pinch-zoom; }

.lightbox-stage {
  position: relative;
  align-self: stretch;
  display: flex;
  justify-content: center;
}

.lightbox-stage .lightbox-image { min-width: 0; }

.lightbox-counter {
  position: absolute;
  top: 24px;
  left: 24px;
  margin: 0;
  color: #fff;
  font-family: var(--font-body);
  font-size: 1rem;
}

.lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  cursor: pointer;
}

.lightbox-prev { left: 8px; }
.lightbox-next { right: 8px; }

.lightbox-nav svg {
  pointer-events: none;
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.lightbox-nav:hover:not(:disabled) { background: rgba(0, 0, 0, 0.8); }

.lightbox-nav:focus-visible,
.lightbox-close:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 2px;
  box-shadow: 0 0 0 2px #000; /* dark ring keeps the focus visible over bright photos */
}

.lightbox-nav:disabled {
  opacity: 0.3;
  cursor: default;
}

/* The strip of neighbours under the photo: the two either side, the current one ringed. Small
   enough not to crowd the Hide button below it or the close button above, and it is the gallery's
   own thumbnails, so it costs no new download. */
.lightbox-strip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  gap: 8px;
  margin-top: 14px;
  padding: 4px;
}

.lightbox-strip[hidden] { display: none; }

.lightbox-strip-item {
  position: relative;
  flex: none;
  width: 72px;
  height: 72px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.12);
  cursor: pointer;
  overflow: hidden;
  opacity: 0.65;
  transition: opacity 0.15s ease;
}

.lightbox-strip-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.lightbox-strip-item:hover { opacity: 1; }

/* The photo on screen: fully lit and ringed, so the eye finds its place in the run at a glance. */
.lightbox-strip-item.is-current {
  opacity: 1;
  box-shadow: 0 0 0 3px #fff;
}

.lightbox-strip-item:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .lightbox-strip-item { transition: none; }
}

/* Phones: five 44px thumbs across one row, clear of the Hide button and the close button. */
@media (max-width: 640px) {
  .lightbox-strip { gap: 6px; margin-top: 10px; }
  .lightbox-strip-item { width: 44px; height: 44px; }
  .lightbox-image { max-height: 52vh; }
}

/* Viewing or Curating: a segmented control in the same family as Size and View. Switching it
   swaps the sections in place, so it is a pair of buttons, never a link to another page. */
/* The status line is for screen readers only: the pressed segment already says which mode is on,
   so an extra sentence in the toolbar would be noise on screen. It has to stay in the layout,
   never display:none, or it would not be announced. */
.gallery-mode-status {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  white-space: nowrap;
  clip-path: inset(50%);
}

/* Said out loud only when the curator cannot be reached. */
.gallery-mode-notice {
  flex: 1 1 100%;
  margin: 0;
  font-family: var(--font-body);
  font-size: 14px;
  font-style: italic;
  color: var(--color-brown);
}

.gallery-mode-notice[hidden] { display: none; }

/* The toolbar sits close under the header band, at the panel rhythm. */
.gallery .page-head { margin-bottom: 16px; }

/* On a phone the header stays at the top, so jump targets land below it. */
@media (max-width: 899.98px) {
  .gallery-section { scroll-margin-top: 72px; }
}

/* Phones: a compact toolbar. The pills are 34px tall with a little air between them, the small
   sizes keep the bar to about three short rows, and the jump chips are slim. */
@media (max-width: 640px) {
  .gallery-toolbar { gap: 10px 8px; padding: 12px 10px; border-radius: 14px; }
  .gallery-toolbar-group { gap: 4px; }
  .gallery-segmented { padding: 2px; gap: 1px; }
  .gallery-toolbar-button { min-height: 32px; padding: 0 11px; font-size: 13px; }
  .gallery-chip { min-height: 32px; padding: 0 12px; font-size: 13px; }
  .gallery-jump-row { gap: 8px; }
  .gallery-jump { gap: 6px; }
  .gallery-jump-row .gallery-toolbar-label { font-size: 10.5px; letter-spacing: 0.14em; }
  .gallery-toolbar-label { font-size: 10.5px; }
}

/* A list row is a fixed, light box, so the list never skips its layout: it is never left blank. */
.gallery[data-view="list"] .gallery-grid { content-visibility: visible; }

/* A small spinner in the toolbar while the gallery switches view, size or mode. */
.gallery-toolbar { position: relative; }

.gallery.is-loading .gallery-toolbar::after {
  content: '';
  position: absolute;
  top: 14px;
  right: 18px;
  width: 20px;
  height: 20px;
  border: 2px solid rgba(116, 72, 54, 0.25);
  border-top-color: var(--color-brown);
  border-radius: 50%;
  animation: gallery-spin 0.7s linear infinite;
}

@keyframes gallery-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .gallery.is-loading .gallery-toolbar::after { animation-duration: 2.4s; }
}

/* The Gallery's header band carries a low contrast ghost of the courtyard, like the other pages. */
.gallery .page-head {
  --page-ghost: url('../img/pages/gallery-header.jpg');
  --page-ghost-pos: center 62%;
}
