/* ============================================================
   gallery.css — Met-style dense, equal-column works grid
   Owns the .gallery* classes only. Reads tokens from base.css.
   Style: a uniform responsive grid of cards. Each card is a real
   link: the work shown in full (object-fit: contain) inside a fixed
   media area, then left-aligned captions below — Title (serif, as a
   link), the artist "Natasha", and the Year. Keeps our luxe air:
   warm surface behind the art, a hairline frame that warms to gold,
   restrained hover.
   ============================================================ */

/* ---- Wrapper reset ---------------------------------------- */
.gallery__grid,
.gallery__card {
  margin: 0;
}

/* ---- Grid ------------------------------------------------- */
/* Equal columns via auto-fill/minmax: ~4 on desktop, 3 on tablet,
   2 on narrow, 1 on the very narrowest. Moderate, Met-like gutters
   with a touch more air. */
.gallery__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* Column gutters as before; rows get ~10px extra air between them. */
  column-gap: clamp(var(--space-3), 2.5vw, var(--space-4));
  row-gap: calc(clamp(var(--space-3), 2.5vw, var(--space-4)) + 10px);
  margin-inline: auto;
}
/* 2 columns on tablet, 1 on the narrowest, so images stay legible. */
@media (max-width: 760px) {
  .gallery__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 460px) {
  .gallery__grid { grid-template-columns: 1fr; }
}

/* ---- Card (a real link) ----------------------------------- */
.gallery__card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 0;
  text-align: left;
  text-decoration: none;
  color: inherit;
}

/* Fixed media area: the work is shown in FULL (contain), never cropped.
   A warm surface fills any letterboxing so the frame reads cleanly. */
.gallery__media {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--surface);
  /* Landscape thumbnail, capped at 470×350 (ratio kept as width scales);
     the work fits inside by both width and height (contain), centred. */
  width: 100%;
  max-width: 470px;
  aspect-ratio: 470 / 350;
  display: flex;
  align-items: center;
  justify-content: center;
  /* No inner mat, no border on the thumbnail. */
  transition: box-shadow var(--transition);
}

.gallery__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
  transition: opacity var(--transition);
}
.gallery__media picture { display: contents; }

/* ---- Caption block below the work (left-aligned, Met-style) ---- */
.gallery__info {
  display: flex;
  flex-direction: column;
  gap: 0.15em;
  margin-top: var(--space-2);
  padding: 0;
}

/* Title: serif, styled like a link — turns gold on card hover/focus. */
.gallery__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-0);
  line-height: 1.3;
  color: var(--text);
  transition: color var(--transition);
  /* A touch more air between the title and the year line. */
  margin-bottom: 3px;
}

.gallery__artist {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--text-muted);
  line-height: 1.4;
}

.gallery__year,
.gallery__medium {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--text-muted);
  line-height: 1.4;
}

/* ---- Hover / focus reveal --------------------------------- */
.gallery__card:hover .gallery__media,
.gallery__card:focus-visible .gallery__media {
  box-shadow: var(--shadow);
}
.gallery__card:hover .gallery__title,
.gallery__card:focus-visible .gallery__title {
  color: var(--accent);
}
/* Keyboard focus ring on the card itself (thumbnail stays borderless). */
.gallery__card:focus-visible {
  outline: 2px solid var(--focus, var(--accent));
  outline-offset: 4px;
  border-radius: var(--radius);
}

/* ---- Empty & failure states ------------------------------- */
.gallery__empty,
.gallery__error {
  margin: 0;
  padding: var(--space-6) var(--space-3);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--step-1);
  font-family: var(--font-display);
  font-style: italic;
}

/* ---- Scroll-reveal (classes toggled by reveal.js) --------- */
.gallery__card.is-reveal-pending {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 800ms cubic-bezier(0.22, 0.61, 0.36, 1),
              transform 800ms cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: opacity, transform;
}
.gallery__card.is-reveal-in {
  opacity: 1;
  transform: none;
}

/* Respect reduced-motion: no reveal animation, shown immediately. */
@media (prefers-reduced-motion: reduce) {
  .gallery__card.is-reveal-pending {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .gallery__media img { transition: none; }
}

/* ============================================================
   Featured carousel — a horizontal lane of work cards, styled
   after the detail page's "More works" (4-up + a peeking 5th,
   arrows, scroll-snap, hidden scrollbar). Used by home blocks of
   type "carousel". Cards link to piece.html#<id>. Self-contained
   so it works wherever gallery.css is loaded (index / listings).
   ============================================================ */
.carousel__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  /* "Selected works" sits ~18px lower; margin-bottom drops by the same amount
     so the head's total footprint (and the one-screen Home fit) is unchanged. */
  margin-top: 18px;
  margin-bottom: 22px;
}
.carousel__heading { min-width: 0; }
.carousel__heading .section__eyebrow { margin-bottom: var(--space-1); }
.carousel__heading .section__title { font-size: var(--step-3); margin: 0; }

