/* afterhours — base styles */

:root {
  color-scheme: light;
  --black: #000000;
  --white: #ffffff;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* The hidden attribute must always win. Its default display:none only applies
   when "display" was not set separately; on anything given flex or grid, hidden
   is quietly ignored (which is exactly what happened in the sign-in form and the
   admin panel). */
[hidden] { display: none !important; }

html, body { height: 100%; }
body.home { overflow: hidden; }   /* the landing page does not scroll, only the poster column does */

body {
  background: var(--white);
  color: var(--black);
  /* The closest freely available match to PP Neue Montreal: Inter Tight */
  font-family: "Inter Tight", "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* ---------- Header ---------- */

.header {
  position: fixed;
  z-index: 10;   /* the screens build their own layer with transform; the menu has to stay on top */
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 28px 32px;
  /* A solid block: scrolling text used to run through the menu */
  background: var(--white);
}

/* On the landing's dark footer screen the menu inverts; a white slab
   there would be a bandage across the black. Nothing scrolls under the
   menu on the landing (the poster column clips itself), so transparent
   is safe exactly there. */
body.home .header { background: transparent; }

/* With an admin signed in a third item joins the menu. We move to three columns
   so the middle one is really in the MIDDLE: space-between cannot do it because
   the sides have different widths. */
.header.isadmin {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
}

.header.isadmin .header-links { justify-self: end; }

.header-admin {
  font-size: 15px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--black);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 6px;
  text-decoration-color: rgba(0, 0, 0, 0.28);
  white-space: nowrap;
  margin: 0 14px;          /* do not let it stick to the logo on a narrow screen */
}

.logo {
  font-family: "ArchivoLogo", "Archivo", "Inter Tight", sans-serif;
  font-size: 26px;
  font-weight: 900;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--black);
  text-decoration: none;
}

/* the full stop is the mark: always red, whatever the ground */
.logo::after {
  content: ".";
  color: #d7261e;
}

.header-links {
  display: flex;
  gap: 28px;
}

.header-links a {
  font-size: 15px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--black);
  text-decoration: none;
}

/* The section you are in: a thin underline, nothing else */
.header-links a[aria-current="page"] {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 6px;
}

/* ---------- The screens ---------- */

/* Two full screens stacked; moving between them is a vertical scroll */
.screens {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  transition: transform 0.72s cubic-bezier(0.65, 0, 0.35, 1);
  transform: translateY(calc(var(--screen, 0) * -100vh));
  transform: translateY(calc(var(--screen, 0) * -100dvh));
}

.screen {
  height: 100vh;
  height: 100dvh;   /* iOS Safari: the height actually visible, minus the address bar */
}

/* ---------- The photo at the bottom right ---------- */

/* The whole photograph, uncropped. 1600x893 -> 780px wide (scaled down, stays sharp) */
.photo {
  position: fixed;
  right: 0;
  bottom: 0;
  width: 780px;
  z-index: 4;
  pointer-events: none;
  transition: transform 0.72s cubic-bezier(0.65, 0, 0.35, 1);
}

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

/* Let the top and left edges reach white: the photo should look like it is
   coming out of the page, not pasted onto it. The corner runs off screen, so
   softening these two edges is enough. */
.photo::before,
.photo::after {
  content: "";
  position: absolute;
  pointer-events: none;
}

.photo::before {
  top: 0;
  left: 0;
  right: 0;
  height: 38%;
  background: linear-gradient(to bottom,
    #ffffff 0%,
    rgba(255, 255, 255, 0.72) 30%,
    rgba(255, 255, 255, 0) 100%);
}

.photo::after {
  top: 0;
  bottom: 0;
  left: 0;
  width: 30%;
  background: linear-gradient(to right,
    #ffffff 0%,
    rgba(255, 255, 255, 0.68) 34%,
    rgba(255, 255, 255, 0) 100%);
}

/* Leaving the first screen takes the photo down with it */
body:not([data-screen="0"]) .photo {
  transform: translateY(110%);
}

/* ---------- Poster showcase ---------- */

.showcase {
  /* Exactly 3 full rows (6 posters) plus half a row (2 posters) should be
     visible, so row height = screen height / 3.5 */
  --gap: 12px;
  --top-gap: 92px;                               /* the gap under the menu (the menu is 79px) */
  --row: calc((100vh - var(--top-gap)) / 3.5);
  --row: calc((100dvh - var(--top-gap)) / 3.5);
  --poster-h: calc(var(--row) - var(--gap));
  --poster-w: calc(var(--poster-h) * 2 / 3);  /* the posters' real ratio: 400x600 = 2:3 */

  display: grid;
  grid-template-columns: calc(var(--poster-w) * 2 + var(--gap)) 1fr;
  align-items: start;
  gap: 72px;
  height: 100vh;
  height: 100dvh;
  padding: var(--top-gap) 32px 0;
}

.posters {
  height: 100%;
  overflow-y: auto;
  scrollbar-width: none;       /* Firefox */
  -ms-overflow-style: none;    /* old Edge */
  display: grid;
  grid-template-columns: repeat(2, var(--poster-w));
  gap: var(--gap);
}

.posters::-webkit-scrollbar { display: none; }   /* Chrome, Safari */

/* The frame: every poster's clickable box */
.poster {
  display: block;
  width: var(--poster-w);
  height: var(--poster-h);
  cursor: pointer;
}

/* The image: a separate SVG file. Without pointer-events the click never reaches
   the frame */
.poster-image {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* A synced night is a photograph: fill the same frame, crop, never squash */
img.poster-image {
  object-fit: cover;
  background: #ececea;
}

/* The right column: two layers in the same place, fading into each other */
.side {
  display: grid;
}

.side > * {
  grid-area: 1 / 1;
  transition: opacity 0.18s ease;
}

/* Default: the site's own type */
.intro {
  max-width: 620px;
}

.intro-1 {
  font-size: 30px;
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.25;
}

.intro-2 {
  font-size: 30px;
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.25;
  margin-top: 20px;
}

.explore-btn {
  display: inline-block;
  margin-top: 40px;
  padding: 22px 56px;
  background: var(--black);
  color: var(--white);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-decoration: none;
}

/* The scroll cue: there are four more screens on the landing page and only
   someone who tried scrolling ever found out. It fades once you leave screen 0. */
.down {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 34px;
  opacity: 0.42;
  transition: opacity 0.4s ease;
}

body:not([data-screen="0"]) .down { opacity: 0; }

.down-text {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

/* A thin vertical line with an arrow at the end; it breathes downwards */
.down-arrow {
  position: relative;
  width: 1px;
  height: 26px;
  background: var(--black);
  animation: asagi-in 2.4s ease-in-out infinite;
}

.down-arrow::after {
  content: "";
  position: absolute;
  left: -3px;
  bottom: 0;
  width: 7px;
  height: 7px;
  border-right: 1px solid var(--black);
  border-bottom: 1px solid var(--black);
  transform: rotate(45deg);
}

@keyframes asagi-in {
  0%, 100% { transform: translateY(0); opacity: 1; }
  50%      { transform: translateY(7px); opacity: 0.55; }
}

/* With reduced motion it simply stands still */
@media (prefers-reduced-motion: reduce) {
  .down-arrow { animation: none; }
}

/* While the pointer is over a poster: that event's details */
.info {
  max-width: 440px;
  opacity: 0;
  pointer-events: none;   /* it sits on top of the intro; clicks must reach the button */
}

.side.poster-hover .intro { opacity: 0; }
.side.poster-hover .info  { opacity: 1; }

.info-index {
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.04em;
  margin-bottom: 8px;
}

/* The event type: the line that shows the page carries four different kinds */
.info-type {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-bottom: 14px;
}

.info-title {
  font-size: 34px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin-bottom: 10px;
}

.info-meta {
  font-size: 14px;
  font-weight: 400;
  margin-bottom: 22px;
}

.info-body {
  font-size: 15px;
  font-weight: 400;
  line-height: 1.6;
}

/* ---------- Second screen: the big heading on the right ---------- */

.screen2 {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  /* top: start well below the menu (79px) · bottom: a sensible gap */
  padding: 150px 32px 60px;
}

.screen2-title {
  flex: 0 0 auto;
  width: 34%;
  /* vw: scales with the column width, so the wrapping never changes. vh: stops
     it overflowing on short screens. 124px at 1440x900 = 6 lines. */
  font-size: min(8.6vw, 14.5vh);
  font-weight: 700;
  line-height: 0.93;
  letter-spacing: -0.04em;
}

/* --- Second screen: the deck on the left (2 cards) --- */

.deck2 {
  flex: 1;
  align-self: stretch;
  position: relative;
}

.card2 {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 313px;
  height: 470px;          /* about 4.6 times the area of a poster in the grid above */
  margin: -235px 0 0 -156px;
  cursor: grab;
  touch-action: none;
  user-select: none;
}

.card2 object {
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;   /* let the drag reach the card itself */
}

/* Live, the demo card is a photograph: fill the frame, crop, never squash */
.card2 img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  pointer-events: none;
  background: #ececea;
}

.card2.dragging {
  cursor: grabbing;
}

/* The animation for snapping back or flying away when released */
.card2.soft {
  transition: transform 0.34s cubic-bezier(0.22, 0.61, 0.36, 1), opacity 0.34s ease;
}

/* --- Second screen: the phone that opens once the deck is done --- */

.phone {
  position: absolute;
  left: 50%;
  top: 50%;
  height: 600px;              /* clearly larger than a card */
  aspect-ratio: 9 / 19.5;     /* phone ratio */
  background: var(--black);
  border-radius: 34px;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.94);
  transition: opacity 0.4s ease,
              transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1),
              height 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
  pointer-events: none;
}

