@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/montserrat-cyrillic-800-normal.e9796e8de1.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/montserrat-latin-500-normal.2b53300fb9.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/montserrat-cyrillic-500-normal.7d2f0315ec.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/cormorant-garamond-latin-600-italic.0b6719b252.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/cormorant-garamond-cyrillic-600-italic.cb92ea139b.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

:root {
  --ink: #14100d;
  --ink-rgb: 20, 16, 13;
  --ivory: #f5eee6;
  --ivory-rgb: 245, 238, 230;
  /* The one accent, lifted from the blonde wefts in the photograph. */
  --gold: #d8b684;
  --gold-rgb: 216, 182, 132;
  --gold-sheen: linear-gradient(104deg, #f4e7cf 0%, #d6b07a 38%, #f1e0c2 62%, #c9a06a 100%);
  --pad: clamp(20px, 4.6vw, 56px);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  /* Width of the longest headline line in em, per language; the build appends the values. */
  --line-em: 8;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--ivory);
  font-family: "Montserrat", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-weight: 500;
  -webkit-font-smoothing: antialiased;
}

/* One stacking context for the whole page: in landscape the headline has to sit BETWEEN the
   photo and the cut-out subject, so .frame and .copy must not create a context of their own
   (no z-index, no transform, no opacity on either). */
.stage {
  position: relative;
  isolation: isolate;
  /* Its own opaque ground, not the body's showing through: inside an isolated group a blend
     mode has nothing to blend with where the group is empty, so the grain fell back to plain
     grey over the text panel and drew the panel a shade lighter than the faded photo. */
  background: var(--ink);
  /* A fixed height, not a minimum: the photo box only gives way to the text when the column
     has a definite size to fit into. */
  height: 100vh;
  height: 100svh;
  min-height: 460px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Portrait: the photo box is capped by WIDTH, not by height. Any taller and the crop narrows
   until the two bundles she is holding fall off the sides, which is the one thing the picture
   is there to show. It shrinks on short phones so the words below always fit. */
.frame {
  position: relative;
  flex: 0 1 138vw;
  min-height: 46vh;
  min-height: 46svh;
}

.layer {
  position: absolute;
  inset: 0;
  display: block;
  overflow: hidden;
}

/* Both pictures share one box, one fit and one animation, which is the only thing keeping the
   cut-out registered to the photo underneath it. Change one and change the other. */
.layer img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 22%;
  animation: settle 5s var(--ease) both;
}

.photo { z-index: 1; }
.shade { z-index: 2; }
.subject { z-index: 4; }
.fade { z-index: 6; }

.shade {
  background: linear-gradient(180deg, rgba(var(--ink-rgb), 0.66) 0%, rgba(var(--ink-rgb), 0.14) 22%, rgba(var(--ink-rgb), 0) 42%);
}

/* Reaches the page colour BEFORE the box ends: stopping exactly at the edge leaves the last
   rows of the photo faintly visible and draws a line where the picture meets the panel. */
.fade {
  background: linear-gradient(180deg, rgba(var(--ink-rgb), 0) 46%, rgba(var(--ink-rgb), 0.7) 72%, var(--ink) 91%);
}

/* Film grain over everything, words included: it is what makes a flat dark panel and a
   photograph read as one surface. */
.grain {
  position: absolute;
  inset: 0;
  z-index: 9;
  pointer-events: none;
  background-image: url("img/grain.d7f0d38053.png");
  background-size: 120px 120px;
  opacity: 0.09;
  mix-blend-mode: overlay;
}

.brand {
  position: absolute;
  z-index: 8;
  top: calc(var(--pad) + env(safe-area-inset-top, 0px));
  left: var(--pad);
  margin: 0;
  font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-style: italic;
  font-weight: 600;
  font-size: clamp(27px, 6.6vw, 40px);
  line-height: 1;
  letter-spacing: 0.005em;
  text-shadow: 0 1px 18px rgba(var(--ink-rgb), 0.55);
  animation: appear 1.4s ease-out 0.1s both;
}

.chip {
  position: absolute;
  z-index: 8;
  top: calc(var(--pad) + env(safe-area-inset-top, 0px) - 2px);
  right: var(--pad);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 9px 14px 9px 11px;
  border: 1px solid rgba(var(--ivory-rgb), 0.3);
  border-radius: 999px;
  background: rgba(var(--ink-rgb), 0.42);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  font-size: 12px;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  animation: appear 1.4s ease-out 0.3s both;
}

.dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gold);
  animation: pulse 2.6s ease-out 1.4s infinite;
}

/* Deliberately NOT positioned and without a z-index: see .stage. */
.copy {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin-top: -12vh;
  margin-top: -12svh;
  padding: 0 var(--pad) clamp(14px, 2.4vh, 26px);
}

/* The box shrinks to the heavy line, so the script word above it starts on the same left edge. */
.headline {
  position: relative;
  z-index: 7;
  width: fit-content;
  margin: 0 auto;
  font-weight: 800;
  font-size: min(calc((100vw - 2 * var(--pad)) / var(--line-em)), 10.5vh);
  font-size: min(calc((100vw - 2 * var(--pad)) / var(--line-em)), 10.5svh);
  line-height: 0.92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-align: center;
}

/* The outer element of each line moves; the inner one only holds the ink. See build.mjs. */
.headline .line {
  display: block;
  animation: rise 1.2s var(--ease) 0.55s both;
}

.headline .line:first-child {
  /* Pulled down so its descenders rest on the heavy line below. */
  margin: 0 0 -0.1em 0.03em;
  font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-style: italic;
  font-weight: 600;
  font-size: 1.62em;
  line-height: 0.9;
  letter-spacing: -0.012em;
  text-transform: none;
  text-align: left;
  color: var(--gold);
  animation-delay: 0.4s;
}