/* "View all →" link — top-right of the carousel head. */
.carousel__viewall {
  align-self: flex-end;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--font-sans);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--transition);
}
.carousel__viewall:hover,
.carousel__viewall:focus-visible { color: var(--accent); }
.carousel__viewall:focus-visible { outline: 2px solid var(--focus, var(--accent)); outline-offset: 3px; border-radius: 2px; }
.carousel__viewall-arrow { transition: transform var(--transition); }
.carousel__viewall:hover .carousel__viewall-arrow,
.carousel__viewall:focus-visible .carousel__viewall-arrow { transform: translateX(3px); }

/* Full-bleed viewport: the track runs to the RIGHT screen edge while the
   first card lines up with the page content on the left; scrolling right
   lets the lane reach the LEFT screen edge. --gutter = the page's left
   content offset (matches .container). Arrows overlay the images and appear
   on hover (Met "Collection Highlights" style). */
.carousel__viewport {
  --gutter: calc((100% - min(100%, var(--maxw))) / 2 + var(--space-4));
  position: relative;
}
.carousel__arrow {
  position: absolute;
  top: 210px;                 /* vertical centre of the 420px image row */
  transform: translateY(-50%);
  z-index: 2;
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  line-height: 1;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--text);
  cursor: pointer;
  opacity: 0;                 /* revealed on hover / focus */
  box-shadow: var(--shadow);
  transition: opacity var(--transition), border-color var(--transition), color var(--transition), background var(--transition);
}
.carousel__arrow--prev { left: calc(var(--gutter) - 24px); }
.carousel__arrow--next { right: 24px; }
.carousel__viewport:hover .carousel__arrow:not(:disabled) { opacity: 1; }
.carousel__arrow:hover:not(:disabled) { border-color: var(--gold-line); color: var(--accent); }
/* When you can't scroll that way, hide the arrow entirely (Met hides the
   left arrow until you scroll). */
.carousel__arrow:disabled { opacity: 0; pointer-events: none; }
.carousel__arrow:focus-visible { opacity: 1; outline: 2px solid var(--focus, var(--accent)); outline-offset: 2px; }
@media (hover: none) {
  /* Touch devices: no hover — keep the arrows visible. */
  .carousel__arrow:not(:disabled) { opacity: 1; }
}

/* Track: horizontal, free-scroll (no snap, so the lane can reach the left
   screen edge), natively scrollable/draggable. Left/right padding = the
   content gutter: the first card aligns with the page on the left, and the
   FINAL scroll docks the last card to the page grid on the right (mid-scroll
   the lane still bleeds off the right screen edge). */
.carousel__track {
  list-style: none;
  margin: 0;
  padding: 0 var(--gutter) var(--space-2) var(--gutter);
  display: flex;
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: none;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none; /* no visible scrollbar — navigate via arrows / swipe */
}
.carousel__track::-webkit-scrollbar { display: none; }
.carousel__item {
  /* Width follows each work's proportion (see .carousel__media). */
  flex: 0 0 auto;
  scroll-snap-align: start;
}

.carousel__card {
  display: flex;
  flex-direction: column;
  width: max-content;      /* hug the image so the card is as wide as it is */
  text-decoration: none;
  color: inherit;
}
/* Fixed 420px tall; width follows the image's aspect ratio. The image fills
   the container completely at its natural proportion — no letterbox, no crop. */
.carousel__media {
  height: 420px;
  width: auto;
  background: var(--surface);
  border-radius: var(--radius);
  overflow: hidden;
  display: block;
  transition: box-shadow var(--transition);
}
.carousel__img { height: 420px; width: auto; display: block; }
.carousel__card-title {
  font-family: var(--font-display);
  font-size: var(--step-0);
  line-height: 1.3;
  margin-top: var(--space-2);
  /* A touch more air between the title and the year line. */
  margin-bottom: 3px;
  color: var(--text);
  transition: color var(--transition);
}
.carousel__card-meta {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--text-muted);
  line-height: 1.4;
}
.carousel__card:hover .carousel__media,
.carousel__card:focus-visible .carousel__media { box-shadow: var(--shadow); }
.carousel__card:hover .carousel__card-title,
.carousel__card:focus-visible .carousel__card-title { color: var(--accent); }
.carousel__card:focus-visible {
  outline: 2px solid var(--focus, var(--accent));
  outline-offset: 4px;
  border-radius: var(--radius);
}
@media (prefers-reduced-motion: reduce) {
  .carousel__track { scroll-behavior: auto; }
}

/* ---- Home: fit the whole page (header + carousel + footer) in one
   viewport on desktops and tablets, so the footer is always visible
   without scrolling — WITHOUT shrinking the header, footer or the 420px
   carousel. Only the section's vertical padding flexes: generous on tall
   screens (up to the normal 9rem), shrinking toward 0 as the screen gets
   shorter.

   The fixed vertical budget around the padding is ~780px (header ~73 +
   footer ~103 + carousel head+gap ~80 + media 420 + caption ~76 + track
   pad ~16 + slack). So the space left for BOTH paddings is (100vh − 780);
   each side gets half of that, clamped to [0, 9rem]. Below 768px width
   (phones) the normal 9rem padding applies and the page may scroll. ----- */
@media (min-width: 768px) {
  .section.carousel {
    padding-block: clamp(1rem, calc((100vh - 730px) / 2), var(--space-7));
  }
}
