/* ==========================================================================
   FEATURES — photo plates, strips, showcase bands, date, entourage
   ========================================================================== */

/* ---------------------------------------------------------- PHOTO PLATES */
/* Every image slot on the site. The box has size before any file loads, so
   nothing collapses and a missing photo still reads as a frame. */
.plate {
  position: relative;
  overflow: hidden;
  background:
    repeating-linear-gradient(135deg,
      rgba(168,184,165,0.18) 0 14px, rgba(201,183,141,0.13) 14px 28px),
    linear-gradient(150deg, var(--beige-deep), #D8D0C0);
}
.plate::after {
  content: attr(data-ph);
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  text-align: center;
  padding: 1rem;
  font-size: var(--fs-mono);
  text-transform: uppercase;
  letter-spacing: var(--track-mid);
  color: rgba(46, 46, 46, 0.42);
  transition: opacity 0.6s var(--ease-silk);
}
.plate.is-loaded::after { opacity: 0; }
.plate > img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Visible by default. This used to start at opacity 0 and wait for a class
     added by JS, which meant any hiccup in the scripts left a perfectly good
     photograph invisible behind its placeholder. The fade is an animation
     now, so it needs nothing but CSS to finish. */
  opacity: 1;
  animation: plateIn 0.9s var(--ease-silk) both;
  transition: transform 1.2s var(--ease-silk);
}
@keyframes plateIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* Only a genuine load failure hides the image and shows the label instead. */
.plate.is-broken > img { display: none; }

/* Parallax images need overscan or the shift would expose the frame behind
   them. The offset lands in --py so a zoom can compose with it. */
.plate > img[data-parallax-y] {
  height: 124%;
  margin-top: -12%;
  transform: translate3d(0, var(--py, 0px), 0);
  transition: none;
  will-change: transform;
}

/* -------------------------------------------------- FULL-WIDTH SHOWCASE */
/* One landscape photograph, edge to edge. */
.showcase {
  position: relative;
  z-index: 1;
  width: 100%;
  overflow: hidden;
}
.showcase__frame {
  aspect-ratio: 21 / 9;
  min-height: 220px;
}
.showcase__frame > img { transform: none; }

@media (max-width: 640px) {
  .showcase__frame { aspect-ratio: 4 / 3; }
}

/* -------------------------------------------------------------- RIBBON */
/* A slow band of repeating type. Same rAF engine as the photo strip. */
.ribbon {
  position: relative;
  overflow: hidden;
  padding-block: clamp(0.7rem, 1.6vw, 1.1rem);
  border-block: 1px solid var(--line);
}
.ribbon__track {
  display: flex;
  align-items: center;
  width: max-content;
  will-change: transform;
}
.ribbon__unit {
  display: inline-flex;
  align-items: center;
  gap: clamp(1.1rem, 3vw, 2.4rem);
  padding-inline: clamp(0.55rem, 1.5vw, 1.2rem);
  font-family: var(--font-body);
  font-size: clamp(0.6rem, 0.55rem + 0.2vw, 0.7rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  color: var(--ink-soft);
  white-space: nowrap;
}
.ribbon__unit i {
  font-style: normal;
  font-size: 0.5em;
  color: var(--gold);
  text-indent: 0;
}

/* ---------------------------------------------------------- PHOTO STRIPS */
/* One row. Portrait and landscape share a row height and keep their own
   proportions, so the two orientations sit together without cropping. */
.strips {
  position: relative;
  z-index: 1;
  padding-block: clamp(2rem, 1.4rem + 3vw, 3.6rem);
  overflow: hidden;
}

.ribbon + .strip { margin-top: clamp(1.2rem, 3vw, 2.2rem); }

.strip {
  position: relative;
  overflow: hidden;
  --row: clamp(190px, 11rem + 16vw, 360px);
}

/* Feather the ends so photos dissolve instead of getting guillotined */
.strips::before,
.strips::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: clamp(28px, 8vw, 140px);
  z-index: 2;
  pointer-events: none;
}
.strips::before { left: 0;  background: linear-gradient(90deg, var(--beige), transparent); }
.strips::after  { right: 0; background: linear-gradient(270deg, var(--beige), transparent); }

.strip__track {
  display: flex;
  align-items: stretch;
  gap: 4px;                 /* a seam, not a margin */
  width: max-content;
  will-change: transform;
}

/* Flat by design: no shadow, no lift, no hover zoom. The strip reads as a
   band of photographs lying on the page, not as cards floating above it. */
.strip__item {
  flex: none;
  height: var(--row);
  border-radius: 2px;
  transition: opacity 0.5s var(--ease-silk);
}
.strip__item--landscape { width: calc(var(--row) * 1.5); }   /* 3:2 */
/* Kept available: swap the class on any figure to mix a portrait back in. */
.strip__item--portrait  { width: calc(var(--row) * 0.75); }  /* 3:4 */

.strip__item:hover { opacity: 0.88; }
.strip__item > img { transition: opacity 0.9s var(--ease-silk); }

