/* What each frame on the reel holds. Rank comes from how many cells a frame
   spans and from orange tape, so headings share one size; the names are the
   single tall exception. */

.heading {
  color: var(--paper);
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  line-height: 1.12;
  text-transform: uppercase;
  text-wrap: balance;
}

.heading--small {
  font-size: 1.375rem;
}

/* a heading that is a sentence keeps one case all the way through */
.heading--sentence {
  letter-spacing: 0;
  text-transform: none;
}

.heading--sentence .lead {
  color: var(--paper);
  font-weight: 600;
}

.heading--sentence .title {
  color: var(--film);
}

#reception-heading .title {
  color: var(--paper);
}

.label {
  color: var(--paper-dim);
  font-size: 0.8125rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  line-height: 1.3;
  text-transform: uppercase;
}

.address,
.room,
.calendar-note,
.rsvp-message,
.rsvp-done-text {
  color: var(--paper-dim);
  font-size: 1.0625rem;
  line-height: 1.45;
  max-width: 34ch;
}

/* ---------- punched white windows: the only place photographs live ---------- */
.mount {
  display: flex;
  padding: 9px;
  background: var(--paper);
  border-radius: 1px;
  box-shadow: 0 14px 28px -10px rgb(0 0 0 / 0.85);
}

.mount-hole {
  position: relative;
  display: block;
  flex: 1;
  overflow: hidden;
  /* an unexposed frame: what shows while a photo loads or if it never does */
  background:
    radial-gradient(90% 70% at 0% 100%, rgb(255 90 31 / 0.32), transparent 60%),
    var(--grain-light) 0 0 / 200px 200px,
    linear-gradient(160deg, #1d1916, #0b0a09);
}

.mount-hole img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 1;
  transition: opacity 0.5s var(--ease-out);
}

.mount-hole img.is-failed {
  opacity: 0;
}

.frame--photo .mount,
.mount--hero {
  flex: 1;
  min-height: 0;
  aspect-ratio: 4 / 5;
}

.frame--photo .window-area {
  padding: 18px;
}

/* a cleared photo takes its whole frame with it */
.frame--photo:has(img[hidden]),
.mount:has(> .mount-hole > img[hidden]) {
  display: none;
}

/* ---------- names + hero ---------- */
.frame--names .window-area {
  justify-content: flex-end;
}

.names {
  color: var(--film);
  font-size: clamp(3rem, 15vw, 4.25rem);
  font-weight: 800;
  letter-spacing: 0.01em;
  /* tall enough that a dot below never meets the acute on the next line */
  line-height: 1.24;
  text-transform: uppercase;
}

.names .name {
  display: block;
}

.names .amp {
  display: inline-block;
  font-weight: 300;
}

.names .amp + .name {
  display: inline;
}

.mount--hero {
  aspect-ratio: 1;
}

.mount--hero img {
  object-position: 50% 16%;
}

/* ---------- families ---------- */
.families {
  display: grid;
  gap: 22px;
}

.family {
  display: grid;
  gap: 6px;
}

.parents {
  color: var(--paper);
  font-size: 1.25rem;
  font-weight: 500;
  line-height: 1.4;
}

