/* «Билет в галерею» (js/gallery.js): the works as framed pictures. Without JS or with reduced
   motion it is a grid of posters with museum labels (videos play from their controls). With JS
   it becomes a gallery wall: a ticket at the entrance, then vertical scroll pans the wall and
   Gleb walks along under the picture in the middle. --p is one art px in CSS px. */

:root,
:root[data-theme="light"] {
  --wall: var(--bg); /* same as the page: no faint seam (Gleb 23.10) */
  --baseboard: #cdc3b2;
  --floor: #d8cfbf;
  --frame-ink: #141310;
  --frame-body: #3b332c;
  --mat: #f6f2ea;
  --ticket: #f4e8cc;
  --ticket-ink: #2b2420;
}

:root[data-theme="dark"] {
  --wall: var(--bg);
  --baseboard: #2c2f34;
  --floor: #131517;
  --frame-ink: #0b0a09;
  --frame-body: #3d434b;
  --mat: #e7e1d6;
  --ticket: #efe2c3;
  --ticket-ink: #2b2420;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --wall: var(--bg);
    --baseboard: #2c2f34;
    --floor: #131517;
    --frame-ink: #0b0a09;
    --frame-body: #3d434b;
    --mat: #e7e1d6;
    --ticket: #efe2c3;
    --ticket-ink: #2b2420;
  }
}

.gallery {
  --p: 1px;
  max-width: 1240px;
  margin: 0 auto;
  padding: 72px var(--gutter) 24px;
}

.gallery__head {
  margin-bottom: 28px;
}

.gallery__head h2 {
  margin-top: 8px;
}

/* The grid: posters in pixel frames, a label under each. */
.gallery__track {
  display: grid;
  gap: 40px 32px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.work__frame {
  width: fit-content;
  max-width: 100%;
  padding: calc(4 * var(--p));
  background: var(--mat);
  box-shadow:
    0 0 0 var(--p) var(--frame-ink),
    0 0 0 calc(5 * var(--p)) var(--frame-body),
    0 0 0 calc(6 * var(--p)) var(--frame-ink),
    0 calc(9 * var(--p)) 0 calc(5 * var(--p)) var(--cast-shadow);
  margin: calc(6 * var(--p));
}

.work__video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: #0b0a09;
}

.work--v .work__video {
  width: auto;
  height: min(70vh, 560px);
  aspect-ratio: 9 / 16;
}

.work__label {
  max-width: 36ch;
  margin-top: calc(14 * var(--p) + 8px);
  font-size: 15px;
  line-height: 1.45;
}

.work__title {
  font-size: 19px;
  line-height: 1.2;
}

.work__meta {
  margin: 4px 0 8px;
  color: var(--fg-dim);
}

.work__row {
  color: var(--fg-dim);
}

.work__row + .work__row {
  margin-top: 4px;
}

.work__key {
  color: var(--fg);
  font-weight: 600;
}

.work--exit {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 16px;
}

.work__exit-text {
  font-size: 24px;
  line-height: 1.2;
  font-weight: 600;
}

.gallery__floor,
.gallery__guide,
.gallery__walker,
.gallery__ticket,
.gallery__puff {
  display: none;
}

@media (min-width: 760px) {
  .gallery {
    --p: 2px;
  }

  .gallery__track {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .gallery__track {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ---------- the wall (JS, motion allowed) ---------- */

.gallery.is-wall {
  --frame-vh: min(34svh, 330px); /* vertical works */
  --frame-h: calc(85vw * 9 / 16); /* horizontal works: about 85vw wide on phones */
  --floor-h: 132px;
  --eye-top: 132px;
  --feet-line: 24px; /* where Gleb's feet stand, from the bottom of the stage */
  position: relative;
  max-width: none;
  height: 100svh;
  padding: 0;
}

.gallery.is-wall.is-open {
  height: calc(100svh + var(--pan, 0px) * 0.5); /* the wall moves 2× faster than the page scroll (shorter page) */
}

.is-wall .gallery__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  overflow: clip; /* hidden still lets a focused frame scroll the stage sideways */
  background: var(--wall);
}

.is-wall .gallery__head {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  padding: 40px var(--gutter) 0;
}

.is-wall .gallery__track {
  position: absolute;
  top: var(--eye-top);
  left: 0;
  display: flex;
  align-items: flex-start;
  gap: 10vw;
  padding: 0 7.5vw;
  transform: translate3d(var(--x, 0px), 0, 0);
  will-change: transform;
  opacity: 1; /* frames show at once, no empty wall */
  transition: opacity 0.6s ease;
}

.is-open .gallery__track {
  opacity: 1;
}

.is-wall .work {
  flex: none;
}

.is-wall .work__video {
  width: calc(var(--frame-h) * 16 / 9);
  height: var(--frame-h);
}

.is-wall .work--v .work__video {
  width: calc(var(--frame-vh) * 9 / 16);
  height: var(--frame-vh);
}

/* Picture centres on one eye line. */
.is-wall .work:not(.work--v):not(.work--exit) {
  margin-top: calc((var(--frame-vh) - var(--frame-h)) / 2);
}

.is-wall .work--exit {
  min-height: var(--frame-vh);
  padding-right: 7.5vw;
}

.is-wall .gallery__floor {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--floor-h);
  background: var(--floor);
  border-top: calc(8 * var(--p)) solid var(--baseboard);
  box-shadow: 0 calc(-1 * var(--p)) 0 var(--frame-ink);
}

.is-wall .gallery__guide,
.is-wall .gallery__walker {
  position: absolute;
  z-index: 2;
  left: 0;
  bottom: var(--feet-line);
  will-change: transform;
}

.is-wall .gallery__guide:not([hidden]),
.is-wall .gallery__walker:not([hidden]) {
  display: block;
}

/* The ticket: cream, a perforated edge, the SALUT spark. A real button. */
.is-wall .gallery__ticket:not([hidden]) {
  position: absolute;
  z-index: 3;
  right: var(--gutter);
  bottom: calc(var(--feet-line) + 10px);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px 10px 22px;
  border: 0;
  background:
    radial-gradient(circle at 0 50%, var(--floor) 0 4px, transparent 4.5px) 0 0 / 8px 10px repeat-y,
    var(--ticket);
  color: var(--ticket-ink);
  font: 600 14px/1.2 var(--font);
  box-shadow: 0 0 0 var(--p) var(--frame-ink), 0 calc(3 * var(--p)) 0 var(--cast-shadow);
  cursor: pointer;
  transform: rotate(-4deg);
  transform-origin: 50% 50%;
  transition: transform 0.65s cubic-bezier(0.3, 0.7, 0.2, 1), opacity 0.4s ease;
}

.is-wall .gallery__ticket:not([hidden]) svg {
  width: 18px;
  height: 18px;
  shape-rendering: crispEdges;
}

.gallery__ticket:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 4px;
}

