/* ============================================================
   OZYDE — Dress decks
   ============================================================
   One dress = one card. A dress is rarely one photograph, so the card
   carries its whole shoot as a fanned deck: the hero flat on top, the
   rest angled out behind it like a hand of cards. Resting state hints
   there is more to see; hover/focus opens the fan; clicking opens the
   full deck in the lightbox.

   Everything is driven by --i (0-based card index, set inline on each
   card) so the fan geometry is one formula rather than nth-child rules,
   and a deck of two behaves like a deck of five without extra CSS.

   NOTE ON STACKING ORDER: the hero is LAST in the DOM so it paints on
   top without z-index juggling; the fan therefore reads right-to-left
   in source order. See --fan-dir if that ever needs flipping.
   ============================================================ */

.deck-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: clamp(28px, 3.4vw, 46px) clamp(20px, 2.6vw, 34px);
  padding-bottom: 96px;
}

/* GEOMETRY IS BUDGETED AGAINST THE GRID GAP, NOT PICKED BY EYE.
   The cards rotate about their bottom edge, so the top corner swings out by
   roughly cardHeight x sin(angle) — with four cards that term dominates the
   translate, and the first values tried here (3.4deg / 4.5%) threw the top
   corner about 100px past the card and straight over the next dress in the
   row. At rest the whole splay must fit inside .deck__fan's right margin;
   only the hover state is allowed past it, and only because it also lifts
   the deck above its neighbours. Re-check both if FAN_MAX ever changes. */
.deck {
  --fan-angle: 2.2deg;   /* per-card rotation at rest */
  --fan-shift: 3.4%;     /* per-card horizontal offset at rest */
  --fan-dir: 1;          /* 1 fans right, -1 fans left */
  --lift: 0px;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.deck.is-hidden { display: none; }

/* The fan itself. Generous right-hand padding so the angled cards have
   somewhere to go without being clipped by the grid cell or triggering
   a horizontal scrollbar on the page. */
.deck__fan {
  position: relative;
  aspect-ratio: 3 / 4;
  margin-right: 22%;
  cursor: pointer;
  isolation: isolate;
}

.deck__card {
  position: absolute;
  inset: 0;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--cream-deep);
  transform-origin: 50% 100%;
  transform:
    translateX(calc(var(--i) * var(--fan-shift) * var(--fan-dir)))
    rotate(calc(var(--i) * var(--fan-angle) * var(--fan-dir)))
    translateY(var(--lift));
  transition:
    transform var(--dur-med) var(--ease),
    box-shadow var(--dur-med) var(--ease);
  box-shadow: 0 6px 20px rgba(26, 21, 18, 0.13), 0 0 0 1px rgba(251, 245, 234, 0.9) inset;
  will-change: transform;
}

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

/* Cards behind the hero are dimmed so the lead image stays the subject
   rather than competing with four near-identical frames. */
.deck__card:not(.is-hero)::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(26, 21, 18, 0.28);
  transition: background var(--dur-med) var(--ease);
}

.deck__card.is-hero {
  box-shadow: var(--shadow-card), 0 0 0 1px rgba(251, 245, 234, 0.9) inset;
}

/* ---- Open the fan ---------------------------------------------------
   Hover, keyboard focus and an .is-open class (used on touch, where
   there is no hover) all drive the same widened geometry. */
.deck__fan:hover,
.deck__fan:focus-visible,
.deck__fan.is-open {
  --fan-angle: 5.4deg;
  --fan-shift: 8.5%;
  --lift: -6px;
}

/* An opened fan is wider than the space budgeted for it, so it has to sit
   above the dresses either side rather than slide under them. Grid items
   paint in DOM order, which alone would let every later deck cover this one. */
.deck:has(.deck__fan:hover),
.deck:has(.deck__fan:focus-visible) { z-index: 2; }

.deck__fan:hover .deck__card:not(.is-hero)::after,
.deck__fan:focus-visible .deck__card:not(.is-hero)::after,
.deck__fan.is-open .deck__card:not(.is-hero)::after {
  background: rgba(26, 21, 18, 0.1);
}

.deck__fan:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 6px;
  border-radius: var(--r-md);
}

/* ---- Count chip -----------------------------------------------------
   Sits on the hero and says how many photographs are behind it, so the
   fan is legible as "there are more" even before anyone hovers. */
.deck__count {
  position: absolute;
  right: 10px;
  bottom: 10px;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  border-radius: var(--r-pill);
  background: rgba(11, 9, 6, 0.62);
  backdrop-filter: blur(6px);
  color: var(--cream);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  pointer-events: none;
}

.deck__count svg { width: 12px; height: 12px; stroke-width: 1.8; }

/* ---- Caption --------------------------------------------------------- */
.deck__meta { display: flex; flex-direction: column; gap: 5px; }

.deck__name {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--ink);
}

.deck__blurb {
  font-size: 13px;
  line-height: 1.55;
  opacity: 0.66;
  max-width: 34ch;
}

.deck__tags {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 3px;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.5;
}

.deck__tags span:not(:last-child)::after {
  content: '·';
  margin-left: 8px;
  opacity: 0.6;
}

/* ---- Booking ---------------------------------------------------------
   Every card carries a "Book a fitting" button (added by gallery.js) and the
   one-line reason it is a fitting rather than this exact dress. The button is
   the site's own .btn-outline scaled down to sit under a caption; the note is
   deliberately quiet, since it is fine print and not a second headline. */