/* Solid gold unless the browser can clip a background to the glyphs; then the sheen. The box is
   widened a little so the fill covers the overhang of the last italic letter. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .headline .line:first-child > span {
    display: inline-block;
    padding-right: 0.12em;
    background: var(--gold-sheen);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}

.ghost {
  display: none;
}

.rule {
  position: relative;
  z-index: 7;
  height: 1px;
  margin: clamp(16px, 2.6vh, 28px) 0 clamp(12px, 2vh, 20px);
  background: linear-gradient(90deg, rgba(var(--gold-rgb), 0) 0%, rgba(var(--gold-rgb), 0.8) 22%, rgba(var(--gold-rgb), 0.8) 78%, rgba(var(--gold-rgb), 0) 100%);
  animation: draw 1.3s var(--ease) 0.85s both;
}

.sub {
  position: relative;
  z-index: 7;
  margin: 0 auto;
  max-width: 32ch;
  font-size: clamp(16px, 4.2vw, 19px);
  line-height: 1.5;
  text-align: center;
  /* Two even lines instead of one long line and a single word left over. */
  text-wrap: balance;
  color: rgba(var(--ivory-rgb), 0.88);
  animation: rise 1.2s var(--ease) 1s both;
}

/* The address, small, at the very bottom: it anchors the poster and gives the empty band under
   the text on a tall phone something to end on. */
.foot {
  position: relative;
  z-index: 7;
  flex: none;
  margin: 0;
  padding: 0 var(--pad) calc(var(--pad) * 0.9 + env(safe-area-inset-bottom, 0px));
  font-size: 12px;
  line-height: 1;
  letter-spacing: 0.28em;
  text-align: center;
  text-transform: uppercase;
  color: rgba(var(--gold-rgb), 0.78);
  animation: appear 1.4s ease-out 1.3s both;
}

/* Every keyframe set states only where the element comes FROM: it arrives at its own resting
   style, so the ghost stops at its own opacity and nothing has to be repeated here. */
@keyframes settle {
  from { transform: scale(1.09); }
}

@keyframes appear {
  from { opacity: 0; }
}

@keyframes rise {
  from { opacity: 0; transform: translateY(0.3em); }
}

@keyframes draw {
  from { opacity: 0; transform: scaleX(0); }
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(var(--gold-rgb), 0.6); }
  70%, 100% { box-shadow: 0 0 0 9px rgba(var(--gold-rgb), 0); }
}

/* Landscape: the photo fills the screen and the headline runs BEHIND the subject. */
@media (min-aspect-ratio: 1/1) {
  .stage {
    display: block;
    /* Low on purpose: a phone on its side leaves about 300px once the browser bars are up, and
       a floor above that pushes the headline under the fold. */
    min-height: 260px;
  }

  .frame {
    position: absolute;
    inset: 0;
    min-height: 0;
  }

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

  .shade {
    background: linear-gradient(180deg, rgba(var(--ink-rgb), 0.62) 0%, rgba(var(--ink-rgb), 0.1) 22%, rgba(var(--ink-rgb), 0.12) 44%, rgba(var(--ink-rgb), 0.88) 100%);
  }

  .fade {
    display: none;
  }

  .copy {
    display: block;
    margin: 0;
    padding: 0;
  }

  .headline {
    position: absolute;
    z-index: 3;
    width: auto;
    left: var(--pad);
    right: var(--pad);
    bottom: clamp(16px, 4.5vh, 56px);
    bottom: clamp(16px, 4.5svh, 56px);
    font-size: min(calc((100vw - 2 * var(--pad)) / var(--line-em)), 14.5vh);
    font-size: min(calc((100vw - 2 * var(--pad)) / var(--line-em)), 14.5svh);
    text-shadow: 0 2px 40px rgba(var(--ink-rgb), 0.45);
  }

  /* The script word stands at the left edge, clear of her and of the blonde bundle she holds:
     gold over either one disappears. text-shadow would show THROUGH a gradient-filled word, so
     its depth comes from a filter instead. */
  .headline .line:first-child {
    margin-left: 0;
    font-size: 1.2em;
    text-shadow: none;
    filter: drop-shadow(0 2px 22px rgba(var(--ink-rgb), 0.7));
  }

  /* The same words once more, in front of the subject and half transparent: without them a
     word centred on the page hides entirely behind the person standing in the middle. */
  .ghost {
    display: block;
    z-index: 5;
    opacity: 0.5;
    /* A dark halo, because the fill alone vanishes wherever it crosses something as light
       as itself (her white top on a wide, short screen). */
    text-shadow: 0 0 26px rgba(var(--ink-rgb), 0.85);
    pointer-events: none;
  }

  .rule,
  .foot {
    display: none;
  }

  .sub {
    position: absolute;
    z-index: 8;
    top: calc(var(--pad) + env(safe-area-inset-top, 0px) + 52px);
    right: var(--pad);
    margin: 0;
    max-width: 24ch;
    font-size: clamp(16px, 1.15vw, 18px);
    line-height: 1.45;
    text-align: right;
    color: var(--ivory);
    text-shadow: 0 1px 18px rgba(var(--ink-rgb), 0.6);
  }
}

/* A phone on its side: the top right corner is where her raised hand is, so the line about
   booking moves under the wordmark, over the wall. */
@media (min-aspect-ratio: 1/1) and (max-height: 430px) {
  .sub {
    left: var(--pad);
    right: auto;
    text-align: left;
  }
}

@media (prefers-reduced-motion: reduce) {
  .layer img,
  .brand,
  .chip,
  .dot,
  .headline .line,
  .rule,
  .sub,
  .foot {
    animation: none;
  }
}

html[lang="ru"] { --line-em: 6.02; }