.gallery__ticket:hover {
  transform: rotate(-4deg) translateY(-3px);
}

.gallery__ticket.is-punched::after {
  content: "";
  position: absolute;
  right: 14px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-radius: 50%;
  background: var(--frame-ink);
}

.gallery__ticket.is-gone {
  opacity: 0;
  pointer-events: none;
}

.is-wall .gallery__puff:not([hidden]) {
  position: absolute;
  z-index: 4;
  display: block;
  width: 4px;
  height: 4px;
  background: var(--fg-dim);
  box-shadow: -10px -6px 0 var(--fg-dim), 9px -8px 0 var(--fg-dim), -6px 8px 0 var(--fg-dim), 10px 6px 0 var(--fg-dim),
    0 -12px 0 var(--fg-dim);
  animation: gallery-puff 0.45s steps(4, end) forwards;
}

@keyframes gallery-puff {
  to {
    opacity: 0;
    transform: scale(2.2);
  }
}

@media (min-width: 760px) {
  .gallery.is-wall {
    --frame-vh: min(34svh, 330px);
    --frame-h: calc(var(--frame-vh) * 0.62);
    --floor-h: min(210px, 25svh);
    --eye-top: 116px;
    --feet-line: 32px;
  }

  .is-wall .gallery__track {
    gap: 80px;
    padding: 0 max(var(--gutter), 12vw);
  }

  .is-wall .work__label {
    width: 34ch;
  }

  .is-wall .gallery__ticket:not([hidden]) {
    right: auto;
    left: calc(var(--gutter) + 420px);
  }
}

/* The label on the wall is a small SAR card (Задача, Что делали, Итог): wider than a vertical
   frame and a size smaller, so all three rows end above the floor and Gleb's line. */
.is-wall .work__label {
  width: min(34ch, 84vw);
  max-width: none;
  margin-top: calc(10 * var(--p) + 6px);
  font-size: 14px;
  line-height: 1.4;
}

.is-wall .work__title {
  font-size: 18px;
}

.is-wall .work__meta {
  margin: 2px 0 6px;
}

.is-wall .work__row + .work__row {
  margin-top: 2px;
}

/* Short phones (SE, 360×740): smaller frames, so the labels end above Gleb's line. */
@media (max-width: 759px) and (max-height: 780px) {
  .gallery.is-wall {
    --frame-vh: 30svh;
  }

  .is-wall .work__meta {
    display: none;
  }
}

/* Low desktop screens (laptops at 720–800 px): smaller frames and floor, so the SAR label of a
   vertical work still ends above the floor. */
@media (min-width: 760px) and (max-height: 820px) {
  .gallery.is-wall {
    --frame-vh: 29svh;
    --floor-h: 22svh;
    --eye-top: 104px;
  }

  .is-wall .work__meta {
    display: none;
  }
}

/* «Все работы на Яндекс Диске»: a quiet link under the heading and on the exit card. */
.gallery__disk {
  display: inline-block;
  margin-top: 10px;
  font-size: 15px;
  color: var(--fg);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.gallery__disk:hover {
  color: var(--accent-text, #a83a1b);
}

.work--exit .gallery__disk {
  display: block;
  margin-top: 16px;
}