.phone.open {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* --- Inside the phone --- */

.phone-body {
  height: 100%;
  padding: 28px 22px 22px;
  overflow: hidden;
  color: var(--white);
}

.phone-top {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}

.phone-poster {
  flex: 0 0 auto;
  width: 50px;
  height: 75px;
  display: block;
  pointer-events: none;
}

img.phone-poster { object-fit: cover; background: #ececea; }

.phone-title {
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.2;
  margin-bottom: 6px;
}

.phone-meta {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.1em;
  opacity: 0.6;
}

.phone-label {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.55;
  margin: 20px 0 10px;
}

.phone-list {
  list-style: none;
}

.phone-list li {
  padding: 13px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.phone-list li:last-child { border-bottom: none; }

.phone-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 3px;
}

.phone-name {
  font-size: 14px;
  font-weight: 500;
}

.phone-status {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.6;
}

.phone-line {
  font-size: 13px;
  line-height: 1.4;
  opacity: 0.82;
}

/* --- The closing line that arrives once the phone is gone --- */

.last-line {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 430px;
  font-size: 34px;
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.18;
  opacity: 0;
  transform: translate(-50%, -50%) translateY(10px);
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
  pointer-events: none;
}

.last-line.open {
  opacity: 1;
  transform: translate(-50%, -50%);
}

/* ---------- Background music: the app's sound control, under the menu ----------
   A small word and a dot. On: "sound on" and the dot takes the app's spot
   blue. Held: a short genre list drops under it. */

.sound {
  position: fixed;
  top: 92px;
  right: 32px;
  z-index: 5;
  text-align: right;
}

.sound-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: none;
  background: none;
  padding: 6px 0;
  cursor: pointer;
  color: var(--black);
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 13px;
  letter-spacing: 0.015em;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.sound-toggle:active { opacity: 0.6; }

.sound-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 1px solid currentColor;
  flex: none;
}
.sound-toggle.on .sound-dot,
.sound-genres .on .sound-dot { background: #2b3ecf; border-color: #2b3ecf; }

/* The genre list: ink ground, paper line on top, like the app's sheet */
.sound-genres {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 220px;
  padding: 14px 18px 12px;
  background: #161512;
  border-top: 1px solid #f3f1ec;
  text-align: left;
}
.sound-head {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #8a877f;
  margin-bottom: 2px;
}
.sound-genres button {
  display: flex;
  width: 100%;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border: none;
  border-bottom: 1px solid #2a2824;
  background: none;
  cursor: pointer;
  color: #8a877f;
  font-family: inherit;
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.02em;
  text-align: left;
}
.sound-genres button.on { color: #f3f1ec; }
.sound-genres button:hover { color: #f3f1ec; }
.sound-note {
  margin-top: 10px;
  font-size: 11px;
  color: #8a877f;
}

/* --- The hint that sits to the left of the card, vertically centred --- */

.swipe-hint {
  position: absolute;
  top: 50%;
  /* half a card (156px) plus a 30px gap to the left */
  right: calc(50% + 186px);
  transform: translateY(-50%);
  white-space: nowrap;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 12px;
  letter-spacing: 0.14em;
  transition: opacity 0.35s ease;
}

.swipe-hint.hidden { opacity: 0; }

/* ======================================================================= PHONE
   (<= 720px) The desktop layout lives outside this block; this only changes
   narrow screens.
   ======================================================================= */

@media (max-width: 720px) {

  /* --- Menu --- */
  /* Five tabs plus the logo did not fit on one line at 375px: "i prefer maps"
     broke across three lines and climbed over the logo. The menu moved to its
     own row. */
  .header {
    padding: 14px 16px 10px;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 6px 0;
  }

  .header.isadmin { display: flex; }   /* three columns are unnecessary on a phone */

  .logo { font-size: 22px; flex: 1 0 100%; }

  .header-links {
    flex: 1 0 100%;
    gap: 14px;
    flex-wrap: wrap;
  }

  .header-links a { font-size: 12px; white-space: nowrap; }
  .header-admin { font-size: 12px; margin: 0; order: 1; }

  /* On a phone the photo was covering half the screen */
  .photo { display: none; }

  /* --- Sound: bottom right, clear of the wrapped menu --- */
  .sound { top: auto; bottom: 14px; right: 16px; }
  .sound-genres { top: auto; bottom: calc(100% + 8px); border-top: none; border-bottom: 1px solid #f3f1ec; }

  /* --- Screen 0: text on top, posters below --- */
  .showcase {
    display: flex;
    flex-direction: column;
    gap: 0;                      /* the 72px column gap on desktop would become a row gap here */
    padding: 74px 16px 0;
  }

  .side { order: -1; }            /* the intro text goes above the posters */
  .info { display: none; }       /* there is no hover on touch */
  .intro { max-width: none; }
  .intro-1, .intro-2 { font-size: 20px; line-height: 1.25; }
  .intro-2 { margin-top: 12px; }

  .explore-btn {
    margin-top: 18px;
    padding: 14px 34px;
    font-size: 16px;
  }

  .posters {
    --pw: calc((100vw - 42px) / 2);
    flex: 1;
    min-height: 0;
    height: auto;
    grid-template-columns: repeat(2, var(--pw));
    gap: 10px;
    margin-top: 20px;
    padding-bottom: 86px;        /* room for the sound bar at the bottom */
  }

  .poster {
    width: var(--pw);
    height: calc(var(--pw) * 1.5);
  }

  /* --- Screen 1: heading on top, card below --- */
  .screen2 {
    flex-direction: column;
    align-items: stretch;
    padding: 74px 16px 96px;
  }

  .screen2-title {
    order: -1;
    width: auto;
    font-size: 34px;
    line-height: 1.06;
    letter-spacing: -0.03em;
  }

  .deck2 { flex: 1; margin-top: 18px; }

  /* The closing line rises to where the heading stands, and the two were
     printed on top of each other. The heading steps aside for it. */
  .screen2-title { transition: opacity 0.4s ease; }
  .screen2.closing .screen2-title { opacity: 0; }

  .card2 {
    width: 56vw;
    height: calc(56vw * 1.5);
    margin: calc(56vw * -0.75) 0 0 calc(56vw / -2);
  }

  .phone {
    height: 62vh;
    height: 62dvh;
    border-radius: 30px;
  }

  /* Inside the phone: the desktop scale overflowed at this size */
  .phone-body { padding: 22px 18px 18px; }
  .phone-poster { width: 42px; height: 63px; }
  .phone-title { font-size: 16px; margin-bottom: 5px; }
  .phone-meta { font-size: 8.5px; }
  .phone-label { font-size: 8.5px; margin: 16px 0 8px; }
  .phone-list li { padding: 10px 0; }
  .phone-name { font-size: 12px; }
  .phone-status { font-size: 8px; }
  .phone-line { font-size: 11px; }

  /* The final state: the desktop pixel values would push the text off screen here */
  .deck2.last-state .last-line.open {
    transform: translate(-50%, calc(-50% - 28dvh));
  }

  .deck2.last-state .phone.open {
    height: 52dvh;
    transform: translate(-50%, calc(-50% + 6dvh)) scale(1);
  }

  .last-line {
    width: calc(100vw - 48px);
    font-size: 23px;
  }

  /* The hint sits under the card rather than beside it */
  .swipe-hint {
    top: auto;
    right: auto;
    left: 50%;
    bottom: 4%;
    transform: translateX(-50%);
    font-size: 11px;
  }
}

/* --- Final state: the text rises, the phone comes back underneath --- */

.deck2.last-state .last-line.open {
  transform: translate(-50%, calc(-50% - 305px));   /* to the very top of the area */
}

.deck2.last-state .phone.open {
  height: 560px;
  transform: translate(-50%, calc(-50% + 45px)) scale(1);
}

/* --- What the card does when someone tries to scroll past it --- */

@keyframes card-jump {
  0%   { transform: translateX(0); }
  22%  { transform: translateX(16px) rotate(1.4deg); }
  48%  { transform: translateX(-9px) rotate(-0.8deg); }
  72%  { transform: translateX(5px) rotate(0.4deg); }
  100% { transform: translateX(0); }
}

.card2.jump {
  animation: card-jump 0.46s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}

/* ---------- Third screen: the card strip ---------- */

.screen3 {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 60px;
  /* top and bottom have to match: otherwise the middle of the phone and the
     middle of the strip drift apart */
  padding: 92px 32px;
}

/* A strip running straight through the middle of the screen, behind the phone
   and the text */
.s3-strip {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 300px;
  display: flex;
  align-items: center;
  overflow: hidden;
  z-index: 0;
}

.s3-rail {
  flex: 0 0 auto;      /* has to be as wide as its contents, or the loop drifts */
  display: flex;
  gap: 44px;
  will-change: transform;
  animation: k3-kay 110s linear infinite;   /* 10 pairs of cards, the same speed */
}

@keyframes k3-kay {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* The front and back of one card as a single object: two faces touching, then a gap */
.s3-pair {
  flex: 0 0 auto;
  display: flex;
  gap: 6px;
}

.s3-pair svg {
  display: block;
  width: 180px;
  height: 270px;
}

.s3-left,
.s3-right {
  position: relative;
  z-index: 2;
  font-size: min(5.3vw, 9vh);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.035em;
}

/* The strip crosses the exact middle, so the two lines sit diagonally: the left
   one high, the right one low — that way the cards never hit the letters */
.s3-left {
  align-self: start;
  margin-top: 40px;
}

.s3-right {
  align-self: end;
  margin-bottom: 40px;
  text-align: right;
}

/* ---------- Sixth screen: the footer ---------- */

.screen6 {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 92px 32px 48px;
  background: #0a0a0a;
  color: #f2f2f0;
}

.s6-top {
  display: flex;
  gap: 26px;
  align-items: baseline;
  letter-spacing: -0.01em;
}

.s6-clock {
  font-size: 14px;
  font-weight: 400;
}

.s6-counter {
  font-size: 14px;
  font-weight: 400;
  opacity: 0.62;
}

.s6-manifesto {
  font-size: min(5.2vw, 8.8vh);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.03em;
  max-width: 24ch;
}

/* The footnote at the end of the first sentence */
.s6-note {
  font-size: 15px;
  font-weight: 400;
  letter-spacing: 0;
  opacity: 0.5;
  vertical-align: super;
  margin-left: 10px;
  white-space: nowrap;
}

.s6-sub {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
}

.s6-cities,
.s6-links {
  list-style: none;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: -0.01em;
  line-height: 1.85;
}

/* We are not hiding how small we are */
.s6-cities li { opacity: 0.28; }
.s6-cities li.open { opacity: 1; }
.s6-cities li.soon { opacity: 0.55; }
.s6-cities li.soon span { opacity: 0.6; margin-left: 6px; }

.s6-links a {
  color: inherit;
  text-decoration: none;
  opacity: 0.55;
}

.s6-button {
  flex: 0 0 auto;
  padding: 22px 56px;
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-decoration: none;
  background: #f2f2f0;
  color: #0a0a0a;
}

/* On the black footer: the menu inverts and the sound bar disappears completely */

.header a { transition: color 0.5s ease; }
.sound { transition: opacity 0.5s ease; }

body[data-screen="5"] .header a { color: #f2f2f0; }

body[data-screen="5"] .sound {
  opacity: 0;
  pointer-events: none;
}

/* ---------- Fourth screen: who is playing ----------
   Just the heading and its sentence, centred at the top of the screen. */
.screen-djs {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 92px 32px;
  text-align: center;
}

/* The walnut knob under the text, seen straight on. The canvas is square
   and a little bigger than the knob so its shadow has room. */
.sd-knob {
  width: min(640px, 62vh, 96vw);
  aspect-ratio: 1;
  margin-top: 2vh;
  cursor: grab;
  touch-action: none;
  outline: none;
  border-radius: 50%;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.sd-knob.ready { opacity: 1; }
.sd-knob.turning { cursor: grabbing; }
.sd-knob:focus-visible { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25); }
.sd-knob canvas {
  display: block;
  width: 100%;
  height: 100%;
  /* the shadow fades out before the square edge of the canvas */
  -webkit-mask-image: radial-gradient(closest-side, #000 72%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 72%, transparent 100%);
}

.sd-title {
  font-size: min(5.3vw, 9vh);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.035em;
  margin-bottom: 22px;
}

.sd-sub {
  font-size: 20px;
  font-weight: 400;
  line-height: 1.4;
  opacity: 0.72;
  max-width: 34ch;
  margin: 0 auto;
}

/* radio.js swaps the heading for artist / song / channel: a short fade */
.sd-title, .sd-sub { transition: opacity 0.16s ease; }
.sd-title.swap, .sd-sub.swap { opacity: 0; }

/* Two buttons on the footer screen: out, and to the app */
.s6-buttons { display: flex; gap: 14px; flex-wrap: wrap; }

@media (max-width: 900px) {
  .screen-djs { padding: 84px 16px 40px; }
  .sd-knob { width: min(460px, 100vw, 54vh); }
  .sd-title { font-size: min(12vw, 60px); }
  .sd-sub { font-size: 16px; }
}

/* ---------- Fourth screen: the model of the city ---------- */

.screen4 {
  position: relative;
  background: #0c0c0d;
  color: #f0f0ee;
  overflow: hidden;
}

.s4-stage {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: grab;
}

.s4-stage:active { cursor: grabbing; }

.s4-text {
  position: absolute;
  top: 112px;
  left: 32px;
  max-width: 520px;
  pointer-events: none;
}

.s4-eyebrow {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.55;
  margin-bottom: 16px;
}

.s4-title {
  font-size: 96px;
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 0.98;
  margin-bottom: 18px;
}

.s4-sub {
  font-size: 20px;
  font-weight: 400;
  line-height: 1.4;
  opacity: 0.72;
}

/* On the city screen the menu inverts against the dark ground */
body[data-screen="4"] .header a { color: #f0f0ee; }
body[data-screen="4"] .sound { opacity: 0; pointer-events: none; }

/* The right side of the globe screen: what is within walking distance tonight */
.s4-near {
  position: absolute;
  top: 118px;
  right: 32px;
  width: 300px;
  text-align: right;
  pointer-events: none;
}

.s4-near-title {
  font-size: 13px;
  font-weight: 400;
  opacity: 0.5;
  padding-bottom: 12px;
  margin-bottom: 6px;
  border-bottom: 1px solid rgba(240, 240, 238, 0.22);
}

.s4-near ul { list-style: none; }

.s4-near li {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 10px;
  padding: 7px 0;
  font-size: 15px;
  font-weight: 400;
}

.s4-near li em {
  font-style: normal;
  font-size: 12px;
  opacity: 0.42;
}

.s4-near li b {
  font-weight: 400;
  font-size: 13px;
  opacity: 0.72;
  min-width: 52px;
}

.s4-near-sub {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(240, 240, 238, 0.22);
  font-size: 12px;
  opacity: 0.45;
}

/* ---------- Event page ---------- */

.event {
  display: flex;
  align-items: flex-start;
  padding: 148px 64px 64px;
}

.event-poster {
  flex: 0 0 auto;
  display: block;
  height: calc(100vh - 212px);
  height: calc(100dvh - 212px);
  max-height: 760px;
  aspect-ratio: 2 / 3;
  pointer-events: none;
}

/* The breadcrumb showing where you are inside a section */
.crumb {
  position: fixed;
  top: 104px;
  left: 64px;
  display: flex;
  gap: 9px;
  font-size: 13px;
  font-weight: 400;
}

.crumb a {
  color: var(--black);
  text-decoration: none;
  opacity: 0.55;
}

.crumb span { opacity: 0.55; }
.crumb span:last-child { opacity: 1; }

/* ---------- explore: the wall ---------- */

/* The filter: country / city / category / date. Not a native <select>: our own
   list that opens on click. The type is the menu's, the panel white with a
   hairline border. */
.ex-filter {
  display: flex;
  gap: 26px;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  position: relative;
  z-index: 30;
}

.fl { position: relative; }

.fl-button {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: inherit;
  font-size: 15px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--black);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

/* A small downward arrow; it flips up when open */
.fl-button::after {
  content: "";
  width: 6px;
  height: 6px;
  margin-top: -4px;
  border-right: 1.4px solid var(--black);
  border-bottom: 1.4px solid var(--black);
  transform: rotate(45deg);
  opacity: 0.5;
  transition: transform 0.18s ease;
}

.fl.open .fl-button::after { transform: translateY(3px) rotate(-135deg); }
.fl.open .fl-value { text-decoration: underline; text-underline-offset: 5px; }

.fl-list {
  position: absolute;
  top: calc(100% + 12px);
  left: 50%;
  transform: translateX(-50%);
  min-width: 190px;
  max-height: 320px;
  overflow-y: auto;
  padding: 6px 0;
  background: var(--white);
  border: 1px solid rgba(0, 0, 0, 0.14);
  scrollbar-width: none;
}

.fl-list::-webkit-scrollbar { width: 0; }

.fl-item {
  display: flex;
  align-items: baseline;
  gap: 14px;
  width: 100%;
  font-family: inherit;
  font-size: 15px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--black);
  background: none;
  border: 0;
  padding: 9px 16px;
  cursor: pointer;
  text-align: left;
}

/* Continent heading: it separates the list and is not clickable */
.fl-group {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.38;
  padding: 12px 16px 5px;
}

.fl-group:first-child { padding-top: 4px; }

.fl-item:hover { background: rgba(0, 0, 0, 0.05); }
.fl-item.selected { font-weight: 500; }

/* Empty cities are not hidden, they just say that they are empty */
.fl-item.empty { opacity: 0.42; }

.fl-note {
  margin-left: auto;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.5;
  font-style: normal;
}

/* The wall: the deck's filter line stays where it was, the deck under it
   is a grid of posters — six across, 2:3, soonest first. The words come
   on hover: a white band slides up from the bottom of the poster with
   the name, the day, the time and the place. Nothing else on the page. */
.ex-wall-page {
  min-height: 100vh;
  min-height: 100dvh;
  padding: 104px 32px 80px;
}

.ex-wall-page .ex-filter { margin-bottom: 34px; }

.ex-wall {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
}

.ex-tile {
  position: relative;
  display: block;
  overflow: hidden;
  color: var(--black);
  text-decoration: none;
  background: #f2f2f2;
}

.ex-tile img,
.ex-tile object {
  display: block;
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  pointer-events: none;
}

.ex-tile-cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 10px 10px 12px;
  background: var(--white);
  transform: translateY(100%);
  transition: transform 0.28s cubic-bezier(0.65, 0, 0.35, 1);
}

.ex-tile:hover .ex-tile-cap,
.ex-tile:focus-visible .ex-tile-cap { transform: none; }

.ex-tile-name {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ex-tile-line {
  margin-top: 4px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.45;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The tally in the free corner, opposite the footer strip */
.ex-tally {
  position: fixed;
  z-index: 5;
  left: 32px;
  bottom: 26px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.4;
}

/* Nothing in the window: one line where the wall would start */
.ex-empty {
  font-size: 21px;
  font-weight: 500;
  letter-spacing: -0.015em;
  text-align: center;
  padding-top: 40px;
}

@media (max-width: 1180px) {
  .ex-wall { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 720px) {
  .ex-wall-page { padding: 92px 16px 72px; }
  .ex-wall-page .ex-filter { gap: 16px; margin-bottom: 26px; }
  .fl-button { font-size: 13px; }
  .fl-list { min-width: 168px; }
  .fl-item { font-size: 14px; padding: 8px 14px; }
  .ex-wall { grid-template-columns: repeat(2, 1fr); gap: 8px; }
  /* No hover on a phone: the band stands under the poster */
  .ex-tile-cap { position: static; transform: none; padding: 8px 0 0; }
  .ex-tally { left: 16px; }
}

/* ---------- beforehours: the comment column on the event page ---------- */

.c-write:empty { display: none; }

.c-write {
  margin-bottom: 30px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

.c-write-field {
  width: 100%;
  font-family: inherit;
  font-size: 15px;
  line-height: 1.5;
  color: var(--black);
  background: none;
  border: 1px solid rgba(0, 0, 0, 0.16);
  padding: 10px 12px;
  resize: vertical;
}

.c-write-field::placeholder { color: rgba(0, 0, 0, 0.32); }
.c-write-field:focus { outline: none; border-color: rgba(0, 0, 0, 0.45); }

.c-write-button {
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  color: var(--white);
  background: var(--black);
  border: 0;
  padding: 9px 22px;
  cursor: pointer;
}

.c-write-button:disabled { opacity: 0.45; cursor: default; }

.c-write-status { font-size: 13px; opacity: 0.6; }

.c-write-invite {
  font-size: 14px;
  color: var(--black);
  opacity: 0.55;
  text-decoration: underline;
  text-underline-offset: 5px;
}

.c-group + .c-group { margin-top: 36px; }

/* Whatever is left over from earlier nights sits a little further back */
.c-group.old { opacity: 0.68; }

.c-group-title {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.5;
  margin-bottom: 16px;
}

.c-topic + .c-topic { margin-top: 24px; }

.c-top {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 5px;
}

.c-who { font-size: 14px; font-weight: 500; }
.c-when { font-size: 12px; opacity: 0.45; }

.c-text {
  font-size: 15px;
  font-weight: 400;
  line-height: 1.55;
}

/* Replies under the topic, joined by a thin line */
.c-replies {
  margin-top: 12px;
  padding-left: 15px;
  border-left: 1px solid rgba(0, 0, 0, 0.13);
}

.c-reply + .c-reply { margin-top: 12px; }
.c-replies .c-text { font-size: 14px; }

.c-none { font-size: 15px; opacity: 0.5; }

/* ---------- login ---------- */

.page {
  min-height: 100vh;
  min-height: 100dvh;
  padding: 104px 32px 48px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 620px;
}

.page-title {
  font-size: min(7vw, 76px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 0.98;
  margin-bottom: 44px;
}

.page-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

.page-label {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.5;
}

/* Not a box, a single line underneath: plain, like the rest of the site */
.page-field {
  width: min(100%, 420px);
  font-family: inherit;
  font-size: 21px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--black);
  background: none;
  border: 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.25);
  padding: 6px 0 10px;
}

.page-field::placeholder { color: rgba(0, 0, 0, 0.28); }
.page-field:focus { outline: none; border-bottom-color: var(--black); }

.page-button {
  text-decoration: none;      /* also used as an <a> */
  margin-top: 20px;
  padding: 18px 44px;
  background: var(--black);
  color: var(--white);
  font-family: inherit;
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.01em;
  border: 0;
  cursor: pointer;
}

.page-button:disabled { opacity: 0.45; cursor: default; }

/* Apple and Google: the same account as in the app (session.js AH.signInWith). */
.page-oauth { display: flex; flex-direction: column; gap: 10px; margin-top: 28px; max-width: 360px; }
.page-or { margin: 0 0 4px; font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.55; }
.page-oauth-button {
  padding: 14px 22px;
  background: transparent;
  color: var(--black);
  border: 1px solid var(--black);
  border-radius: 999px;
  font-family: inherit;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  text-align: center;
}
.page-oauth-button:hover { background: var(--black); color: var(--white); }

.page-note {
  margin-top: 22px;
  font-size: 15px;
  opacity: 0.6;
  min-height: 22px;
}

.page-note.error { opacity: 1; color: #c22a1f; }
.page-note.ok { opacity: 1; }

.page-note.waiting {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.5;
}

.page-who { font-size: 21px; font-weight: 500; letter-spacing: -0.01em; }

/* Account sections: the handle and friends */
.account { margin-top: 40px; }

.account-title {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.5;
  margin-bottom: 6px;
}

.account-about { font-size: 14px; opacity: 0.55; margin-bottom: 14px; }

.account-row { display: flex; align-items: flex-end; gap: 14px; }

.account-field {
  width: min(100%, 260px);
  font-family: inherit;
  font-size: 17px;
  color: var(--black);
  background: none;
  border: 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.25);
  padding: 4px 0 8px;
}

.account-field::placeholder { color: rgba(0, 0, 0, 0.28); }
.account-field:focus { outline: none; border-bottom-color: var(--black); }

.account-button {
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  color: var(--white);
  background: var(--black);
  border: 0;
  padding: 9px 20px;
  cursor: pointer;
}

.account-status { font-size: 13px; opacity: 0.6; margin-top: 10px; min-height: 18px; }


.page-signout {
  margin-top: 18px;
  font-family: inherit;
  font-size: 15px;
  color: var(--black);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 5px;
  opacity: 0.6;
}

@media (max-width: 720px) {
  .page { padding: 92px 16px 56px; }
  .page-title { font-size: 38px; margin-bottom: 32px; }
  .page-field { font-size: 18px; }
  .page-button { font-size: 16px; padding: 15px 34px; }
}

/* ---------- maps: the hand-drawn schematic of Munich ---------- */

/* This replaced the globe: a single SVG, no animation loop at all. */
/* Let the schematic fill the whole area and the text sit on top of it: the map
   is content, the text is a label. Stacking them doubled the size of the
   schematic. */
.map {
  height: 100vh;
  height: 100dvh;
  position: relative;
  overflow: hidden;
}

.map-text {
  position: absolute;
  top: 96px;
  left: 32px;
  z-index: 2;
  pointer-events: none;
}

.map-title {
  font-size: min(5.2vw, 60px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
}

.map-sub { font-size: 15px; opacity: 0.5; margin-top: 4px; }

/* An SVG is a replaced element: inset does not stretch it, it sizes itself from
   its own internal measurements. So we position the box and place the SVG inside
   it. */
.map-schema-box {
  position: absolute;
  inset: 72px 24px 52px;
}

/* --- maps is closed on the web ---
   The schematic stays, faded to a memory, and nothing on it answers;
   one line in the middle says where it lives now. */
.map.closed .map-schema-box {
  opacity: 0.14;
  pointer-events: none;
}

.map.closed .map-sub { display: none; }   /* hover advice would be a lie */
.map.closed .map-footline { display: none; }   /* so would the tally */

.map-closed {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 0 24px;
  pointer-events: none;
}

.map-closed-line {
  font-size: min(5.2vw, 44px);
  font-weight: 500;
  letter-spacing: -0.03em;
  text-align: center;
}

/* "preview." — reads as a link, still black; one day it starts the
   reveal animation, today it deliberately does nothing. */
.map-preview {
  pointer-events: auto;
  background: none;
  border: none;
  padding: 0 0 2px;
  cursor: pointer;
  color: var(--black);
  font-family: inherit;
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.01em;
  border-bottom: 1px solid rgba(0, 0, 0, 0.35);
}

.map-preview:hover { border-bottom-color: var(--black); }

.map-schema { width: 100%; height: 100%; display: block; }

/* --- the lines of the schematic --- */

.map-park { fill: #f0f1ed; stroke: none; }

.map-river {
  fill: none;
  stroke: #dde2e6;
  stroke-width: 11;
  stroke-linecap: round;
}

.map-ring-outer, .map-ring-inner {
  fill: none;
  stroke: rgba(0, 0, 0, 0.17);
  stroke-width: 1.2;
}

.map-link path {
  fill: none;
  stroke: rgba(0, 0, 0, 0.12);
  stroke-width: 1;
}

.map-station { fill: none; stroke: rgba(0, 0, 0, 0.35); stroke-width: 1.4; }

.map-label text {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  fill: rgba(0, 0, 0, 0.38);
}

.map-label-park { fill: rgba(0, 0, 0, 0.22) !important; }
.map-label-station { font-size: 8.5px !important; }

/* --- the nights --- */

.map-dot { cursor: pointer; }
.map-dot-target { fill: transparent; }

.map-dot-circle {
  fill: var(--black);
  transition: r 0.16s ease, fill 0.16s ease;
}

.map-dot:hover .map-dot-circle,
.map-dot.over .map-dot-circle { r: 8; }

.map-dot:focus-visible .map-dot-circle { r: 8; }
.map-dot:focus { outline: none; }

/* --- the night under the pointer --- */

.map-card {
  position: absolute;
  z-index: 2;
  right: 32px;
  top: 96px;
  max-width: 300px;
  text-align: right;
  pointer-events: none;
}

.map-card-kind {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  opacity: 0.5;
  margin-bottom: 6px;
}

.map-card-name { font-size: 26px; font-weight: 500; letter-spacing: -0.02em; }
.map-card-meta { font-size: 14px; opacity: 0.6; margin-top: 4px; }

.map-footline {
  position: absolute;
  left: 32px;
  bottom: 26px;
  z-index: 2;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.38;
}

@media (max-width: 720px) {
  .map-text { top: 84px; left: 16px; }
  .map-schema-box { inset: 150px 8px 64px; }
  .map-footline { left: 16px; bottom: 18px; }
  .map-title { font-size: 34px; }
  .map-sub { font-size: 13px; }
  .map-card { right: 16px; top: 84px; text-align: right; max-width: 46vw; }
  .map-card-name { font-size: 20px; }
}

/* ---------- card collection ---------- */

/* The line and the small print on the left (unmoved), three sample cards side by
   side on the right. The cards speak the same language as the poster generator,
   in a lighter palette. */
.cc {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(0, 1.55fr);
  gap: 56px;
  align-items: center;
  max-width: 1240px;
}

/* Keep the text and the button from overlapping (same as the friends invitation) */
.cc-left {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.cc-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.cc-card { min-width: 0; }

/* The card is clickable: front and back sit in the same place, one of them visible */
.cc-flip {
  display: grid;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.cc-face {
  grid-area: 1 / 1;
  transition: opacity 0.24s ease;
}

.cc-face svg {
  display: block;
  width: 100%;
  height: auto;
}

.cc-back { opacity: 0; }
.cc-card.flipped .cc-face:not(.cc-back) { opacity: 0; }
.cc-card.flipped .cc-back { opacity: 1; }

.cc-card figcaption {
  margin-top: 10px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.4;
}

@media (max-width: 900px) {
  .cc {
    display: flex;
    flex-direction: column;
    gap: 34px;
  }
  .cc-cards { gap: 12px; }
}

/* friends&more: the title sits at the top left, where it stood when the
   page still had two columns under it. */
body.friends .page,
body.djs .page {
  justify-content: start;
  max-width: 1240px;
  padding-top: 132px;
}

@media (max-width: 900px) {
  body.friends .page,
body.djs .page { padding-top: 104px; }
}

/* --- friends&more is closed on the web ---
   Like maps, but with nothing behind the line: the title, then white,
   and the same centred line saying where it lives now. The page is held
   to one screen so the line sits in the middle of it. */
body.friends .fr.closed,
body.djs .fr.closed {
  height: 100vh;
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
}

.fr-closed {
  position: fixed;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 0 24px;
  pointer-events: none;
}

/* ---------- help ---------- */

/* The same language as the login and friends pages, but the content is long, so
   it is not centred vertically: it starts at the top and runs. */
/* The strip should span the whole page, so its container is wide; the text to be
   read stays in a narrow column, but on this page a CENTRED one. */
.help {
  max-width: 1400px;
  padding: 128px 32px 96px;
}

.help-body {
  max-width: 660px;
  margin: 0 auto;
}

/* The strip above the heading: three numbers side by side with hairlines between
   them. Left, centre, right — the edge habit from the rest of the site. */
.stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid rgba(0, 0, 0, 0.12);
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
  margin-bottom: 64px;
}

/* Every number centred in its own cell: the label as well as the figure. */
.stat {
  padding: 22px 24px 24px;
  border-left: 1px solid rgba(0, 0, 0, 0.09);
  text-align: center;
}

.stat:first-child { border-left: 0; }

.stat-label {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.42;
  line-height: 1.5;
  min-height: 28px;
}

.stat-value {
  margin-top: 8px;
  font-size: clamp(30px, 3.4vw, 46px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
}

@media (max-width: 720px) {
  /* They do not fit side by side on a phone: stacked, all aligned left */
  .help { padding: 104px 16px 64px; }
  .stats { grid-template-columns: minmax(0, 1fr); margin-bottom: 34px; }
  .stat {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 0;
    border-left: 0;
    border-top: 1px solid rgba(0, 0, 0, 0.07);
    text-align: left !important;
  }
  .stat:first-child { border-top: 0; }
  .stat-label { min-height: 0; }
  .stat-value { margin-top: 0; font-size: 22px; }
  .stat { padding: 12px 0; }
}

.help .page-title {
  margin-bottom: 20px;
  text-align: center;
}

.help-text {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.62;
  opacity: 0.78;
}

@media (max-width: 720px) {
  .help { padding: 104px 16px 64px; }
  .help .page-title { font-size: 38px; }
  .help-text { font-size: 15px; }
}

/* ---------- The footer: the small strip at the bottom of every page ---------- */

/* The same language as the fine print under the menu: mono, 10px, tracked out.
   Not part of the content — the colophon standing at the foot of the page. */
.foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px 24px;
  padding: 22px 32px;
  border-top: 1px solid rgba(0, 0, 0, 0.09);
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.foot-name { opacity: 0.38; }

.foot-links {
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
}

.foot-links a {
  color: var(--black);
  text-decoration: none;
  opacity: 0.38;
  transition: opacity 0.25s ease;
}

.foot-links a:hover { opacity: 1; }
.foot-links a[aria-current="page"] { opacity: 1; }

/* Full-screen pages (explore, maps) do not scroll vertically: there the strip
   sits in the free corner without a rule and does not push the layout at all. */
.foot.thin {
  position: fixed;
  z-index: 5;
  bottom: 26px;
  left: 32px;
  width: auto;
  padding: 0;
  border-top: 0;
}

.foot.thin .foot-name { display: none; }
.foot.thin.right { left: auto; right: 32px; }

/* Let the strip really stand at the FOOT of the page. On pages with little
   content (the event pages while they were still empty) it was sticking right
   under the menu: the body lays out as a column, and the strip is pushed down by
   whatever space is left. */
body:has(> .foot:not(.thin)) {
  height: auto;
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

body:has(> .foot:not(.thin)) > .foot { margin-top: auto; }

/* Centred pages leave room for the strip; without it every one of them started
   scrolling by exactly the height of a strip. */
.page { min-height: calc(100dvh - 58px); }

/* ---------- The account page: the shortcuts beside the sign-in ---------- */

/* Sign-in on the left, a shortcut in the middle and one at the far right. All
   three start on the same line: the row itself is centred vertically, the
   columns are aligned from the top. */
.account-page {
  max-width: none;
  display: grid;
  /* The third column is as wide as its content: that way the block on the right
     lands on the same edge as "login" in the menu and "agb" in the footer. The
     first two are flexible at 1.9:1 — the left heading staying on one line
     depends on that ratio, and a fixed width made the middle one overflow on a
     narrow screen. */
  grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr) auto;
  gap: 44px;
  align-content: center;
  align-items: start;
}

/* All three headings at one size. They shrink with the width of the page (5vw
   rather than 7vw): standing side by side, a fixed 76px had them climbing over
   each other on a narrow screen. */
.account-page .page-title,
.sc-title {
  font-size: min(5vw, 72px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 0.98;
}

.sc-sub {
  margin-top: 20px;
  font-size: 15px;
  opacity: 0.55;
}

.sc-link {
  display: inline-block;
  margin-top: 20px;
  padding-bottom: 2px;
  color: var(--black);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-decoration: none;
  border-bottom: 1px solid rgba(0, 0, 0, 0.3);
  transition: border-color 0.25s ease;
}

.sc-link:hover { border-bottom-color: var(--black); }

/* ---------- Legal pages ---------- */

.legal { max-width: 700px; }

/* Until these texts settle, let them say for themselves what they are */
.legal-warning {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
  margin-bottom: 18px;
}

.legal .account { margin-bottom: 30px; }
.legal .account-title { margin-bottom: 8px; }
.legal .help-text + .help-text { margin-top: 12px; }

.legal-list {
  list-style: none;
  font-size: 16px;
  line-height: 1.62;
  opacity: 0.78;
}

.legal-list li { padding-left: 18px; position: relative; }
.legal-list li::before { content: "—"; position: absolute; left: 0; opacity: 0.5; }

.legal-date {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.38;
  margin-top: 10px;
}

@media (max-width: 720px) {
  /* Three columns do not fit on a phone: stacked */
  .account-page { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .account-page .page-title, .sc-title { font-size: min(7vw, 72px); }

  .foot { padding: 20px 16px; }
  .foot-links { gap: 16px; }

  /* On a phone explore and maps flow too: rather than staying fixed, the strip
     should sit at the end of the page like it does everywhere else. */
  .foot.thin {
    position: static;
    padding: 20px 16px;
    border-top: 1px solid rgba(0, 0, 0, 0.09);
  }

  .foot.thin .foot-name { display: block; }
  .legal-list { font-size: 15px; }
}
/* ---------- Event page: the contact sheet ---------- */

/* It does not describe one night but this month's frame of something that
   repeats. What does not change on the left, the unselected frames in the
   middle, who is coming on the right. All of it is visible on the first screen;
   only the editions you went to are further down. */
.cs {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr) 336px;
  gap: 52px;
  align-items: start;
  max-width: 1400px;
  padding: 100px 32px 56px;
}

/* The rail: it stays where it is however far the page scrolls — but it lets
   go before the page runs out. A sticky column is pinned for the whole of
   its grid row, so without this the poster and the column of faces were
   still hanging at the top of the screen while the black band came up from
   the bottom: three sets of pictures on one screen, none of them finished
   with. The bottom margin ends the pinning early, and the band's own top
   margin does the rest. Nothing is pushed by it — the middle column is
   taller than both of these. */
.cs-rail {
  position: sticky;
  top: 100px;
  margin-bottom: 130px;
}

.cs-poster {
  display: block;
  width: 100%;
  aspect-ratio: 2 / 3;
  pointer-events: none;      /* an object swallows the click */
}

/* When the poster is a photograph (synced nights): crop, never squash */
img.cs-poster {
  object-fit: cover;
  background: #ececea;
}

/* --- the preview chip ON the poster (hand-picked nights only) ---
   Absolute inside the frame, so the page gains no height for it. */
.cs-poster-frame {
  position: relative;
}

.cs-preview {
  position: absolute;
  left: 10px;
  bottom: 12px;
  display: flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--black);
}

.cs-preview-button {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--black);
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}

.cs-preview-icon {
  width: 0;
  height: 0;
  border-left: 7px solid var(--black);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  flex: 0 0 auto;
}

/* A pause mark instead of a triangle while it plays — the same trick
   as the sound rows on the landing page */
.cs-preview.playing .cs-preview-icon {
  width: 7px;
  height: 10px;
  border: none;
  background: linear-gradient(to right,
    var(--black) 0 2.5px, transparent 2.5px 4.5px, var(--black) 4.5px 7px);
}

.cs-preview-store {
  padding: 7px 10px 7px 2px;
  color: var(--black);
  text-decoration: none;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
}

/* How far in the song is: a hairline along the poster's bottom edge */
.cs-preview-line {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
}

.cs-preview-line span {
  display: block;
  width: 0;
  height: 100%;
  background: var(--black);
}

/* The colophon: all of it in one language, one size, one order. Deliberately
   boring — a series is identified by what does not change, not by what does.
   ONLY the things that are the same in every edition are here; the times are on
   the frames. */
.cs-facts {
  margin-top: 18px;
  border-top: 1px solid rgba(0, 0, 0, 0.14);
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.cs-facts > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.07);
}

.cs-facts dt { opacity: 0.38; white-space: nowrap; }
.cs-facts dd { text-align: right; }

/* --- the middle column --- */

/* A grid item should not try to be as wide as its own content */
.cs-field { min-width: 0; }

/* The breadcrumb is not fixed here, it stands at the head of the text */
.cs .crumb {
  position: static;
  margin-bottom: 20px;
}

.cs-edition {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.5;
}

.cs-title {
  margin-top: 8px;
  font-size: min(5.4vw, 64px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 0.98;
}

/* Nothing written in the colophon or on the frames is repeated here */
.cs-meta { margin-top: 12px; font-size: 15px; opacity: 0.5; }

.cs-text {
  margin-top: 18px;
  max-width: 68ch;
  font-size: 15px;
  line-height: 1.6;
  opacity: 0.78;
}

.cs-text + .cs-text { margin-top: 13px; }

.cs-section { margin-top: 34px; }

.cs-label {
  margin-bottom: 12px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.5;
}

/* --- the after: a bracket that drops out of the closing time ---

   Four columns and no pictures. The second column is 1px of nothing that
   carries the whole drawing: a vertical rule down its left edge and a tick
   across it at the height of the mark. Because the rows sit against each
   other with no gap, those fragments join into one continuous bracket
   whatever the rows are — the line never has to be measured. */
.cs-rooms {
  list-style: none;
  margin-top: 6px;
}

.cs-room {
  display: grid;
  grid-template-columns: 54px 20px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 0;
  min-height: 52px;
}

.cs-room-rule {
  position: relative;
  align-self: stretch;
}

/* the vertical */
.cs-room-rule::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(0, 0, 0, 0.16);
}

/* the tick into the room */
.cs-room-rule::after {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 20px;
  height: 1px;
  background: rgba(0, 0, 0, 0.16);
}

/* The bracket hangs from the first mark and stops at the last: above the
   one and below the other there is nothing to hold. */
.cs-room.origin .cs-room-rule::before { top: 50%; }
.cs-room:last-child .cs-room-rule::before { bottom: 50%; }

/* This night going dark is a filled square, not a branch — the same mark
   the cards use for something that has happened. */
.cs-room.origin .cs-room-rule::after {
  left: -2px;
  top: calc(50% - 2px);
  width: 5px;
  height: 5px;
  background: var(--black);
}

.cs-room-time {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.14em;
  font-variant-numeric: tabular-nums;
  opacity: 0.5;
}

.cs-room-body { min-width: 0; padding-left: 14px; }
/* a real room is a night of ours: its name opens that night */
.cs-room-link { min-width: 0; color: inherit; text-decoration: none; }
.cs-room-link:hover .cs-room-name { text-decoration: underline; text-underline-offset: 3px; }

.cs-room-name {
  display: block;
  font-size: 15px;
  letter-spacing: -0.01em;
}

.cs-room-kind {
  display: block;
  margin-top: 3px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.45;
}

.cs-room-walk {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: right;
  white-space: nowrap;
  opacity: 0.38;
}

/* The night this page is about is stated, not offered */
.cs-room.origin .cs-room-name {
  font-size: 13px;
  opacity: 0.4;
}

.cs-note {
  margin-top: 16px;
  max-width: 52ch;
  font-size: 13px;
  line-height: 1.6;
  opacity: 0.42;
}

/* --- right column: who is coming, then the ticket --- */

.cs-right { position: sticky; top: 100px; margin-bottom: 130px; }

.cs-who {
  list-style: none;
  border-top: 1px solid rgba(0, 0, 0, 0.14);
}

.cs-who-row {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.07);
}

/* A face: the generated frame from avatars.js, kept in a box with the same
   hairline as everything else on this page so it sits on the paper rather
   than floating above it. */
.cs-face {
  display: block;
  overflow: hidden;
  background: #e6e6e4;
  border: 1px solid rgba(0, 0, 0, 0.18);
}

.cs-face svg { display: block; width: 100%; height: 100%; }

.cs-who-face { width: 42px; height: 42px; }

/* The answer, read without reading it: someone who is coming is in full
   light, someone who only kept the card is dimmer, someone who cannot make
   it has nearly gone out. */
.cs-who-row.kept .cs-who-face { opacity: 0.72; }
.cs-who-row.out .cs-who-face { opacity: 0.3; }
.cs-who-row.out .cs-who-name { opacity: 0.45; }

.cs-who-body { min-width: 0; }

.cs-who-name {
  display: block;
  font-size: 15px;
  letter-spacing: -0.01em;
}

/* One slot holding two things, both taken out of the flow: the handle at
   rest, the path on hover. A row that grew a line instead would shove every
   row under it down on the way past. */
.cs-who-slot {
  position: relative;
  display: block;
  height: 17px;
  margin-top: 3px;
}

.cs-who-rel,
.cs-chain {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  height: 17px;
  white-space: nowrap;
  transition: opacity 0.16s ease;
}

.cs-who-rel {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.08em;
  opacity: 0.4;
}

.cs-chain { opacity: 0; pointer-events: none; }

.cs-who-row:hover .cs-who-rel,
.cs-who-row:focus-within .cs-who-rel { opacity: 0; }

.cs-who-row:hover .cs-chain,
.cs-who-row:focus-within .cs-chain { opacity: 1; }

/* Nothing hovers on a phone, and the path is the entire reason this column
   was rebuilt. Where there is no pointer the chain is simply always the one
   showing, and the handle is the thing you never see. */
@media (hover: none) {
  .cs-who-rel { opacity: 0; }
  .cs-chain { opacity: 1; }
}

/* You are the filled square — the same mark the after hangs its bracket
   from. Everything after it is a face, and the hairlines between them are
   the introductions you would have to ask for. */
.cs-chain-you {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  background: var(--black);
}

.cs-chain-link {
  flex: 0 0 auto;
  width: 8px;
  height: 1px;
  background: rgba(0, 0, 0, 0.28);
}

.cs-chain-face { flex: 0 0 auto; width: 15px; height: 15px; }

.cs-chain-word {
  margin-left: 9px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.5;
}

.cs-who-status {
  align-self: center;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
}

.cs-tally {
  margin-top: 10px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.38;
}

/* The line the column is really for: how much of this room is not yours. */
.cs-reach {
  margin-top: 4px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.55;
}

.cs-ticket {
  display: block;
  margin-top: 20px;
  padding: 16px 20px;
  background: var(--black);
  color: var(--white);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-align: center;
  text-decoration: none;
}

/* The second button, for the app: same shape, drawn with a rule */
.cs-app {
  margin-top: 12px;
  background: none;
  color: var(--black);
  border: 1px solid var(--black);
}

.cs-ticket-sub a {
  color: var(--black);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.cs-ticket-sub {
  margin-top: 9px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.38;
  text-align: center;
}

/* What friends left for this night: the same language as beforehours in explore,
   shrunk a little for a narrow column. */
.cs-comments { margin-top: 30px; }
.cs-comments .c-topic + .c-topic { margin-top: 20px; }
.cs-comments .c-top { gap: 8px; margin-bottom: 4px; }
.cs-comments .c-who { font-size: 13px; }
.cs-comments .c-when { font-size: 11px; }
.cs-comments .c-text { font-size: 13.5px; line-height: 1.5; opacity: 0.8; }
.cs-comments .c-replies { margin-top: 10px; padding-left: 12px; }
.cs-comments .c-replies .c-text { font-size: 13px; }

/* --- what the night leaves you ---

   The last thing on the page and the only black on it. Everything above is
   paper: the poster, the bracket, the column of who is coming. Then the
   page stops being paper and the card is metal. That is the whole reason
   the band is here rather than a fourth section in the middle column.

   It is a sibling of the contact sheet rather than a fourth item inside it.
   As a grid child it looked right and behaved badly: a sticky column is
   clamped to the grid CONTAINER and not to its own row, so the poster and
   the column of faces slid down over the black. Out here the sheet ends
   where the columns end, the band is what comes after, and it runs the full
   width of the window on its own without a negative margin in sight. */
.cs-earn {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  align-items: start;
  gap: 40px 56px;
  padding: 60px 32px 64px;
  background: var(--black);
  color: var(--white);
}

.cs-earn-label {
  grid-column: 1 / -1;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.45;
}

/* Both faces, side by side and the same size: neither of them is the
   preview of the other. */
.cs-earn-pair {
  display: grid;
  grid-template-columns: repeat(2, 300px);
  gap: 26px;
}

.cs-earn-card { min-width: 0; }
.cs-earn-face svg { display: block; width: 100%; height: auto; }

.cs-earn-card figcaption {
  margin-top: 12px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.4;
}

/* The offer, next to the thing being offered. No button: the ticket is
   already in the right column and a second one here would turn a promise
   into an advert. */
.cs-earn-say { max-width: 46ch; padding-top: 2px; }

.cs-earn-line {
  font-size: 21px;
  line-height: 1.35;
  letter-spacing: -0.015em;
}

.cs-earn-sub {
  margin-top: 14px;
  font-size: 14px;
  line-height: 1.6;
  opacity: 0.55;
}

/* On a narrow desktop the third column does not fit: who is coming and the
   ticket move under the rail — not to the foot of the page, so that they stay on
   the first screen. */
@media (max-width: 1100px) {
  .cs { grid-template-columns: 216px minmax(0, 1fr); gap: 40px; }
  .cs-rail { position: static; margin-bottom: 0; }
  .cs-field { grid-row: 1 / span 2; grid-column: 2; }
  .cs-right { grid-column: 1; position: static; margin-top: 26px; margin-bottom: 0; }
}

@media (max-width: 900px) {
  .cs {
    display: flex;
    flex-direction: column;
    gap: 34px;
    padding: 104px 16px 64px;
  }

  /* On a phone the rail neither sticks nor stays together: first a small poster,
     then the night itself, the colophon last. Otherwise reaching the event's
     name meant passing ten lines of colophon. */
  .cs-rail { display: contents; }
  .cs-poster-frame { order: 1; max-width: 190px; }
  .cs-poster { max-width: 190px; }
  .cs-field { order: 2; width: 100%; }
  .cs-right { order: 3; max-width: none; }
  .cs-facts { order: 4; margin-top: 0; }

  /* The bracket keeps its shape on a phone — it is four short columns, and
     four short columns fit. Only the measurements tighten. Dropping the walk
     onto a second line was tried and it broke the rule into segments. */
  .cs-room { grid-template-columns: 46px 16px minmax(0, 1fr) auto; min-height: 46px; }
  .cs-room-rule::after { width: 16px; }
  .cs-room-body { padding-left: 11px; }
  .cs-room-name { font-size: 14px; }
  .cs-room-walk { font-size: 9px; letter-spacing: 0.1em; }
  .cs-title { font-size: min(11vw, 52px); }
  .cs-text, .cs-note { max-width: none; }
  /* On a phone the two faces halve and the words go under them. The band
     keeps its black and its full bleed — that is the point of it. */
  .cs-earn {
    grid-template-columns: minmax(0, 1fr);
    gap: 30px;
    padding: 46px 16px 52px;
  }

  .cs-earn-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .cs-earn-line { font-size: 18px; }
}

/* A card at 166px is a thumbnail of a card. On a narrow phone the two faces
   stop sharing a row and take the full measure instead: the band is the end
   of the page and can afford the height, and none of the small print on the
   plate survives being halved. */
@media (max-width: 720px) {
  .cs-earn-pair { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .cs-earn-card { max-width: 340px; }
}

/* ---------- Somebody's page ---------- */

/* Three things from three sketches, in the order the question arrives:
   how you reach them (the path), who they are and what they kept (the
   roll), and what those nights left them with (the shelf, which is the
   same black band the event page ends on). One column, the contact
   sheet's measure. */
.pf {
  max-width: 1160px;
  padding: 118px 32px 64px;
}

.pf-none { font-size: 17px; opacity: 0.5; }

/* --- the path --- */
.pf-path { margin-bottom: 52px; }

.pf-hops {
  display: flex;
  align-items: flex-start;
  gap: 0;
  margin-top: 6px;
}

.pf-hop {
  flex: 0 0 auto;
  width: 150px;
  color: inherit;
  text-decoration: none;
}

/* You are the filled square, the size of a face */
.pf-hop-mark {
  display: block;
  width: 150px;
  height: 150px;
  background: var(--black);
}

.pf-hop-face { display: block; width: 150px; height: 150px; }

.pf-hop-name {
  margin-top: 12px;
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.02em;
}

.pf-hop-rel {
  margin-top: 4px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
}

/* The introductions you would have to ask for */
.pf-hop-link {
  flex: 1 1 40px;
  max-width: 120px;
  height: 1px;
  margin-top: 75px;
  background: rgba(0, 0, 0, 0.28);
}

a.pf-hop:hover .pf-hop-name { text-decoration: underline; text-underline-offset: 3px; }

/* --- the head --- */
.pf-head {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  gap: 28px;
  align-items: start;
  padding-top: 40px;
  border-top: 1px solid rgba(0, 0, 0, 0.14);
}

.pf-portrait { display: block; width: 132px; height: 132px; }

.pf-name {
  font-size: min(6vw, 56px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
}

.pf-meta { margin-top: 12px; font-size: 15px; opacity: 0.5; }
.pf-bio { margin-top: 16px; max-width: 60ch; font-size: 16px; line-height: 1.55; opacity: 0.8; }

/* --- the roll --- */
.pf-roll { margin-top: 56px; }

.pf-frames {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 30px 16px;
}

/* A frame is a photograph with the number of the exposure under it. In
   colour: the contact-sheet grey was tried and taken off again — on this
   page the nights are the person, and a person is not a proof sheet. */
.pf-shot {
  display: block;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: #ececea;
  border: 1px solid rgba(0, 0, 0, 0.16);
}

.pf-shot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pf-shot.empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f4f4f2;
  border-color: rgba(0, 0, 0, 0.08);
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.4;
}

.pf-frame-line {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 9px;
  min-width: 0;
}

.pf-no {
  flex: 0 0 auto;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.14em;
  opacity: 0.3;
}

.pf-frame-name {
  font-size: 13.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pf-frame-name.dim { opacity: 0.4; }

.pf-frame-meta {
  margin-top: 4px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 8.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.42;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- which friends, and you and them --- */
.pf-friends {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 40px;
  align-items: start;
  margin-top: 56px;
  padding-top: 30px;
  border-top: 1px solid rgba(0, 0, 0, 0.14);
}

.pf-faces { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pf-face-link { display: block; }
.pf-small-face { display: block; width: 40px; height: 40px; }
.pf-more { font-size: 12px; opacity: 0.4; margin-left: 4px; }

/* On this page the path is always showing — there is nothing to hover
   away from, and the whole page is the hover. */
.pf-you .cs-chain { position: static; opacity: 1; pointer-events: auto; height: auto; }

/* --- the shelf --- */
.pf-shelf { margin-top: 64px; }

.pf-cards {
  display: flex;
  gap: 22px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 4px;
}

.pf-cards::-webkit-scrollbar { display: none; }
.pf-cards .cs-earn-card { flex: 0 0 230px; }

@media (max-width: 900px) {
  .pf { padding: 104px 16px 56px; }
  /* Four hops have to fit a phone: 4 × 78 plus three hairlines is 343
     with nothing to spare, so the row may also scroll rather than push
     the page sideways. */
  .pf-hops { overflow-x: auto; scrollbar-width: none; }
  .pf-hops::-webkit-scrollbar { display: none; }
  .pf-hop, .pf-hop-mark, .pf-hop-face { width: 78px; }
  .pf-hop-mark, .pf-hop-face { height: 78px; }
  .pf-hop-link { flex-basis: 10px; min-width: 10px; margin-top: 39px; }
  .pf-hop-name { font-size: 15px; }
  .pf-hop-rel { font-size: 8.5px; letter-spacing: 0.1em; }
  .pf-head { grid-template-columns: 88px minmax(0, 1fr); gap: 18px; }
  .pf-portrait { width: 88px; height: 88px; }
  .pf-frames { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 12px; }
  .pf-friends { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .pf-cards .cs-earn-card { flex-basis: 200px; }
}

/* ---------- Settings page ---------- */

/* One column, the same measure as the help page: something to be read, not a
   form to be filled in. Sections separated by a hairline. */
.set,
.fb,
.reg {
  max-width: 620px;
  padding: 132px 32px 96px;
}

.set .page-title { margin-bottom: 34px; }
.fb .page-title { margin-bottom: 22px; }
.reg .page-title { margin-bottom: 22px; }

.set-out {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

.set .account { margin-top: 34px; }
.set .account-about { max-width: 48ch; }
.set-wide { width: min(100%, 420px); }

/* Moving to a different set: the card is finished, the rules begin */
.set-section {
  margin-top: 52px;
  padding-top: 34px;
  border-top: 1px solid rgba(0, 0, 0, 0.12);
}

.set-save {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 26px;
}

.set-save .account-status { margin-top: 0; }

/* Two options side by side: the chosen one solid, the other faded. The same
   language as the deck's source picker in explore. */
.set-choice {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-top: 10px;
}

.set-choice button {
  font-family: inherit;
  font-size: 16px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--black);
  background: none;
  border: 0;
  padding: 0;
  opacity: 0.42;
  cursor: pointer;
  transition: opacity 0.2s ease;
}

.set-choice button:hover { opacity: 0.7; }

.set-choice button.selected {
  font-weight: 500;
  opacity: 1;
  cursor: default;
  text-decoration: underline;
  text-underline-offset: 5px;
}

/* Fifty-four cities do not fit on one screen: grouped by country, in a box that
   scrolls. The height is deliberately short — this page is not about cities. */
.set-cities {
  /* Let offsetTop be measured against this box: with no positioned ancestor it
     measured from the top of the page and scrolled the box to the very bottom. */
  position: relative;
  max-height: 210px;
  overflow-y: auto;
  margin-top: 12px;
  padding: 4px 14px 10px 0;
  border-top: 1px solid rgba(0, 0, 0, 0.09);
  border-bottom: 1px solid rgba(0, 0, 0, 0.09);
  scrollbar-width: thin;
}

.set-country {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.38;
  margin-top: 16px;
}

.set-cities .set-country:first-child { margin-top: 8px; }
.set-cities .set-choice { gap: 14px; margin-top: 6px; }
.set-cities .set-choice button { font-size: 15px; }

.set-who { font-size: 17px; font-weight: 500; letter-spacing: -0.01em; margin-bottom: 6px; }
.set .page-signout { margin-top: 16px; }

/* Deleting: the only red on the site. It appears nowhere else, and it should not. */
.set-danger { margin-top: 44px; }

.set-delete {
  margin-top: 14px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  color: #c22a1f;
  background: none;
  border: 1px solid rgba(194, 42, 31, 0.4);
  padding: 9px 18px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.set-delete:hover { background: #c22a1f; color: var(--white); }
.set-confirm { margin-top: 18px; }
.set-confirm .account-row { margin-top: 8px; }
.set-confirm .set-delete { margin-top: 0; }

.account-status.ok { opacity: 0.85; }
.account-status.error { opacity: 1; color: #c22a1f; }

@media (max-width: 720px) {
  .set, .fb, .reg { padding: 104px 16px 64px; }
  .set .page-title, .fb .page-title, .reg .page-title { font-size: 38px; }
  .set-choice { gap: 16px; }
}

/* ---------- Feedback ---------- */

.fb-intro {
  max-width: 52ch;
  font-size: 16px;
  line-height: 1.62;
  opacity: 0.78;
}

.fb .account { margin-top: 34px; }
.fb .account-about { max-width: 48ch; }

/* One box, a line underneath rather than a border — like the rest of the site */
.fb-text {
  display: block;
  width: 100%;
  max-width: 520px;
  margin-top: 12px;
  padding: 10px 0;
  font-family: inherit;
  font-size: 16px;
  line-height: 1.55;
  color: var(--black);
  background: none;
  border: 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.25);
  resize: vertical;
}

.fb-text::placeholder { color: rgba(0, 0, 0, 0.28); }
.fb-text:focus { outline: none; border-bottom-color: var(--black); }

.fb-counter {
  margin-top: 8px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.4;
  min-height: 14px;
}

.fb-thanks { margin-top: 12px; }

.fb-thanks-title {
  font-size: 26px;
  font-weight: 500;
  letter-spacing: -0.02em;
  margin-bottom: 14px;
}

.fb-links { display: flex; flex-wrap: wrap; gap: 26px; margin-top: 24px; }

/* A button that looks like a link: .sc-link in button form */
.fb-again {
  font-family: inherit;
  background: none;
  cursor: pointer;
}

/* The directions at the end of the page: this is not the right place for everything */
.fb-note {
  margin-top: 64px;
  padding-top: 26px;
  border-top: 1px solid rgba(0, 0, 0, 0.09);
  max-width: 52ch;
  font-size: 14px;
  line-height: 1.6;
  opacity: 0.45;
}

@media (max-width: 720px) {
  .fb-text { max-width: none; }
}

/* ---------- Register ---------- */

/* The two steps never stand together: one of them is visible at a time. */
.reg-edition {
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.42;
  margin-bottom: 14px;
}

.reg-intro {
  max-width: 52ch;
  font-size: 16px;
  line-height: 1.62;
  opacity: 0.78;
  margin-bottom: 30px;
}

.reg .account { margin-top: 30px; }
.reg .account-about { max-width: 48ch; }
.reg .page-form { margin-top: 4px; }

.reg-sub {
  margin-top: 40px;
  font-size: 15px;
  opacity: 0.55;
}

.reg-sub a {
  color: var(--black);
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* ---------- Accessibility ---------- */

/* Someone moving by keyboard had to walk the whole menu on every page. This link
   is invisible; it appears when Tab is pressed. */
.skip {
  position: fixed;
  z-index: 100;
  top: 10px;
  left: 10px;
  padding: 12px 18px;
  background: var(--black);
  color: var(--white);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform 0.18s ease;
}

.skip:focus { transform: translateY(0); }

/* The browser default was invisible in most places (black on black). It only
   shows for the KEYBOARD, not for the mouse. */
:focus-visible {
  outline: 2px solid var(--black);
  outline-offset: 3px;
}

.screen6 :focus-visible,
.screen4 :focus-visible,
.s6-button:focus-visible { outline-color: #f2f2f0; }

/* A tabindex given so an element can be focused should not draw a ring when it
   is clicked */
[tabindex="-1"]:focus { outline: none; }

/* On systems asking for less motion the site stops moving: a card still flies,
   but in one step rather than an animation. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Every surface: what the first mobile pass missed ---------- */

/* The landing page's globe and footer screens had no rules below the
   desktop at all: at phone width "go local." printed straight over the
   walking-distance list, the sónar footnote lay across the manifesto,
   and the "go outside" button ran off the right edge. */

@media (max-width: 900px) {
  /* Screen 3, the globe: title top, the near list moves to the BOTTOM of
     the frame — the two shared the same band and collided. */
  .s4-text { top: 96px; left: 16px; right: 16px; max-width: none; }
  .s4-title { font-size: min(15vw, 72px); }
  .s4-sub { font-size: 15px; }

  .s4-near {
    top: auto;
    bottom: 24px;
    left: 16px;
    right: 16px;
    width: auto;
  }
  .s4-near li { padding: 4px 0; font-size: 13px; }
  .s4-near li b { min-width: 44px; font-size: 12px; }
  .s4-near-title { padding-bottom: 8px; margin-bottom: 2px; }
  .s4-near-sub { margin-top: 8px; padding-top: 8px; font-size: 11px; }

  /* Screen 5, the footer: the footnote becomes its own line instead of a
     superscript that no longer fits, and the button takes a full row
     rather than being cut off at the edge. */
  .screen6 { padding: 84px 16px 40px; }
  .s6-manifesto { max-width: none; }
  .s6-note {
    display: block;
    margin: 12px 0 0;
    vertical-align: baseline;
    white-space: normal;
  }
  .s6-sub { flex-wrap: wrap; gap: 26px 44px; align-items: flex-start; }
  .s6-button { flex: 1 0 100%; text-align: center; padding: 18px 20px; font-size: 18px; }
}

/* The band between the phone and the desktop (721–1180): the fixed
   sound box sat on top of the intro copy, and the photo — 780px flat —
   swallowed half the layout. The photo now scales with the surface; the
   intro starts below the sound rows. */
@media (min-width: 721px) and (max-width: 1180px) {
  .intro { padding-top: 76px; }
  .photo { width: min(780px, 46vw); }
}

/* ---------- the screen-reader line, the reply box ---------- */

/* Only for screen readers: the deck announces what a swipe did. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Replying to a topic: a small word after the text, a slim box below. */
.c-reply-button {
  border: none;
  background: none;
  padding: 0;
  margin-top: 6px;
  cursor: pointer;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--black);
  opacity: 0.4;
}

.c-reply-button:hover { opacity: 0.9; }

.c-reply-write {
  margin: 8px 0 4px 14px;
  padding-left: 12px;
  border-left: 1px solid rgba(0, 0, 0, 0.14);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

.c-reply-write textarea {
  width: 100%;
  font-family: inherit;
  font-size: 13px;
  line-height: 1.5;
  border: 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.25);
  background: none;
  padding: 2px 0 6px;
  resize: vertical;
}

.c-reply-write textarea:focus { outline: none; border-bottom-color: var(--black); }

/* The quiet way out under the sign-in button */
.page-forgot {
  margin-top: 10px;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--black);
  opacity: 0.45;
  text-decoration: none;
  border-bottom: 1px solid rgba(0, 0, 0, 0.3);
  padding-bottom: 2px;
}

.page-forgot:hover { opacity: 0.9; }


/* ---------- "preview." on the closed pages: the phone (phone.js) ----------
   Ink ground over the page, a big phone in the middle with the app's real
   screenshots inside, a finger that taps and drags, one line under it. */

body.pv-open { overflow: hidden; }

.pv-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
  background: rgba(22, 21, 18, 0.94);
  color: #f3f1ec;
  opacity: 0;
  transition: opacity 0.32s ease;
}
.pv-overlay.in { opacity: 1; }

.pv-close {
  position: absolute;
  top: 26px;
  right: 32px;
  border: none;
  background: none;
  padding: 6px 0;
  cursor: pointer;
  color: #f3f1ec;
  font-family: inherit;
  font-size: 13px;
  letter-spacing: 0.02em;
  border-bottom: 1px solid rgba(243, 241, 236, 0.35);
}
.pv-close:hover { border-bottom-color: #f3f1ec; }

.pv-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
  transform: translateY(28px);
  transition: transform 0.42s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.pv-overlay.in .pv-stage { transform: none; }

/* The phone itself: 9:19.5, as tall as the room allows */
.pv-frame {
  --phone-h: min(78vh, 78dvh, calc(92vw * 19.5 / 9));
  height: var(--phone-h);
  aspect-ratio: 9 / 19.5;
  padding: 12px;
  border-radius: 46px;
  background: #0d0c0b;
  box-shadow:
    0 0 0 1px #2e2c29,
    0 40px 90px rgba(0, 0, 0, 0.6);
}

.pv-screen {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 36px;
  overflow: hidden;
  background: #f3f1ec;
  isolation: isolate;
}

.pv-shot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  opacity: 0;
  transition: opacity 0.45s ease;
}
.pv-shot.on { opacity: 1; }

/* Until a screenshot exists: its expected path, small, on paper */
.pv-missing {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: #8a877f;
}

/* The finger: a soft disc with a hairline ring, pressed = smaller and darker */
.pv-finger {
  position: absolute;
  width: 38px;
  height: 38px;
  margin: -19px 0 0 -19px;
  border-radius: 50%;
  background: rgba(22, 21, 18, 0.22);
  box-shadow: 0 0 0 1.5px rgba(243, 241, 236, 0.9), 0 2px 10px rgba(0, 0, 0, 0.35);
  transform: scale(1);
  transition: transform 0.16s ease, background 0.16s ease;
  pointer-events: none;
  z-index: 2;
}
.pv-finger.down {
  transform: scale(0.72);
  background: rgba(22, 21, 18, 0.5);
}

.pv-say {
  min-height: 1.4em;
  max-width: 34ch;
  text-align: center;
  font-size: 17px;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: #f3f1ec;
}

.pv-end {
  display: flex;
  align-items: center;
  gap: 22px;
}
.pv-again {
  border: none;
  background: none;
  padding: 6px 0;
  cursor: pointer;
  color: #8a877f;
  font-family: inherit;
  font-size: 13px;
  border-bottom: 1px solid rgba(138, 135, 127, 0.5);
}
.pv-again:hover { color: #f3f1ec; border-bottom-color: #f3f1ec; }

@media (max-width: 720px) {
  .pv-close { top: 18px; right: 16px; }
  .pv-frame { --phone-h: min(70vh, 70dvh, calc(88vw * 19.5 / 9)); padding: 9px; border-radius: 36px; }
  .pv-screen { border-radius: 28px; }
  .pv-say { font-size: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .pv-overlay, .pv-stage, .pv-shot, .pv-finger { transition: none; }
}


/* ---------- The store badges ----------
   Two small boxes in place of the old "get the app" line: google play
   (live) and the app store (not yet — it sits there dimmed, no link,
   until config.js gets an ios address). Glyphs are CSS masks, so the
   boxes take the colour of wherever they sit. */
.stores {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
.store {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  height: 54px;
  padding: 0 18px 0 14px;
  border-radius: 9px;
  background: #0a0a0a;
  color: #f2f2f0;
  border: 1px solid rgba(242, 242, 240, 0.22);
  text-decoration: none;
  font-family: "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif;
  line-height: 1;
  white-space: nowrap;
}
.store::before {
  content: "";
  flex: none;
  width: 26px;
  height: 26px;
  background: currentColor;
  -webkit-mask: var(--glyph) center / contain no-repeat;
  mask: var(--glyph) center / contain no-repeat;
}
.store-play { --glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 2.6v18.8c0 .5.5.8.9.5l9.1-9.1L4.9 2.1c-.4-.3-.9 0-.9.5zM6.2 3.9l8.4 8.4-2.2 2.2L6.2 3.9zm9.9 6.9L12.6 12l3.5 3.5 3.5-2c.9-.5.9-1.9 0-2.4l-3.5-2.3zM6.2 20.1l6.2-6.2 2.2 2.2-8.4 4z'/%3E%3C/svg%3E"); }
.store-ios  { --glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M16.4 12.7c0-2.4 2-3.6 2.1-3.7-1.1-1.7-2.9-1.9-3.5-1.9-1.5-.2-2.9.9-3.7.9-.8 0-1.9-.9-3.2-.8-1.6 0-3.1 1-4 2.4-1.7 3-.4 7.3 1.2 9.7.8 1.2 1.8 2.5 3 2.4 1.2 0 1.7-.8 3.2-.8s1.9.8 3.2.8c1.3 0 2.2-1.2 3-2.4.9-1.3 1.3-2.6 1.3-2.7 0 0-2.6-1-2.6-3.9zM14 5.5c.7-.8 1.1-1.9 1-3-1 0-2.1.7-2.8 1.5-.6.7-1.2 1.8-1 2.9 1.1.1 2.2-.6 2.8-1.4z'/%3E%3C/svg%3E"); }
.store small {
  display: block;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.7;
  margin-bottom: 3px;
}
.store b {
  display: block;
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.015em;
}
.store:hover { border-color: rgba(242, 242, 240, 0.6); }
.store.soon { opacity: 0.4; cursor: default; }
.store.soon:hover { border-color: rgba(242, 242, 240, 0.22); }

/* Small: on the night page, under "open in the app" */
.stores-small .store { height: 44px; padding: 0 14px 0 11px; gap: 9px; border-radius: 7px; }
.stores-small .store::before { width: 20px; height: 20px; }
.stores-small .store small { font-size: 8px; margin-bottom: 2px; }
.stores-small .store b { font-size: 14px; }

/* On the closed pages the block sits inside a pointer-events:none layer */
.map-closed .stores, .fr-closed .stores { pointer-events: auto; margin-top: 14px; justify-content: center; }

/* On the footer the badges line up with the "go outside" button */
.s6-buttons .stores { align-self: center; }
@media (max-width: 720px) {
  .s6-buttons .stores { flex: 1 0 100%; justify-content: center; }
}

/* ---------- Phones and tablets, second pass (2026-09-26) ----------
   Fixes found by walking every page at 375 and 768: the night's photo was
   half a phone wide with white beside it, the explore tally and the thin
   footer sat over the wall while it scrolled, the globe's list lay on the
   city with nothing behind it, the collection showed three tiny cards.
   Everything here comes last in the file on purpose: same specificity,
   later rule wins. */

/* --- tablet: 721–1180 --- */
@media (min-width: 721px) and (max-width: 1180px) {
  /* explore scrolls here as well: nothing fixed over the wall */
  body.explore .foot.thin,
  .ex-wall-page ~ .foot.thin {
    position: static;
    padding: 24px 32px;
    border-top: 1px solid rgba(0, 0, 0, 0.09);
  }
  .ex-tally { position: static; padding: 26px 0 0; }
}

/* the event page between phone and desktop: one column, a poster that is not a stamp */
@media (min-width: 721px) and (max-width: 900px) {
  .cs-poster-frame { max-width: 300px; }
  .cs-poster { max-width: 300px; }
  .cs-facts { max-width: 420px; }
}

/* --- phone: up to 720 --- */
@media (max-width: 720px) {
  /* the night: photo across the whole width; a photograph is cropped 4:3,
     a drawn poster keeps its 2:3 sheet */
  .cs-poster-frame { max-width: none; width: 100%; }
  .cs-poster { max-width: none; width: 100%; }
  img.cs-poster { aspect-ratio: 4 / 3; }
  .cs-facts { max-width: none; width: 100%; }

  /* the tally goes under the wall, not over it */
  .ex-tally { position: static; padding: 26px 0 0; }

  /* the globe: the list of nearby nights stands on its own dark band at the
     foot of the screen, left-aligned, instead of floating on the buildings */
  .s4-near {
    left: 0;
    right: 0;
    bottom: 0;
    padding: 16px 16px 20px;
    text-align: left;
    background: linear-gradient(to top, rgba(10, 10, 10, 0.96) 0%, rgba(10, 10, 10, 0.92) 78%, rgba(10, 10, 10, 0) 100%);
    padding-top: 40px;
  }
  .s4-near li { justify-content: flex-start; }
  .s4-near li b { min-width: 0; margin-left: auto; text-align: right; }
  .s4-near-title { text-align: left; }

  /* the collection: two cards a row, big enough to read */
  .cc-cards { grid-template-columns: repeat(2, 1fr); gap: 12px; }
}

/* very small phones: one card a row */
@media (max-width: 380px) {
  .cc-cards { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .ex-wall { gap: 6px; }
}


/* ---------- Three languages (i18n.js) ---------- */

/* The page is written in english; until i18n.js has swapped the words
   the body stays hidden, so nobody watches it change language. */
html.i18n-wait body { visibility: hidden; }

/* Long pages (impressum, datenschutz, agb, privacy) are written out once
   per language; only the block in the page's language shows. */
html[lang="en"] [data-lang-block]:not([data-lang-block="en"]),
html[lang="de"] [data-lang-block]:not([data-lang-block="de"]),
html[lang="tr"] [data-lang-block]:not([data-lang-block="tr"]) { display: none !important; }

/* The switch: en de tr. The same language as the other choices on the
   site — the one in force at full weight, the others faded. */
.lang {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
}

.lang-code {
  appearance: none;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  font-size: 15px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: inherit;
  opacity: 0.42;
  cursor: pointer;
  transition: opacity 0.2s ease;
}

.lang-code:hover { opacity: 0.8; }

.lang-code[aria-pressed="true"] {
  opacity: 1;
  font-weight: 500;
  cursor: default;
}

.lang-code:focus-visible { outline: 1px solid currentColor; outline-offset: 3px; }

/* In the menu it takes the colour of the links, so it inverts with them
   on the landing's dark screens. */
.header-links .lang { color: var(--black); transition: color 0.5s ease; }
body[data-screen="4"] .header-links .lang { color: #f0f0ee; }
body[data-screen="5"] .header-links .lang { color: #f2f2f0; }

/* Written out in full where there is room (settings, the landing footer) */
.lang[data-lang-names] { gap: 22px; }

@media (max-width: 720px) {
  .lang { gap: 9px; }
  .header-links .lang-code { font-size: 12px; }

  /* On a phone the menu has one row and the translated words are longer
     than the english ones. The switch moves up beside the logo, and the
     row scrolls sideways instead of breaking onto a third line that the
     page under the fixed menu never made room for. */
  .header-links .lang {
    position: absolute;
    top: 18px;
    right: 16px;
  }

  .header-links {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .header-links::-webkit-scrollbar { display: none; }
}