.parents b {
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.couple-line,
.closing-names {
  color: var(--film);
  font-size: 2rem;
  font-weight: 800;
  line-height: 1.1;
  text-transform: uppercase;
}

.couple-line [data-amp],
.closing-names [data-amp] {
  font-weight: 300;
}

/* ---------- ceremony + reception ---------- */
.when {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
}

.tape--time {
  font-size: 2rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  padding: 4px 16px 2px;
}

.when-date {
  color: var(--paper);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* "Được cử hành tại" leads straight into the venue, one sentence */
.venue-line {
  color: var(--paper);
  font-size: 2rem;
  line-height: 1.15;
  text-wrap: balance;
}

.venue-label {
  font-weight: 600;
}

.venue-line .venue {
  font-size: inherit;
  line-height: inherit;
  text-transform: none;
}

.venue {
  color: var(--paper);
  font-size: 2rem;
  font-weight: 800;
  line-height: 1.1;
  text-transform: uppercase;
}

.room {
  margin-top: -12px;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: auto;
}

/* ---------- calendar ---------- */
.calendar-year {
  color: var(--film);
}

.month {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 2px;
  text-align: center;
}

.month .weekday {
  padding-bottom: 6px;
  color: var(--paper-dim);
  font-size: 0.8125rem;
  font-weight: 800;
  letter-spacing: 0.06em;
}

.month .day {
  position: relative;
  display: grid;
  place-items: center;
  height: 38px;
  color: var(--paper);
  font-size: 1.0625rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.month .day.is-wedding {
  color: var(--film);
  font-size: 1.375rem;
  font-weight: 800;
}

.ring {
  position: absolute;
  inset: -4px -2px;
  width: calc(100% + 4px);
  height: calc(100% + 8px);
  color: var(--paper);
  pointer-events: none;
  transform: rotate(-8deg);
}

/* ---------- schedule: a cue sheet of timecodes ---------- */
.cue-sheet {
  display: grid;
  border-top: 1px solid rgb(244 239 233 / 0.22);
}

.cue-sheet li {
  display: grid;
  grid-template-columns: 5.25rem 1fr;
  align-items: baseline;
  gap: 12px;
  padding: 10px 0 9px;
  border-bottom: 1px solid rgb(244 239 233 / 0.22);
}

.cue-sheet time {
  color: var(--film);
  font-size: 1.625rem;
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  line-height: 1;
}

.cue-sheet span {
  color: var(--paper);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ---------- album: the contact sheet ---------- */
.sheet-head {
  display: grid;
  justify-items: start;
  gap: 14px;
}

.sheet-slate {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  color: var(--paper-dim);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.sheet-count {
  color: var(--film);
}

.sheet {
  display: grid;
  gap: 28px;
}

.strip {
  --strip-perf: 18px;

  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px 8px;
  padding: var(--strip-perf) 8px;
  background:
    url("../img/perf-top.svg") 0 0 / 16px var(--strip-perf) repeat-x,
    url("../img/perf-bottom.svg") 0 100% / 16px var(--strip-perf) repeat-x,
    var(--grain-dark) 0 0 / 180px 180px,
    var(--film);
}

.shot {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: zoom-in;
}

.shot .mount {
  padding: 4px;
  box-shadow: none;
}

.shot .mount-hole {
  aspect-ratio: 4 / 5;
}

.shot:hover .mount,
.shot:focus-visible .mount {
  background: var(--film);
}

.shot .ring {
  inset: -10px -8px;
  width: calc(100% + 16px);
  height: calc(100% + 20px);
  color: var(--paper);
  filter: drop-shadow(0 1px 0 rgb(0 0 0 / 0.6));
}

.trims {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 26px 10px;
  padding-top: 10px;
}

.trims::before {
  content: "";
  position: absolute;
  top: 6px;
  right: 0;
  left: 0;
  height: 1px;
  background: rgb(244 239 233 / 0.4);
}

.trim {
  position: relative;
  display: grid;
  gap: 6px;
  width: 78px;
  padding: 8px 13px;
  background:
    url("../img/perf-left.svg") left top / 12px 12px repeat-y,
    url("../img/perf-right.svg") right top / 12px 12px repeat-y,
    var(--grain-dark) 0 0 / 180px 180px,
    var(--film);
  transform: rotate(var(--tilt, 0deg));
  transform-origin: 50% -8px;
}

/* the pin each trim hangs from */
.trim::before {
  content: "";
  position: absolute;
  top: -12px;
  left: calc(50% - 6px);
  width: 12px;
  height: 12px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--paper);
}

.trim .shot .mount {
  padding: 3px;
}

.trim .shot .mount-hole {
  aspect-ratio: 3 / 4;
}

/* ---------- RSVP ---------- */
.frame--rsvp .window-area {
  gap: 26px;
}

.rsvp-copy {
  display: grid;
  gap: 12px;
}

.rsvp-form {
  display: grid;
  gap: 18px;
}

.field {
  display: grid;
  gap: 8px;
}

.rsvp-form input[type="text"] {
  width: 100%;
  min-height: 52px;
  padding: 10px 14px;
  border: 0;
  border-bottom: 2px solid var(--film);
  border-radius: 0;
  background: rgb(244 239 233 / 0.07);
  color: var(--paper);
  font: 600 1.25rem / 1.2 var(--face);
}

.rsvp-form input[type="text"]::placeholder {
  color: #a69990;
  opacity: 1;
}

.rsvp-form input[type="text"]:focus-visible {
  outline: 3px solid var(--paper);
  outline-offset: 2px;
}

.count-chips {
  display: grid;
  grid-template-columns: repeat(5, minmax(44px, 1fr));
  gap: 6px;
}

.count-chips label {
  position: relative;
  display: block;
}

.count-chips input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.count-chips span {
  display: grid;
  place-items: center;
  min-height: 48px;
  border: 2px solid rgb(244 239 233 / 0.3);
  color: var(--paper);
  font-size: 1.25rem;
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  pointer-events: none;
}

.count-chips label:hover span {
  border-color: var(--film);
}

.count-chips input:checked + span {
  border-color: var(--film);
  background: var(--film);
  color: var(--ink);
}

.count-chips input:focus-visible + span {
  outline: 3px solid var(--paper);
  outline-offset: 2px;
}

.rsvp-submit {
  min-height: 56px;
  font-size: 1.0625rem;
}

.rsvp-status {
  min-height: 1.5em;
  color: var(--paper);
  font-size: 1.0625rem;
  font-weight: 600;
}

.rsvp-done {
  display: grid;
  gap: 18px;
}

/* the kept take: orange tape across the committed frame */
.seal-tape {
  position: relative;
  margin-inline: calc(-1 * var(--pad) - var(--band) + 6px);
  padding: 14px calc(var(--pad) + var(--band));
  background:
    var(--grain-dark) 0 0 / 180px 180px,
    var(--film);
  color: var(--ink);
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  line-height: 1.1;
  text-transform: uppercase;
  transform: rotate(-2.5deg);
  --tear: 14px;
}

.frame--rsvp.is-kept .seal-tape {
  animation: tape-lay 0.9s var(--ease-out) both;
}

@keyframes tape-lay {
  from {
    clip-path: inset(0 100% 0 0);
  }

  to {
    clip-path: inset(0);
  }
}

.rsvp-done-text {
  color: var(--paper);
  font-size: 1.25rem;
}

/* ---------- closing ---------- */
.frame--closing .window-area {
  justify-content: flex-end;
  gap: 22px;
}

.closing-message {
  color: var(--paper);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.3;
  text-wrap: balance;
}

.closing-date {
  color: var(--paper-dim);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ---------- the stop mark: a folded flag where the guest left off ---------- */
.stop-flag {
  position: absolute;
  z-index: 2;
  top: 0;
  right: 18px;
  display: block;
  padding: 6px 12px 16px;
  background: var(--film);
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  line-height: 1.2;
  text-transform: uppercase;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% calc(100% - 9px), 0 100%);
}

/* ---------- desktop frames ---------- */
@media (min-width: 900px) and (min-height: 680px) {
  .names {
    font-size: 6rem;
    line-height: 1.2;
  }

  .names .word {
    display: block;
    width: fit-content;
  }

  .names .amp {
    display: block;
    font-size: 4rem;
    line-height: 1.1;
  }

  .names .amp + .name {
    display: block;
  }

  .mount--hero,
  .frame--photo .mount {
    aspect-ratio: auto;
  }

  .frame--families .window-area {
    justify-content: space-between;
  }

  .families {
    grid-template-columns: 1fr 1fr;
    gap: 32px;
  }

  .frame--families .parents {
    font-size: 1.5rem;
    line-height: 1.35;
  }

  .frame--families .address {
    font-size: 1.125rem;
  }

  /* the ceremony time is the frame's one big fact, on its tape */
  .frame--rite .when {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    margin-top: auto;
  }

  .frame--rite .tape--time {
    font-size: 5rem;
    line-height: 1;
    padding: 8px 26px 2px;
    --tear: 12px;
  }

  .frame--rite .when-date {
    font-size: 1.125rem;
  }

  .frame--rite .venue-line {
    margin-top: auto;
  }

  .frame--rite .venue-line {
    font-size: 2rem;
  }

  /* the frame under the playhead carries an orange edge */
  .frame.is-now {
    box-shadow:
      inset 0 0 0 4px var(--film),
      inset 0 6px 18px rgb(0 0 0 / 0.7);
  }

  .frame--rite .window-area,
  .frame--reception .window-area {
    gap: 20px;
  }

  .frame--calendar .window-area {
    gap: 16px;
  }

  /* the sheet's slate runs across its top, the sheet takes the rest */
  .frame--album .window-area {
    gap: 22px;
  }

  .sheet-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 28px;
  }

  .sheet-head .btn {
    margin-inline-start: auto;
  }

  .sheet {
    gap: 30px;
  }

  .strip {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 8px;
  }

  .shot .mount-hole {
    height: calc(var(--frame-h) * 0.3);
    aspect-ratio: auto;
  }

  .trims--long ~ .strip .shot .mount-hole,
  .sheet:has(.trims--long) .strip .shot .mount-hole {
    height: calc(var(--frame-h) * 0.2);
  }

  /* the hanging trims are sized by the script to fill the sheet */
  .trims {
    flex-wrap: nowrap;
    justify-content: space-between;
  }

  .trim .shot .mount-hole {
    height: var(--trim-hole, calc(var(--frame-h) * 0.15));
    aspect-ratio: 3 / 4;
  }

  .trim {
    width: auto;
  }

  .frame--rsvp .window-area {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 0 calc(var(--pad) * 2 + var(--gap));
  }

  .frame--rsvp .heading {
    font-size: 2.5rem;
    line-height: 1.08;
  }

  .rsvp-message {
    font-size: 1.25rem;
  }

  .rsvp-done {
    grid-column: 1 / -1;
    align-self: center;
  }

  .frame--rsvp.is-kept .rsvp-copy {
    display: none;
  }

  .seal-tape {
    font-size: 2.5rem;
  }

  .rsvp-done-text {
    font-size: 1.5rem;
    max-width: 40ch;
  }
}
