/* The frame that becomes the page: an amber poster with two lines and a dark frame between them, a violin rising out
   of the frame; the first scroll turns the frame into the night of the whole page, and the violin flies to its place. */
:root {
  --night: #10132e;
  --amber: #ffb81c;
  --cream: #fff3da;
  --pad: 24px;
  /* the elastic curve of the button: it overshoots, then settles */
  --bounce: cubic-bezier(0.34, 1.9, 0.45, 1);
}

@media (min-width: 62em) {
  :root {
    --pad: 70px;
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  background: var(--night);
  color: var(--cream);
  font-family: 'Newsreader Variable', Georgia, serif;
  -webkit-font-smoothing: antialiased;
}

/* the poster holds the page still until the first scroll */
html.locked,
html.locked body {
  overflow: hidden;
  overscroll-behavior: none;
}

/* while the poster is up the page is amber, so Safari paints its bars amber too; the page below is hidden, or
   it would show in the strip under Safari's toolbar */
html.poster,
html.poster body {
  background: var(--amber);
}

html.poster .programme {
  visibility: hidden;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ------------------------------------------------------------------ fit to width, with CSS alone
   The hidden copy keeps the text at 16px and takes its own width, the box next to it takes the rest. A registered
   length turns 100cqi into pixels where it is written: in the box it is the whole line, in the display it is the box,
   so line / (line − box) = line / text, and tan(atan2(a, b)) = a / b divides one length by another. */
@property --fit-captured {
  syntax: '<length>';
  initial-value: 0px;
  inherits: true;
}

.fit {
  --fit-captured: initial;
  display: flex;
  container-type: inline-size;
  font-size: 16px;
  white-space: nowrap;
}

.fit__ref {
  visibility: hidden;
}

.fit__box {
  --fit-captured: 100cqi;
  --fit-space: var(--fit-captured);
  flex-grow: 1;
  container-type: inline-size;
}

.fit__display {
  --fit-captured: 100cqi;
  --fit-ratio: tan(atan2(var(--fit-space), var(--fit-space) - var(--fit-captured)));
  display: block;
  inline-size: var(--fit-space);
  font-size: clamp(1em, 1em * var(--fit-ratio), var(--fit-max, 1000px));
  text-align: center;
}

/* ------------------------------------------------------------------ the hero */
.hero {
  /* as tall as the screen with Safari's bars hidden; --bars is what they cover, so things at the bottom stay above */
  --bars: 0px;
  position: relative;
  height: 100vh;
  height: 100lvh;
  overflow: clip;
}

@supports (height: 100lvh) {
  .hero {
    --bars: calc(100lvh - 100svh);
  }
}

.top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 7;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: clamp(18px, 3.4vh, 30px) var(--pad);
  color: var(--night);
  font-family: 'Mona Sans Variable', system-ui, sans-serif;
  pointer-events: none;
}

.brand {
  margin: 0;
  font-size: 17px;
  font-weight: 720;
  font-stretch: 112%;
  letter-spacing: -0.02em;
}

.top__line {
  margin: 0;
  font-size: 13px;
  font-weight: 560;
}

/* the stage: a container, so the lines can size themselves on its height (cqh) */
.stage {
  --rect-h: min(calc(min(48vw, 50rem) / 2.05), 27svh);
  --rect-w: calc(var(--rect-h) * 2.5);
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  justify-items: center;
  align-items: center;
  height: 100%;
  padding: 72px var(--pad) calc(36px + var(--bars));
  background: var(--amber);
  container-type: size;
}

.title {
  display: contents;
}

/* the top line sits under the portal, the bottom one over it */
.line {
  position: relative;
  grid-column: 1;
  color: var(--night);
  font-family: 'Big Shoulders Variable', 'Arial Narrow', sans-serif;
  font-size: clamp(2.5rem, min(18vw, 36cqh), 35rem);
  font-weight: 800;
  line-height: 0.8;
  letter-spacing: -0.01em;
  text-align: center;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
}

.line__in {
  display: block;
}

.line--top {
  grid-row: 1;
  z-index: 1;
}

.line--bottom {
  grid-row: 3;
  z-index: 3;
}

.line__break {
  display: none;
}

.slot {
  grid-row: 2;
  grid-column: 1;
  width: var(--rect-w);
  max-width: 100%;
  height: var(--rect-h);
}

/* the portal covers the stage; the script cuts it along the frame's lower edge */
.portal {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.rect {
  position: absolute;
  background: var(--night);
  transform: scaleX(0);
}

.welcome {
  position: absolute;
  top: 64px;
  left: var(--pad);
  right: var(--pad);
  margin: 0;
  color: var(--amber);
  font-family: 'Big Shoulders Variable', 'Arial Narrow', sans-serif;
  font-weight: 800;
  line-height: 0.8;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  visibility: hidden;
}

.welcome .fit__display {
  transform-origin: 50% 100%;
}

/* the violin's own box is its place in the night */
.violin {
  position: absolute;
  top: 11vh;
  right: calc(var(--pad) + 3vw);
  width: calc((100% - 2 * var(--pad)) * 0.44);
  aspect-ratio: 600 / 1100;
  visibility: hidden;
}

.violin__art {
  display: block;
  width: 100%;
  height: auto;
}

.fade {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 4;
  height: 34%;
  background: linear-gradient(to bottom, rgba(16, 19, 46, 0), var(--night) 88%);
  visibility: hidden;
  pointer-events: none;
}

.intro {
  position: absolute;
  z-index: 5;
  top: 46%;
  left: var(--pad);
  display: flex;
  flex-direction: column;
  gap: 1em;
  width: min(30rem, 34vw);
  color: var(--cream);
  font-size: clamp(17px, 1.3vw, 20px);
  line-height: 1.4;
  visibility: hidden;
}

.intro p {
  margin: 0;
}

.hint {
  position: absolute;
  z-index: 5;
  right: var(--pad);
  bottom: calc(24px + var(--bars));
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  color: var(--night);
  font-family: 'Mona Sans Variable', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 600;
  visibility: hidden;
}

.hint svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ------------------------------------------------------------------ the button, for the keyboard: an elastic pill
   Hidden until it has the focus. With the pointer over it the words widen along the typeface's width axis and the
   pill swells with an overshoot; pressed, it squashes. */
.toggle {
  position: absolute;
  z-index: 8;
  left: 50%;
  bottom: calc(24px + var(--bars));
  display: inline-flex;
  align-items: center;
  min-height: 50px;
  padding: 0 24px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--cream);
  font-family: 'Mona Sans Variable', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 640;
  font-stretch: 100%;
  white-space: nowrap;
  cursor: pointer;
  isolation: isolate;
  translate: -50% 0;
  -webkit-tap-highlight-color: transparent;
}

/* until it has the focus it is a transparent dot, still there to be clicked (the catalogue's autopilot does) */
.toggle:not(:focus-visible) {
  width: 1px;
  height: 1px;
  min-height: 0;
  padding: 0;
  overflow: hidden;
  opacity: 0;
}

.toggle::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--night);
  box-shadow: 0 0 0 2px var(--amber);
  transition: inset 0.6s var(--bounce), transform 0.2s cubic-bezier(0.23, 1, 0.32, 1);
}

