/* ============================================================
   THE EVENING — the itinerary, as its own chapter.

   No photograph and no ornament: the four moments are carried by
   the size of the type, the room around them, and the order they
   arrive in. Every figure below is measured, not guessed — the
   binding case is Russian, which is the longer language in every
   line here:

     THE EVENING        7.737em      ПРОГРАММА ВЕЧЕРА  11.781em
     EVENING            5.143em      ПРОГРАММА          7.142em
     6:00 PM            3.613em
     CEREMONY BEGINS   14.017em      НАЧАЛО ЦЕРЕМОНИИ  15.370em

   The title is sized so ПРОГРАММА sets on one line inside the
   page's own measure at every width; English then breaks to
   THE / EVENING on a phone, which is the composition either way.

   The artwork beside each hour is set on the page's own black. It
   has no frame, no ground, no border and nothing behind it — the
   files carry their own alpha and the page shows it. Each moment
   names its artwork's true proportion in `--art`, measured off the
   trimmed file, so the picture is sized by its own shape rather
   than fitted into a box drawn for it:

     01  doves and rings   715 x 487   1.468
     02  the setting       619 x 532   1.164
     03  the dancers       596 x 563   1.059
     04  the cake          447 x 518   0.863

     1. Tokens
     2. The chapter and its ground
     3. The opening
     4. The four moments
     5. The artwork beside them
     6. Where each one sits
     7. Composition — tablet and desktop
     8. Entrance
     9. Reduced motion
   ============================================================ */

/* ---------- 1. Tokens ------------------------------------- */
.screen--night {
  --night-ink:   #000000;
  --night-lift:  #0C0C0B;   /* the middle of the sheet, not the edges */
  --night-ivory: #F4F1EC;
  --night-soft:  #CFC9BF;  /* 11.0:1 on black */
  --night-faint: #A8A196;  /* 6.6:1 — small and tracked, and still read */
  --night-seq:   #A8A196;  /* the sequence mark is read, not sensed */

  --t-night: clamp(2.5rem, 11.8vw, 8rem);      /* ПРОГРАММА  7.142em */

  /* The two switches stand in the right margin for the whole visit:
     their own offset from the edge, plus the wider of the two. Nothing
     on this chapter may be set underneath them. */
  --lane: calc(clamp(1.25rem, 5vw, 3.25rem) + 3.5rem);

  /* 6:00 PM is 3.86em wide including its tracking, and it is the
     widest type on the page. Three things share this line — the hour,
     the step the composition takes in from the left, and the lane —
     and on a phone narrower than about 375px they cannot all have what
     they want. The hour is what gives, and never by more than it must:
     what is left for it is the window, less the padding it starts
     after, less the lane, less the least step worth taking. Above that
     width the 17vw is smaller than the room and simply governs. */
  --t-time: min(clamp(3.25rem, 17vw, 6rem),
                calc((100vw - var(--pad) - var(--lane) - 1.625rem) / 3.86));
  --t-seq:   clamp(.7rem, 2.9vw, .875rem);     /* 01 — a mark, not a shape */
  --t-when:  clamp(.68rem, 2.9vw, .875rem);    /* the caption under it */

  --night-gap: clamp(7rem, 26svh, 15rem);      /* between moments */

  /* The artwork is sized by height, not by width, so a wide pair of
     doves and a tall cake carry the same weight on the page. */
  --art-h: clamp(11rem, 58vw, 19rem);
  --art-scale: 1;
}

/* ПРОГРАММА is one word and cannot be broken. On the narrowest phone
   the floor above holds it at 2.5rem where 11.8vw would have been
   smaller, and the last letter leaves the window. Russian alone steps
   down there; 340px and up, and English everywhere, are unchanged. */
@media (max-width: 339px) {
  :root[data-lang="ru"] .screen--night { --t-night: clamp(2rem, 11.4vw, 8rem); }
}

