/* The public page. Phone first, then a separate laptop composition from 1024 px.
   Photos stay whole: masks and fades melt their edges into the page, nothing is cut out.

   The hero entrance never hides what matters: date, place and doors only move, they never fade,
   so a paused or hidden tab still shows them. Opacity is animated on decoration only. */

/* The gold line that draws itself down the hero. The paths only ever go down, so a clip from the top
   draws them exactly, in every browser, and at rest the line is simply whole. */
@keyframes swash-draw { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
/* A short bright band of the same path rides the tip of the line. */
@keyframes swash-tip {
  from { clip-path: inset(0 0 97.5% 0); opacity: 1; }
  92% { opacity: 1; }
  to { clip-path: inset(97.5% 0 0 0); opacity: 0; }
}
@keyframes hall-up { from { opacity: .2; transform: scale(1.04); } }
@keyframes light-up { from { opacity: 0; } }
@keyframes beam-drift { from { transform: rotate(var(--from)); } to { transform: rotate(var(--to)); } }
@keyframes bead-land { from { opacity: 0; transform: rotate(45deg) scale(.2); } }
@keyframes door-glint { from { opacity: 1; transform: translateX(-160%) skewX(-18deg); } to { opacity: 1; transform: translateX(300%) skewX(-18deg); } }
@keyframes twinkle { 0%, 100% { opacity: 0; transform: scale(.5); } 50% { opacity: 1; transform: scale(1); } }

.page-landing .topbar { display: none; }

.melt {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 12%, #000 80%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 12%, #000 80%, transparent 100%);
}
.melt img { width: 100%; }

/* Hero. It sits above the fixed bottom bar and hides it until scrolled past, with no script. */
.hero {
  position: relative;
  z-index: 2;
  display: flex;
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
  overflow: clip;
  isolation: isolate;
  background: var(--page);
}
.hero__wash {
  position: absolute;
  inset: 0;
  z-index: -3;
  background:
    radial-gradient(ellipse 90% 38% at 82% 34%, rgb(147 87 146 / .34), transparent),
    radial-gradient(ellipse 80% 34% at 14% 46%, rgb(165 154 199 / .14), transparent),
    radial-gradient(ellipse 110% 18% at 50% 82%, rgb(242 176 94 / .1), transparent);
  animation: light-up .7s ease-out backwards;
}
.hero__hall {
  position: absolute;
  inset: 212px 0 200px;
  z-index: -2;
  container-type: size;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 20%, #000 74%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 20%, #000 74%, transparent);
}
.hero__hall picture { display: block; height: 100%; }
.hero__hall img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 60%;
  opacity: .78;
  animation: hall-up .9s var(--ease-out) backwards;
}
/* Glints on the real chandelier: this box repeats the photo's object-fit, so they stay pinned. */
.hero__glints { display: none; }
@supports (width: 1cqw) {
  .hero__glints {
    display: block;
    position: absolute;
    z-index: 1;
    left: 50%;
    top: 60%;
    width: max(100cqw, 150cqh);
    aspect-ratio: 3 / 2;
    transform: translate(-50%, -60%);
    pointer-events: none;
  }
  .hero__glints i {
    position: absolute;
    width: 42px;
    height: 42px;
    margin: -21px 0 0 -21px;
    background:
      linear-gradient(90deg, transparent, #fff 50%, transparent) 50% 50% / 100% 1.5px no-repeat,
      linear-gradient(180deg, transparent, #fff 50%, transparent) 50% 50% / 1.5px 100% no-repeat,
      radial-gradient(closest-side, #fff, rgb(255 226 170 / .7) 20%, transparent 58%);
    opacity: 0;
    animation: twinkle 3.6s ease-in-out 20 backwards;
  }
  .hero__glints i:nth-child(1) { left: 35.4%; top: 27%; animation-delay: .9s; }
  .hero__glints i:nth-child(2) { left: 39%; top: 25.8%; animation-delay: 2.3s; }
  .hero__glints i:nth-child(3) { left: 42.7%; top: 26%; animation-delay: 1.4s; animation-duration: 4.4s; }
  .hero__glints i:nth-child(4) { left: 45.8%; top: 27.4%; animation-delay: 3.1s; }
  .hero__glints i:nth-child(5) { left: 47.9%; top: 28.2%; animation-delay: 1.9s; animation-duration: 5s; }
  .hero__glints i:nth-child(6) { left: 48.2%; top: 39.4%; animation-delay: 2.8s; animation-duration: 4.8s; }
}
/* Stage light: two or three soft beams from the rig, drifting slowly and only for two minutes. */
.hero__light { position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.hero__beam {
  position: absolute;
  inset: -4% -30% 0;
  transform-origin: var(--x) 0;
  transform: rotate(var(--from));
  background: conic-gradient(from 166deg at var(--x) 0, transparent 0deg, var(--beam) 14deg, transparent 28deg);
  -webkit-mask-image: linear-gradient(180deg, #000 15%, transparent 78%);
  mask-image: linear-gradient(180deg, #000 15%, transparent 78%);
  animation: light-up .8s ease-out backwards, beam-drift var(--drift) ease-in-out 6 alternate;
}
.hero__beam--violet { --x: 26%; --beam: rgb(186 96 205 / .3); --from: -7deg; --to: 9deg; --drift: 19s; }
.hero__beam--amber { --x: 72%; --beam: rgb(242 176 94 / .2); --from: 8deg; --to: -6deg; --drift: 23s; }
.hero__beam--rose { display: none; }
.hero__spot { display: none; }
/* Off screen the light rests; landing.js marks it. Without script it simply runs out on its own. */
.hero.is-away .hero__beam, .hero.is-away .hero__glints i { animation-play-state: paused; }

/* The line hangs from the top edge of the doors' panel, whatever the screen or the panel's height:
   this box ends exactly there, across the full width of the screen, and starts level with the logo. */
.hero__line {
  position: absolute;
  bottom: 100%;
  left: calc(8px - var(--gutter));
  width: 100vw;
  height: max(120px, calc(100svh - 338px));
  pointer-events: none;
}
.hero__swash { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
/* Where the line lands: one diamond of the parquet, on the panel's edge. */
.hero__bead {
  position: absolute;
  left: 32%;
  bottom: -6px;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  background: var(--thread-bright);
  box-shadow: 0 0 16px rgb(242 176 94 / .85);
  transform: rotate(45deg);
  animation: bead-land 460ms var(--spring) 1.2s backwards;
}
/* Below the panel the line waits for the scroll: it starts behind the panel's edge. */
.hero::after {
  content: "";
  position: absolute;
  left: 2.8%;
  bottom: 0;
  width: 1.25px;
  height: 30px;
  background: var(--thread);
  opacity: .8;
}
.hero__swash--laptop { display: none; }
.hero__swash path { vector-effect: non-scaling-stroke; fill: none; }
.hero__swash--line path { stroke: var(--thread); stroke-width: 1.25; opacity: .85; }
.hero__swash--line { animation: swash-draw 1.5s ease-out 80ms backwards; }
.hero__swash--tip path { stroke: var(--thread-bright); stroke-width: 2.5; stroke-linecap: round; }
.hero__swash--tip { opacity: 0; animation: swash-tip 1.5s ease-out 80ms backwards; }

.hero__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 24px;
  padding-block: 20px 16px;
}
.hero__brand { font: inherit; animation: rise .5s var(--ease-out) 60ms backwards; --rise: 8px; }
.hero__lead { position: relative; z-index: 1; }
.hero__date {
  margin-top: 6px;
  color: var(--text);
  font: 600 38px/1.1 var(--font-display);
  font-feature-settings: "lnum" 1;
  text-shadow: 0 1px 18px rgb(23 16 26 / .7);
  animation: rise .46s var(--ease-out) 130ms backwards;
}
.hero__place { margin-top: 4px; font-size: 17px; text-shadow: 0 1px 12px rgb(23 16 26 / .8); animation: rise .46s var(--ease-out) 170ms backwards; }
.hero__routes {
  position: relative;
  padding: 12px;
  margin-inline: -8px;
  background: var(--page);
  border-radius: var(--radius);
}
.hero__routes .banner { margin-bottom: 10px; }
.hero__question { margin-bottom: 10px; font-size: 16px; }
.hero__login { display: flex; align-items: center; justify-content: center; min-height: 44px; margin-top: 6px; color: var(--text); font-size: 16px; }
.hero__routes .door { animation: rise .42s var(--ease-out) 210ms backwards; --rise: 12px; }
.hero__routes .door + .door { animation-delay: 260ms; }
/* A glint runs over the doors as the bead lands. Off-door at rest. */
.hero__routes .door::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 40%;
  z-index: -1;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / .4), transparent);
  opacity: 0;
  animation: door-glint .46s var(--ease-in-out) 1.26s backwards;
}
.hero__routes .door + .door::after { animation-delay: 1.32s; }

/* The gold line continues below the hero, one stretch per block, each edge to edge, so the stretches
   join without a seam. It runs at the side, behind cards and clear of faces. */
.thread {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.thread--laptop { display: none; }
.thread path {
  fill: none;
  stroke: var(--thread);
  stroke-width: 1.25;
  vector-effect: non-scaling-stroke;
  opacity: .8;
}

/* Sections below the fold */
.evening { position: relative; isolation: isolate; }
.programme {
  position: relative;
  padding: 44px var(--gutter) 0;
  background:
    linear-gradient(180deg, var(--page), transparent 46%),
    radial-gradient(ellipse 120% 50% at 88% 50%, rgb(147 87 146 / .3), transparent);
}
.programme__title, .programme__list { position: relative; z-index: 2; }
.programme__list { list-style: none; padding: 0; margin-top: 16px; }
.programme__list li { position: relative; padding: 8px 0 8px 8px; }
/* A bead on the line: same x as the line's own position in the box, on any width. */
.programme__list li::before {
  content: "";
  position: absolute;
  left: calc(2.8vw - var(--gutter) - 4.5px);
  top: 19px;
  width: 9px;
  height: 9px;
  background: var(--champagne);
  transform: rotate(45deg);
}
.show { position: relative; padding-top: 28px; }
.show::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(ellipse 110% 50% at 30% 50%, rgb(47 143 120 / .24), transparent);
}
.show__title { position: relative; z-index: 2; padding-inline: var(--gutter); }
.show__photo { position: relative; margin-top: 4px; overflow: clip; }

.after-band {
  position: relative;
  isolation: isolate;
  padding-top: 20px;
  background: radial-gradient(ellipse 130% 50% at 50% 50%, rgb(105 23 36 / .6), transparent);
}
.after { position: relative; }
.after__photo { position: relative; overflow: clip; }
/* The hero's stage beams again, in the afterparty's colours. The scroll swings them. */
.after__beams { position: absolute; inset: 0; z-index: 1; overflow: clip; pointer-events: none; mix-blend-mode: screen; }
.after__beams i {
  position: absolute;
  inset: -6% -40% 0;
  transform-origin: var(--x) 0;
  transform: rotate(var(--from));
  background: conic-gradient(from 165deg at var(--x) 0, transparent 0deg, var(--beam) 15deg, transparent 30deg);
  -webkit-mask-image: linear-gradient(180deg, #000 10%, transparent 88%);
  mask-image: linear-gradient(180deg, #000 10%, transparent 88%);
}
.after__beams i:nth-child(1) { --x: 39%; --beam: rgb(255 170 180 / .42); --from: -30deg; --to: 26deg; }
.after__beams i:nth-child(2) { --x: 61%; --beam: rgb(255 214 170 / .38); --from: 32deg; --to: -24deg; }
.after__photo img { width: 100%; }
.after__copy { position: relative; z-index: 2; margin-top: -8px; }
.after__title { font-size: 50px; }
.after__text { margin-top: 4px; font-size: 19px; }

.routes-band { position: relative; isolation: isolate; padding-top: 44px; }
.routes-band::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--parquet);
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 45%, #000, transparent);
  mask-image: radial-gradient(ellipse 90% 70% at 50% 45%, #000, transparent);
}
.routes { position: relative; z-index: 2; display: grid; gap: 18px; }
.route {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 24px 20px;
  scroll-margin-top: 24px;
  border: 1px solid var(--line);
}
/* A gold edge that draws itself as the card arrives. */
.route::before {
  content: "";
  position: absolute;
  inset: -1px -1px auto;
  height: 2px;
  border-radius: var(--radius) var(--radius) 0 0;
  background: linear-gradient(90deg, var(--thread), var(--thread-bright) 50%, var(--thread));
}
.route > * + * { margin-top: 0; }
.route__price { font-size: 17px; }
.route__subtitle { font-size: 18px; font-weight: 600; margin-top: 4px; }
.route__note { color: var(--muted); }
.route__closed { padding: 14px 16px; background: var(--surface-raised); border-radius: var(--radius-small); font-weight: 500; text-align: center; }
.route .btn, .route__closed { margin-top: auto; }

.closing {
  position: relative;
  isolation: isolate;
  background: radial-gradient(ellipse 100% 30% at 80% 70%, rgb(147 87 146 / .2), transparent);
}
.venue { position: relative; padding: 44px var(--gutter) 0; }
.venue > :not(.thread), .last-time__title { position: relative; z-index: 2; }
.venue__place { margin-block: 8px; }
.venue__contacts { margin-top: 28px; }
.last-time { position: relative; padding-top: 56px; padding-bottom: 28px; }
.last-time__photos {
  position: relative;
  z-index: 2;
  display: flex;
  gap: 10px;
  margin-top: 12px;
  padding-inline: var(--gutter);
  overflow-x: auto;
  scroll-snap-type: x proximity;
}
.last-time__photo { flex: 0 0 82%; scroll-snap-align: center; }

/* Where the line ends: one diamond of the hall's parquet. */
.page-landing .site-footer { position: relative; margin-top: 0; border-top: 0; }
.page-landing .site-footer::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -6px;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  background: var(--thread);
  transform: rotate(45deg);
}

/* Scroll tells the story where the browser can do it without script. Elsewhere everything is simply there. */
@media screen and (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    @keyframes thread-draw { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
    @keyframes rises-in { from { opacity: .5; transform: translateY(14px); } to { opacity: 1; transform: none; } }
    @keyframes item-in { from { opacity: .5; transform: translateX(-10px); } to { opacity: 1; transform: none; } }
    @keyframes bead-in { from { transform: rotate(45deg) scale(.3); opacity: .3; } 60% { transform: rotate(45deg) scale(1.35); opacity: 1; } to { transform: rotate(45deg) scale(1); opacity: 1; } }
    @keyframes photo-in { from { opacity: .25; } to { opacity: 1; } }
    @keyframes drift-slow { from { transform: translateY(-4%) scale(1.09); } to { transform: translateY(4%) scale(1.09); } }
    @keyframes beam-swing { from { transform: rotate(var(--from)); } to { transform: rotate(var(--to)); } }
    @keyframes tail-draw { from { transform: scaleY(0); } to { transform: scaleY(1); } }
    @keyframes lights-down { from { opacity: 0; } 35% { opacity: 1; } 75% { opacity: 1; } to { opacity: 0; } }
    @keyframes edge-draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }
    @keyframes footer-bead { from { transform: rotate(45deg) scale(.2); } to { transform: rotate(45deg) scale(1); } }

    /* The pen stays at 78 % of the screen: each stretch starts when its top reaches that height
       and ends when its bottom does, and a clip from the top is exact because the paths only go down. */
    .thread {
      animation: thread-draw linear both;
      animation-timeline: view();
      animation-range: cover 22vh cover calc(100% - 78vh);
    }
    /* The last stretch must finish before the page runs out of scroll, whatever the footer's height
       and whichever viewport height (small or large on iOS): it is fully drawn once its end reaches
       the bottom edge of the screen, which any page that ends with the footer can scroll to.
       The view timeline's bottom edge sits scroll-padding-bottom (104px, base.css) above the screen's. */
    .thread--last { animation-range: cover 22vh entry-crossing calc(100% - 104px); }

    .rises {
      animation: rises-in linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 60%;
    }
    .programme__list li {
      animation: item-in linear both;
      animation-timeline: view();
      animation-range: cover 2vh cover 14vh;
    }
    /* The bead lights as the pen passes it. */
    .programme__list li::before {
      animation: bead-in linear both;
      animation-timeline: view();
      animation-range: cover 16vh cover 26vh;
    }
    .show__photo, .last-time__photo--dance, .last-time__photo--hall {
      animation: photo-in linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 60%;
    }
    .show__photo img, .after__photo img {
      animation: drift-slow linear both;
      animation-timeline: view();
      animation-range: cover;
    }
    .after__beams i {
      animation: beam-swing linear both;
      animation-timeline: view();
      animation-range: cover;
    }
    .hero::after {
      transform-origin: 50% 0;
      animation: tail-draw linear both;
      animation-timeline: view();
      animation-range: cover 22vh cover calc(100% - 78vh);
    }
    /* The moment of the afterparty: the room around the photo goes red, then comes back. */
    .after-band::before {
      content: "";
      position: absolute;
      inset: -22vh 0;
      z-index: -1;
      pointer-events: none;
      background: radial-gradient(ellipse 110% 50% at 50% 50%, rgb(150 28 48 / .42), transparent);
      animation: lights-down linear both;
      animation-timeline: view();
      animation-range: cover;
    }
    .route::before {
      transform-origin: 0 50%;
      animation: edge-draw linear both;
      animation-timeline: view();
      animation-range: entry 10% entry 70%;
    }
    /* The bead lights as the line lands on it: over the footer's first 40px on screen
       (the timeline's edge is 104px of scroll-padding above the screen's, hence the offsets). */
    .page-landing .site-footer::before {
      animation: footer-bead linear both;
      animation-timeline: view();
      animation-range: entry -104px entry -64px;
    }
  }
}

/* Short phones: tighten the hero so the doors still fit in the first viewport. */
@media (max-width: 1023px) and (max-height: 700px) {
  .brand--large { --brand-h: 96px; }
  .hero__date { font-size: 32px; }
  .hero__place { font-size: 16px; }
  .hero__inner { gap: 12px; padding-block: 12px 8px; }
  .hero__line { height: max(100px, calc(100svh - 290px)); }
  .hero__hall { inset: 170px 0 180px; }
  .door { min-height: 72px; }
}

/* Laptop: a composition of its own. The hall is wide, the routes sit in the top bar and the hero. */
@media (min-width: 1024px) {
  .page-landing .topbar { display: block; }

  .hero { min-height: min(calc(100vh - 64px), 900px); }
  .hero__hall { inset: 0; -webkit-mask-image: none; mask-image: none; }
  .hero__hall img { object-position: 50% 62%; opacity: .86; }
  .hero__glints { top: 62%; transform: translate(-50%, -62%); }
  .hero__wash { display: none; }
  .hero__hall::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
      linear-gradient(180deg, rgb(23 16 26 / .62) 0, rgb(23 16 26 / .06) 24%, rgb(23 16 26 / .04) 50%, rgb(23 16 26 / .9) 88%, var(--page) 100%),
      linear-gradient(90deg, rgb(23 16 26 / .84) 0, rgb(23 16 26 / .4) 30%, transparent 54%);
  }
  .hero__beam--rose { display: block; --x: 50%; --beam: rgb(226 120 190 / .16); --from: -3deg; --to: 5deg; --drift: 29s; }
  .hero__spot {
    display: block;
    position: absolute;
    left: -320px;
    top: -320px;
    width: 640px;
    height: 640px;
    z-index: -1;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgb(255 214 150 / .26), rgb(255 214 150 / .08) 55%, transparent);
    opacity: 0;
    transition: opacity .5s ease;
    pointer-events: none;
  }
  .hero__spot.is-on { opacity: 1; }
  .hero__line {
    left: auto;
    right: calc((min(100vw - 80px, 1240px) - 100vw) / 2);
    height: max(200px, calc(min(100vh - 64px, 900px) - 323px));
  }
  .hero__bead { left: 68%; }
  .hero::after { left: 60%; height: 60px; }
  .hero__swash--phone { display: none; }
  .hero__swash--laptop { display: block; }
  .hero__swash--line path { stroke-width: 1.5; opacity: .9; }
  .hero__inner {
    flex-direction: row;
    align-items: flex-end;
    padding-block: 48px;
    gap: 64px;
  }
  .hero__lead { margin-right: auto; }
  .brand--large { --brand-h: 210px; }
  .hero__date { margin-top: 12px; font-size: 68px; }
  .hero__place { font-size: 24px; }
  .hero__routes {
    flex: 0 0 500px;
    margin: 0;
    padding: 22px;
    background: linear-gradient(180deg, rgb(44 29 52 / .94), rgb(23 16 26 / .96));
    box-shadow: inset 0 1px 0 rgb(223 192 138 / .5), 0 24px 60px -24px rgb(0 0 0 / .8);
  }
  .hero__routes .door { min-height: 104px; }
  .hero__routes .door__title { font-size: 23px; }
  .hero__routes .door__note { font-size: 16px; }
  .hero__question { font-size: 19px; font-weight: 500; }

  /* The top bar carries the reading progress: the gold line again. */
  @media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: scroll()) {
      @keyframes grow-across { from { transform: scaleX(0); } to { transform: scaleX(1); } }
      .page-landing .topbar::after {
        content: "";
        position: absolute;
        inset: auto 0 -1px;
        height: 2px;
        background: linear-gradient(90deg, var(--thread), var(--thread-bright));
        transform-origin: 0 50%;
        animation: grow-across linear both;
        animation-timeline: scroll(root);
      }
    }
  }

  .thread--phone { display: none; }
  .thread--laptop { display: block; }

  .evening {
    display: grid;
    grid-template-columns: minmax(var(--gutter), 1fr) minmax(0, 480px) minmax(0, 760px);
    column-gap: 40px;
    align-items: center;
    padding-top: 72px;
    background:
      linear-gradient(180deg, var(--page), transparent 34%),
      radial-gradient(ellipse 50% 50% at 16% 50%, rgb(147 87 146 / .28), transparent),
      radial-gradient(ellipse 50% 50% at 78% 50%, rgb(47 143 120 / .24), transparent);
  }
  .programme { grid-column: 2; padding: 0; background: none; }
  .programme__list { margin-top: 24px; }
  .programme__list li { padding-block: 14px; padding-left: 30px; font-size: 22px; line-height: 1.35; border-top: 1px solid var(--surface-raised); }
  .programme__list li::before { left: 2px; top: 25px; }
  .show { grid-column: 3; padding: 0; }
  .show::before { display: none; }
  .show__title { position: absolute; left: 0; bottom: 8%; z-index: 3; padding: 0; font-size: 80px; text-shadow: 0 2px 34px rgb(23 16 26 / .9); }
  .show__photo {
    margin: 0;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 22%), linear-gradient(180deg, transparent 0, #000 12%, #000 82%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(90deg, transparent 0, #000 22%), linear-gradient(180deg, transparent 0, #000 12%, #000 82%, transparent 100%);
    mask-composite: intersect;
  }

  /* The floor under the title is bright: a local shade keeps the word above 4.5:1. */
  .show__photo::after {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse 52% 50% at 6% 86%, rgb(23 16 26 / .94) 30%, rgb(23 16 26 / .6) 62%, transparent);
    pointer-events: none;
  }

  .after-band { padding-top: 56px; }
  .after__photo {
    height: min(780px, 58vw);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 14%, #000 72%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0, #000 14%, #000 72%, transparent 100%);
  }
  .after__photo picture { display: block; height: 100%; }
  .after__photo img { height: 100%; object-fit: cover; object-position: 50% 42%; }
  .after__photo::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(0deg, rgb(23 16 26 / .9) 0, rgb(23 16 26 / .55) 22%, transparent 45%);
  }
  .after__copy { position: absolute; inset: auto 0 64px; margin-inline: auto; }
  .after__title { font-size: 112px; line-height: 1; text-shadow: 0 2px 34px rgb(23 16 26 / .9); }
  .after__text { font-size: 26px; text-shadow: 0 1px 18px rgb(23 16 26 / .95); }

  .routes-band { padding-top: 72px; }
  .routes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px; }
  .route { padding: 36px; }
  .route__title { font-size: 60px; }

  .closing {
    display: grid;
    grid-template-columns: minmax(var(--gutter), 1fr) minmax(0, 340px) minmax(0, 900px);
    column-gap: 40px;
    align-items: start;
    padding-top: 88px;
  }
  .venue { grid-column: 2; padding: 0; position: sticky; top: 96px; }
  .last-time { grid-column: 3; padding: 0 0 40px; }
  .last-time__title { width: auto; margin: 0; }
  /* Side by side and overlapping, so the pair is about as tall as the text beside it:
     no empty column under "Контакти". */
  .last-time__photos { display: flex; align-items: flex-start; gap: 0; overflow: visible; padding: 0; margin-top: 12px; }
  .last-time__photo--hall { flex: 0 0 60%; }
  .last-time__photo--dance {
    flex: 0 0 48%;
    margin: 96px 0 0 -8%;
    position: relative;
    /* Its sides melt too: into the hall photo it overlaps, and into the page at the screen's edge. */
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16%, #000 90%, transparent 100%), linear-gradient(180deg, transparent 0, #000 12%, #000 80%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(90deg, transparent 0, #000 16%, #000 90%, transparent 100%), linear-gradient(180deg, transparent 0, #000 12%, #000 80%, transparent 100%);
    mask-composite: intersect;
  }
}
@media (min-width: 1680px) {
  .evening, .closing { padding-right: var(--gutter); }
}