.toggle__text {
  display: inline-block;
  text-align: center;
  transition: font-stretch 0.6s var(--bounce);
}

/* the words at their widest, invisible and zero tall: they keep the room */
.toggle__text::before {
  content: attr(data-text);
  display: block;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-stretch: 125%;
}

@media (hover: hover) and (pointer: fine) {
  .toggle:hover::before {
    inset: -2px -7px;
  }

  .toggle:hover .toggle__text {
    font-stretch: 125%;
  }
}

.toggle:active::before {
  transform: scale(1.03, 0.88);
}

.toggle:focus-visible {
  outline: none;
}

/* ------------------------------------------------------------------ the page after the hero */
.programme {
  position: relative;
  padding: clamp(80px, 12vh, 140px) var(--pad) 140px;
  background: var(--night);
}

.programme__title {
  margin: 0 0 48px;
  color: var(--amber);
  font-family: 'Big Shoulders Variable', 'Arial Narrow', sans-serif;
  font-size: clamp(56px, 9vw, 150px);
  font-weight: 800;
  line-height: 0.8;
  text-transform: uppercase;
}

.programme__list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid rgba(255, 243, 218, 0.22);
}

.programme__list li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr);
  align-items: baseline;
  gap: 16px;
  padding: 22px 0;
  border-bottom: 1px solid rgba(255, 243, 218, 0.22);
}

.programme__date,
.programme__place {
  font-family: 'Mona Sans Variable', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 560;
  color: rgba(255, 243, 218, 0.72);
}

.programme__place {
  text-align: right;
}

.programme__name {
  font-size: clamp(22px, 2.2vw, 30px);
  line-height: 1.15;
}

.programme__end {
  margin: 48px 0 0;
  font-size: 20px;
}

/* ------------------------------------------------------------------ phones: the lines above and below the frame */
@media (max-width: 56.25em) {
  .stage {
    --rect-h: min(calc(100cqi / 2.54 * 1.07), 20svh);
    --rect-w: min(calc(var(--rect-h) * 2.54), 100cqi);
    grid-template-rows: minmax(0, 1fr);
    padding-top: 64px;
  }

  .line {
    grid-row: 1;
    z-index: 0;
    font-size: clamp(2.75rem, min(30vw, 21cqh), 35rem);
  }

  .line--top {
    transform: translateY(calc(-50% - var(--rect-h) / 2 - 12px));
  }

  .line--bottom {
    z-index: 3;
    transform: translateY(calc(50% + var(--rect-h) / 2 + 12px));
  }

  .line__break {
    display: inline;
  }

  .slot {
    grid-row: 1;
  }

  .welcome {
    top: 68px;
    line-height: 0.86;
  }

  .violin {
    top: 30svh;
    right: auto;
    left: 50%;
    width: 64vw;
    margin-left: -32vw;
  }

  .fade {
    height: 52%;
  }

  .intro {
    top: auto;
    bottom: calc(26px + var(--bars));
    right: var(--pad);
    width: auto;
    font-size: 16px;
  }

  .hint {
    right: 50%;
    translate: 50% 0;
  }

  .programme__list li {
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
  }

  .programme__place {
    text-align: left;
  }
}

/* ------------------------------------------------------------------ phones held low (the catalogue's preview box,
   341 × 410): the two lines a little smaller, so the bottom one ends above "Scroll to open" */
@media (max-width: 56.25em) and (max-height: 520px) {
  .line {
    font-size: clamp(2.5rem, min(30vw, 18cqh), 35rem);
  }

  .intro {
    font-size: 15px;
  }
}