/* ---------- 2. The chapter and its ground ----------------- */
/* Black, but not a flat fill: a slow lift through the middle of the
   sheet and a fine grain over it, so it reads as ink on paper rather
   than as an empty canvas. The lift returns to pure black at the top
   and bottom edges, so the joins with the screens either side stay
   invisible, and the date pressed into it is set a few values above
   the lifted ground rather than below — printing catches the light,
   it does not cut a hole in the page. */
.screen--night {
  height: auto;
  min-height: 100svh;
  overflow: hidden;
  overflow: clip;
  cursor: default;
  position: relative;
  isolation: isolate;
  color: var(--night-ivory);
  padding: clamp(7rem, 20svh, 13rem) var(--pad) clamp(8rem, 22svh, 14rem);

  background-color: var(--night-ink);
  background-image:
    url('../img/grain.png'),
    linear-gradient(to bottom,
      var(--night-ink) 0%, var(--night-lift) 22%,
      var(--night-lift) 74%, var(--night-ink) 100%);
  background-size: 172px 172px, auto;
  background-repeat: repeat, no-repeat;
}

/* ---------- 3. The opening -------------------------------- */
/* The chapter opens on its own page: the date, then the title, and
   nothing else above the first moment. */
.night__open {
  max-width: 26em;
  margin: 0 0 clamp(6rem, 22svh, 12rem);
}

.night__eyebrow {
  font-family: var(--ui);
  font-weight: 400;
  font-size: var(--t-note);
  letter-spacing: .45em;
  text-indent: .45em;
  text-transform: uppercase;
  color: var(--night-faint);
  margin: 0;
}

.night__head {
  font-family: var(--display);
  font-weight: 400;
  font-variation-settings: 'opsz' 96;
  font-size: var(--t-night);
  line-height: .96;
  letter-spacing: .1em;
  text-indent: .1em;
  text-transform: uppercase;
  text-wrap: balance;
  margin: clamp(1.25rem, 4vw, 2.25rem) 0 0;
}

/* ---------- 4. The four moments --------------------------- */
.night__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.moment {
  position: relative;
  display: grid;
  gap: clamp(1.5rem, 5vw, 2.75rem);
}
.moment + .moment { margin-top: var(--night-gap); }

.moment__type { min-width: 0; }

/* The sequence mark counts the evening: a small tracked numeral over
   the hour, set to be read. It is not an enormous ghost behind the
   type — nothing on this chapter is printed behind anything. */
.moment__n {
  display: block;
  font-family: var(--ui);
  font-weight: 400;
  font-size: var(--t-seq);
  line-height: 1;
  letter-spacing: .34em;
  text-indent: .34em;
  margin: 0 0 clamp(.9rem, 3.2vw, 1.4rem);
  color: var(--night-seq);
  user-select: none;
}

.moment__time {
  font-family: var(--display);
  font-weight: 400;
  font-variation-settings: 'opsz' 96;
  font-size: var(--t-time);
  line-height: 1;
  letter-spacing: .02em;
  font-variant-numeric: lining-nums;
  white-space: nowrap;
}

/* The hour rises out of a mask rather than simply appearing. The mask
   is padded on every side and pulled back out of the flow by the same
   amount, so it hides the hour below its edge without ever cutting
   into the glyphs — a tight mask clips the tracking off the M. */
.moment__time {
  overflow: hidden;
  padding: .14em .34em .10em 0;
  margin: 0 -.34em -.10em 0;
}
.moment__time > span { display: block; }

/* Much smaller, and the only thing here in the secondary face — the
   hour is the moment, this names it. */
.moment__name {
  font-family: var(--ui);
  font-weight: 400;
  font-size: var(--t-when);
  line-height: 1.5;
  letter-spacing: .28em;
  text-indent: .28em;
  text-transform: uppercase;
  color: var(--night-soft);
  max-width: 22em;
  margin: clamp(1.1rem, 4vw, 1.75rem) 0 0;
}

/* ---------- 5. The artwork beside them -------------------- */
/* Nothing is drawn around it and nothing is put behind it: the file's
   own transparency is the whole of its edge. Sized by height so its
   proportion is its own, and never cropped — where a shape is wider
   than the room it has, it is contained rather than cut. */