@media (prefers-reduced-motion: reduce) {
  .clock__num.is-swap { opacity: 1; }
  .strip__track { flex-wrap: wrap; width: auto; justify-content: center; }
  .strip__item[aria-hidden="true"] { display: none; }
}

/* ============================================================ DATE PLATE */
/* Minimal: no panel, no border, no glass. Type and air only. */
.countdown {
  position: relative;
  z-index: 1;
  padding-block: clamp(4rem, 2.5rem + 6vw, 7rem);
  text-align: center;
  overflow: hidden;
}

#confetti {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

.dateline {
  position: relative;
  z-index: 2;
  max-width: 40rem;
  margin-inline: auto;
}

.dateline__date {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2.1rem, 1.2rem + 4.2vw, 4.2rem);
  line-height: 1.05;
  letter-spacing: -0.015em;
  margin: 0;
}

/* The clock: four numbers on one line, hairline colons, tiny labels. */
.clock {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(0.5rem, 2vw, 1.6rem);
  margin: 0;
  padding: 0;
  list-style: none;
}
.clock__unit {
  display: grid;
  justify-items: center;
  min-width: clamp(3rem, 11vw, 5rem);
}
.clock__num {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.9rem, 1rem + 3.6vw, 3.2rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--charcoal);
  transition: opacity 0.3s var(--ease-silk);
}
/* Each value crossfades rather than snapping */
.clock__num.is-swap { opacity: 0; }
.clock__lbl {
  margin-top: 0.85rem;
  font-size: 0.56rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.28em;
  text-indent: 0.28em;      /* balance the trailing letter-space */
  color: var(--ink-faint);
}
.clock__sep {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 0.9rem + 2vw, 2.2rem);
  line-height: 1.15;
  color: var(--gold);
  opacity: 0.55;
  align-self: start;
}
.clock__done {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-h3);
  color: var(--olive);
}

/* ============================================================= ENTOURAGE */
/* One name style everywhere — the hierarchy comes from the labels above the
   columns, not from switching typeface or size between groups. */
.roll {
  font-family: var(--font-body);
  --name-size: clamp(0.98rem, 0.92rem + 0.25vw, 1.12rem);
  --name-leading: 1.95;
  max-width: 60rem;
  margin-inline: auto;
}

.roll__group + .roll__group { margin-top: clamp(2.6rem, 5vw, 4.5rem); }
.roll__group:last-child { padding-bottom: clamp(1.5rem, 4vw, 2.5rem); }

/* Playfair has deep descenders; give the last line of a column somewhere to
   land so nothing looks clipped by the section boundary. */
.names-list li:last-child { padding-bottom: 0.15em; }

.roll__role {
  text-align: center;
  font-family: var(--font-body);
  font-size: var(--fs-mono);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-wide);
  text-indent: var(--track-wide);
  color: var(--olive);
  margin: 0 0 clamp(1.3rem, 2.5vw, 2rem);
}
.roll__role::after {
  content: "";
  display: block;
  width: 28px; height: 1px;
  margin: 0.9rem auto 0;
  background: var(--line-gold);
  text-indent: 0;
}

.roll__cols {
  display: grid;
  grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: start;
}
.roll__cols--3 { --cols: 3; }

.roll__col { text-align: center; }

.roll__sub:empty { display: none; }
.roll__sub {
  font-family: var(--font-body);
  font-size: 0.6rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  color: var(--ink-faint);
  margin: 0 0 0.85rem;
}

/* Every name on the page, in one declaration. Playfair for the names, the
   sans labels above each column carry the hierarchy. */
.names-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-names);
  font-size: var(--name-size);
  font-weight: 400;
  line-height: var(--name-leading);
  letter-spacing: 0.002em;
  color: var(--charcoal);
}

/* ------------------------------------------------------------ Responsive */
@media (max-width: 760px) {
  .roll__cols--3 { --cols: 2; }

  /* Cord and Bible are the third of three in a two-column grid, so they land
     alone on a second row. Let them span both columns and sit centred rather
     than hanging off the left edge. */
  .roll__cols--3 > .roll__col:nth-child(3):last-child { grid-column: 1 / -1; }
}

/* The paired columns survive to the smallest screen — collapsing them to a
   single stack loses the couple-per-row reading that makes it look like a
   printed invitation. The type shrinks instead. */
@media (max-width: 560px) {
  .roll {
    --name-size: 0.84rem;
    --name-leading: 1.6;
  }
  .roll__cols { gap: 1.1rem 0.9rem; }
  .roll__group + .roll__group { margin-top: 2.4rem; }

  .roll__sub { font-size: 0.54rem; letter-spacing: 0.18em; text-indent: 0.18em; }

  .clock { gap: 0.2rem; }
  .clock__unit { min-width: 3.4rem; }
  .clock__lbl { font-size: 0.5rem; letter-spacing: 0.18em; text-indent: 0.18em; }
}

@media (max-width: 380px) {
  .roll { --name-size: 0.76rem; }
  .roll__cols { gap: 0.9rem 0.6rem; }
}