:root {
  --bg: #000;
  --fg: #fff;
  --cursor-size: 12px;
  --img-fade-in: 200ms;
  --img-fade-out: 700ms;
}

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

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  overflow: hidden;
  overscroll-behavior: none;
}

body {
  font-family: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  -webkit-font-smoothing: antialiased;
}

/* Hide the system cursor once we know a fine pointer is driving the page. */
body.has-cursor,
body.has-cursor * { cursor: none; }

/* ---------------------------------------------------------- image stage */

.stage {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.shot {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--w);          /* set per image by main.js, already capped there */
  max-width: 42vw;          /* backstop if the script's caps ever change */
  max-height: 62vh;
  height: auto;
  object-fit: contain;
  display: block;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.98);
  transition: opacity var(--img-fade-out) ease, transform var(--img-fade-out) ease;
  will-change: opacity, transform;
}

.shot.is-in {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  transition-duration: var(--img-fade-in);
}

/* --------------------------------------------------------------- chrome */

.ui {
  position: fixed;
  left: 0;
  right: 0;
  z-index: 60;
  display: flex;
  justify-content: space-between;
  padding: 24px;
  pointer-events: none;
}

header.ui { top: 0; }
footer.ui { bottom: 0; }

.label {
  color: var(--fg);
  text-decoration: none;
  white-space: nowrap;
  mix-blend-mode: difference;   /* stays legible over any image */
}

a.label,
button.label {
  pointer-events: auto;
  /* button reset — it has to read as the same label as its neighbour */
  border: 0;
  background: none;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: inherit;
  text-decoration: none;
  /* Padding sits there permanently and is cancelled by the negative margin, so
     the highlight has room to breathe without the label shifting on hover.
     The right side is short by the trailing letter-space of the last glyph. */
  padding: 0.3em 0.32em 0.3em 0.4em;
  margin: -0.3em -0.32em -0.3em -0.4em;
  transition: background-color 120ms ease, color 120ms ease;
}

a.label:hover,
a.label:focus-visible,
button.label:hover,
button.label:focus-visible {
  /* Opt out of the blend so the highlight is actually white, rather than a
     negative of whatever image happens to be behind it. */
  mix-blend-mode: normal;
  background-color: var(--fg);
  color: var(--bg);
}

/* Caption slots are swapped on every new image; they leave on the image's clock. */
.label--bl, .label--br {
  opacity: 0;
  transition: opacity var(--img-fade-out) ease;
}
.label--bl.is-on, .label--br.is-on {
  opacity: 1;
  transition-duration: var(--img-fade-in);
}

/* The captions describe the work, so they go quiet while it's covered. */
body.info-open .label--bl,
body.info-open .label--br { opacity: 0; }
.label--br { text-align: right; }

/* -------------------------------------------------------- contact screen */

.info {
  position: fixed;
  inset: 0;
  z-index: 50;               /* over the work, under the chrome that closes it */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 72px 24px;
  background: var(--bg);
  opacity: 0;
  visibility: hidden;
  transition: opacity 260ms ease, visibility 0s linear 260ms;
}

.info.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 260ms ease, visibility 0s;
}

.info__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2.6em;
  text-align: center;
  max-width: 100%;
}

.info__lead { line-height: 1.8; }

.info__list {
  list-style: none;
  line-height: 2;
}

.info__mail {
  color: var(--fg);
  text-decoration: none;
  padding: 0.3em 0.32em 0.3em 0.4em;
  margin: -0.3em -0.32em -0.3em -0.4em;
  transition: background-color 120ms ease, color 120ms ease;
}

.info__mail:hover,
.info__mail:focus-visible {
  background-color: var(--fg);
  color: var(--bg);
}

/* --------------------------------------------------------------- cursor */

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
  width: var(--cursor-size);
  height: var(--cursor-size);
  background: var(--fg);
  mix-blend-mode: difference;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(-50%, -50%, 0);
  will-change: transform;
}
body.has-cursor .cursor { opacity: 1; }

/* ---------------------------------------------------------------- small */

@media (max-width: 700px) {
  .ui { padding: 16px; }
  body { font-size: 11px; }
  .shot { max-width: 78vw; }
}

@media (prefers-reduced-motion: reduce) {
  .shot { transition-duration: 1ms; }
}