.moment__art {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateY(var(--drift, 0px));
  will-change: transform;
}
.moment__art picture { display: contents; }
.moment__art img {
  display: block;
  width: auto;
  height: calc(var(--art-h) * var(--art-scale));
  max-width: 100%;
  object-fit: contain;
  border: 0;
}

/* On a phone the picture takes the outer edge and runs a little off
   the page, and the numeral comes up under it, so the two read as one
   composition rather than as a picture with a caption below it. The
   picture keeps the page's edge and the type steps in from it, which
   is what makes the side change between one moment and the next. */
.moment__art { order: -1; }
.moment { --bleed: calc(var(--pad) * -0.62); }
.moment--a .moment__art,
.moment--c .moment__art { justify-content: flex-end; margin-right: var(--bleed); }
.moment--b .moment__art,
.moment--d .moment__art { justify-content: flex-start; margin-left: var(--bleed); }
.moment__type { margin-top: 0; }

/* The cake is the tallest and the narrowest of the four, and the only
   one whose flowers run right to its own edge. It is given its room
   rather than made to match the others: it keeps the page, it does not
   run off it, and the numeral does not come as far up under it. */
.moment--d {
  --art-scale: 1.06;
  --bleed: 0px;
}
.moment--d .moment__type { margin-top: 0; }
.moment--c { --art-scale: 1.04; }

/* ---------- 6. Where each one sits ------------------------ */
/* The composition walks from side to side down the page. On a phone
   the step is small — enough to feel, not enough to strand a line
   against the edge — and it is the type that steps, so the picture
   can keep running off the page. */
/* The step is capped by the room the hour has left. Whatever the
   moment steps in, the hour it carries must still stop before the
   lane: the measure, less however far the switches reach in past the
   padding, less the hour itself. Where the step already fits — which
   is most windows — nothing moves at all. */
.moment { --step-max: max(0px, calc(100% - var(--lane) + var(--pad) - 3.86 * var(--t-time))); }

.moment--b .moment__type { margin-left: min(15%, var(--step-max)); }
.moment--c .moment__type { margin-left: min(5%,  var(--step-max)); }
.moment--d .moment__type { margin-left: min(21%, var(--step-max)); }

/* ---------- 7. Composition — tablet and desktop ----------- */
/* From a tablet up the picture stands beside the hour rather than over
   it, and the two share the width: the type keeps a measure it can
   hold and the artwork takes what its own shape asks for. */
@media (min-width: 700px) {
  .screen--night {
    --t-night: clamp(3.5rem, 8.6vw, 8rem);
    --t-time:  clamp(3.4rem, 8.4vw, 8.5rem);
    --t-seq:   clamp(.72rem, 1.4vw, .9rem);
    --t-when:  clamp(.72rem, 1.5vw, .9rem);
    --art-h:   clamp(12rem, 25vw, 20rem);
  }

  .moment {
    grid-template-columns: minmax(0, 1fr) minmax(0, 47%);
    align-items: center;
    gap: clamp(1.5rem, 4vw, 3.5rem);
  }
  .moment__type { margin-top: 0; }
  .moment__art { order: 0; margin: 0; }

  /* One side, then the other, down the page. */
  .moment--b .moment__type,
  .moment--d .moment__type { order: 2; }
  .moment--b .moment__art,
  .moment--d .moment__art  { order: 1; }

  .moment--b .moment__type,
  .moment--c .moment__type,
  .moment--d .moment__type { margin-left: 0; }
  /* From a tablet up the hour sits in the right-hand column, which is
     the one the switches stand over. The two moments that take that
     side step in less far than they did, so the hour stops short of
     the lane; the picture beside them moves with them and keeps the
     side it had. The type is not made smaller to do it. */
  .moment--b { margin-left: 4.5%; }
  .moment--c { margin-left: 5%; }
  .moment--d { margin-left: 5.5%; }
}

/* A spread: the four moments are placed across twelve columns rather
   than indented, so the walk from side to side becomes the page. */