.deck__book {
  align-self: flex-start;
  margin-top: 8px;
  padding: 10px 18px;
  font-size: 11px;
  letter-spacing: 0.08em;
}

.deck__note {
  margin-top: 2px;
  font-size: 11px;
  line-height: 1.5;
  opacity: 0.55;
  max-width: 34ch;
}

/* The grid stays empty until the studio's catalogue has answered (see
   buildDecks in gallery.js) so a hidden dress is never painted and then taken
   back. Say so rather than leave a blank panel. */
.deck-grid[aria-busy='true']::before {
  content: 'Loading the wardrobe\2026';
  grid-column: 1 / -1;
  font-size: 13px;
  opacity: 0.55;
}

/* ---- Price ----------------------------------------------------------- */
.deck__price {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--gold-deep);
}

/* ---- Responsive ------------------------------------------------------
   The fan is the first thing to go on a narrow screen: two decks side by
   side leave no room to splay cards without them overlapping each other's
   captions. Tighten the geometry rather than dropping the effect. */
@media (max-width: 900px) {
  .deck-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
  .deck { --fan-angle: 1.8deg; --fan-shift: 2.8%; }
  .deck__fan { margin-right: 18%; }
  .deck__fan:hover, .deck__fan:focus-visible, .deck__fan.is-open {
    --fan-angle: 4.2deg; --fan-shift: 7%;
  }
}

@media (max-width: 560px) {
  .deck-grid { grid-template-columns: repeat(2, 1fr); gap: 26px 14px; }
  .deck__name { font-size: 16px; }
  .deck__blurb { display: none; }
  .deck__fan { margin-right: 16%; }
  /* Two columns leave a card about 150px: fill it, and let the label wrap
     rather than overflow on the narrowest phones. */
  .deck__book {
    align-self: stretch;
    padding: 10px 8px;
    font-size: 10.5px;
    letter-spacing: 0.06em;
    line-height: 1.25;
    text-align: center;
    white-space: normal;
  }
}

/* Someone who has asked for less motion still gets the fan — it is
   information, not decoration — but it stops animating between states. */
@media (prefers-reduced-motion: reduce) {
  .deck__card { transition: none; will-change: auto; }
}

/* ============================================================
   Deck lightbox — walking one dress's photographs
   ============================================================
   The existing .lightbox shows a single photo. A deck needs prev/next
   within the dress and a strip showing where you are, so it reuses the
   overlay and adds its own furniture. */

.lb-deck-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 4;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  color: var(--cream);
  background: rgba(251, 245, 234, 0.14);
  backdrop-filter: blur(8px);
  transition: background var(--dur-fast) var(--ease);
}

.lb-deck-nav:hover { background: rgba(251, 245, 234, 0.26); }
.lb-deck-nav svg { width: 21px; height: 21px; stroke-width: 2; }
.lb-deck-prev { left: clamp(8px, 3vw, 34px); }
.lb-deck-next { right: clamp(8px, 3vw, 34px); }
.lb-deck-nav[hidden] { display: none; }

/* Thumbnail strip under the enlarged photo. */
.lb-strip {
  display: flex;
  gap: 7px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 14px;
  max-width: 560px;
  margin-inline: auto;
}

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

.lb-strip button {
  width: 40px;
  height: 53px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  opacity: 0.42;
  background: none;
  transition: opacity var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.lb-strip button img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lb-strip button:hover { opacity: 0.75; }
.lb-strip button.is-current {
  opacity: 1;
  box-shadow: 0 0 0 2px var(--gold);
}

@media (max-width: 560px) {
  .lb-strip button { width: 32px; height: 43px; }
  .lb-deck-nav { width: 38px; height: 38px; }
}

/* ---- Disclaimer in the lightbox and the video viewer ------------------
   The same sentence as on each card, under the caption row that carries the
   booking link. Both overlays were sized without it, so each gives up a little
   height to keep the whole thing on screen. */
.lb-note,
.vv-note {
  color: var(--cream);
  font-size: 11.5px;
  line-height: 1.5;
  opacity: 0.6;
}

.lightbox-inner .lightbox-media,
.lightbox-inner .lightbox-media img { max-height: calc(74vh - 40px); }

/* On a short phone the photo is the part that gives: it is the only piece of
   the lightbox that can shrink. Without this the top of the photo and the
   second row of thumbnails are cut off. */
@media (max-width: 560px) {
  .lightbox-inner .lightbox-media,
  .lightbox-inner .lightbox-media img { max-height: calc(100vh - 290px); }
}

/* Same overhang as .vv-caption above it, so a narrow frame does not squeeze
   the sentence into a tall column. */
.vv-note {
  align-self: center;
  width: max(100%, 260px);
}

/* --vv-chrome (components.css) is the vertical budget for the caption row.
   The note needs room of its own, restated at the same three breakpoints in
   the same order: this file loads after components.css, so a bare override
   would win at every width. */
.video-viewer { --vv-chrome: 186px; }

@media (max-width: 720px) {
  .video-viewer { --vv-chrome: 202px; }
}

@media (max-height: 560px) {
  .video-viewer { --vv-chrome: 140px; }
  .vv-note { width: min(92vw, 520px); font-size: 10.5px; }
}