@media (min-width: 1100px) {
  .screen--night {
    --t-night: clamp(4rem, 7vw, 8rem);
    --t-time:  clamp(3.6rem, 5.2vw, 7.5rem);
    --t-seq:   clamp(.75rem, .95vw, .95rem);
    --t-when:  clamp(.75rem, 1vw, .95rem);
    --night-gap: clamp(8rem, 26svh, 18rem);
    --art-h:    clamp(14rem, 17.5vw, 24rem);
  }

  .night__open,
  .night__list {
    width: 100%;
    max-width: 96rem;
    margin-inline: auto;
  }
  .night__open { max-width: 96rem; }

  /* A staircase, not a table: each moment keeps its own row and only
     its column changes, so the composition still walks down the page
     one moment at a time — it simply has room to walk further. */
  .night__list {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    column-gap: var(--gut);
    row-gap: var(--night-gap);
  }
  .moment { max-width: none; margin-left: 0; }
  .moment + .moment { margin-top: 0; }

  /* Each moment now holds a picture as well as its hour, so it takes
     seven of the twelve columns rather than five — and the walk from
     side to side is the seven moving across the spread. */
  .moment--a { grid-column: 1 / 8;  grid-row: 1; }
  .moment--b { grid-column: 6 / 13; grid-row: 2; }
  .moment--c { grid-column: 1 / 8;  grid-row: 3; }
  .moment--d { grid-column: 6 / 13; grid-row: 4; }
  .moment { margin-left: 0; }
}

@media (min-width: 1600px) {
  .night__open,
  .night__list { max-width: 100rem; }
}

/* ---------- 8. Entrance ----------------------------------- */
/* The date, then the title. */
.night__open [data-r] {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 1000ms cubic-bezier(.32,.08,.24,1) calc(var(--i, 0) * var(--step)),
    transform 1000ms cubic-bezier(.32,.08,.24,1) calc(var(--i, 0) * var(--step));
}
.night__open.is-in [data-r] { opacity: 1; transform: none; }

/* Each moment arrives on its own as it comes up the page, never four
   at once: the mark lifts, the hour rises out of its mask, the words
   settle out of their tracking, and the picture floats up last. */
.moment__n,
.moment__name,
.moment__art {
  opacity: 0;
  transition:
    opacity 1100ms cubic-bezier(.32,.08,.24,1),
    transform 1100ms cubic-bezier(.32,.08,.24,1),
    letter-spacing 1400ms cubic-bezier(.22,.61,.24,1);
}
.moment__n    { transform: translateY(14px); transition-delay: 0ms; }
.moment__name { transform: translateY(12px); letter-spacing: .46em; text-indent: .46em;
                transition-delay: 340ms; }

/* The hour is not faded in — it comes up from under the edge of its
   own mask, which is why the mask is padded rather than tight. */
.moment__time > span {
  transform: translateY(112%);
  transition: transform 1250ms cubic-bezier(.22,.61,.24,1) 140ms;
}

/* The picture is the last thing to arrive, and it only rises: it is
   never scaled, so nothing about the artwork changes as it comes. */
.moment__art {
  transform: translateY(20px);
  transition:
    opacity 1400ms cubic-bezier(.32,.08,.24,1) 420ms,
    transform 1400ms cubic-bezier(.22,.61,.24,1) 420ms;
}

.moment.is-in .moment__n    { opacity: 1; transform: none; }
.moment.is-in .moment__name { opacity: 1; transform: none; letter-spacing: .28em; text-indent: .28em; }
.moment.is-in .moment__time > span { transform: none; }
.moment.is-in .moment__art  { opacity: 1; transform: translateY(var(--drift, 0px)); }

/* ---------- 9. Reduced motion ---------------------------- */
@media (prefers-reduced-motion: reduce) {
  .night__open [data-r],
  .moment__n,
  .moment__name,
  .moment__art,
  .moment__time > span {
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    transform: none !important;
  }
  .moment__name { letter-spacing: .28em; text-indent: .28em; }
  .night__open.is-in [data-r],
  .moment.is-in .moment__name,
  .moment.is-in .moment__art { opacity: 1; }
  .moment.is-in .moment__n { opacity: 1; }
}
