/* halfpast — minimal portfolio */

:root {
  --paper: #f0f0ec;
  --paper-deep: #e4e5df;
  --ink: #16171a;
  --ink-soft: #6c6e68;
  --rule: #c9cac3;
  --tally: #ff1493;
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Instrument Sans", "Helvetica Neue", Arial, sans-serif;
  --font-mono: "DM Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --gutter: clamp(1rem, 3vw, 3rem);
  --meta: 0.6875rem;
  --track: 0.14em;
}

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

html {
  background: var(--paper);
  color: var(--ink);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

[hidden] { display: none !important; }
img { display: block; max-width: 100%; }
a { color: inherit; }

::selection {
  background: var(--tally);
  color: var(--paper);
}

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--tally);
  outline-offset: 4px;
}

.skip {
  position: fixed;
  left: -9999px;
  top: 0;
  z-index: 20;
  padding: 0.75rem 1rem;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--meta);
}

.skip:focus { left: 0; }

/* Entrance */

.entrance {
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: var(--gutter);
}

.entrance__links {
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: center;
}

.entrance__links li + li { margin-top: 0.25rem; }

.entrance__links a {
  display: inline-block;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 104, "wght" 500;
  font-size: clamp(1.5rem, 1.05rem + 2vw, 3rem);
  line-height: 1.18;
  letter-spacing: -0.025em;
  text-decoration: none;
  transition: color 160ms ease, font-variation-settings 160ms ease;
}

.entrance__links a:hover,
.entrance__links a:focus-visible {
  color: var(--tally);
  font-variation-settings: "wdth" 104, "wght" 650;
}

/* Masthead: the name, with press and contact small beneath it */

.masthead {
  position: absolute;
  top: var(--gutter);
  left: var(--gutter);
  z-index: 5;
}

.portfolio__title {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 112, "wght" 620;
  font-size: clamp(1.5rem, 1.15rem + 1.4vw, 2.75rem);
  line-height: 0.9;
  letter-spacing: -0.035em;
  text-transform: lowercase;
}

.aside {
  display: flex;
  gap: 1.1rem;
  margin-top: 0.6rem;
}

.aside__link {
  appearance: none;
  border: 0;
  padding: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: clamp(var(--meta), 1.5vw, 0.8125rem);
  letter-spacing: var(--track);
  transition: color 160ms ease;
}

.aside__link:hover,
.aside__link:focus-visible,
.aside__link[aria-pressed="true"] { color: var(--tally); }

/* Centered text menu */

.menu {
  min-height: 100svh;
  display: grid;
  /* A set width, not one sized to the content: Safari widens a content-
     sized column to fit the open index's one-line row, and on a phone
     the page then scrolls sideways. */
  grid-template-columns: 100%;
  place-items: center;
  padding: clamp(4.5rem, 10vw, 7rem) var(--gutter);
}

.menu__inner {
  width: 100%;
  text-align: center;
}

.menu__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu__list > li { width: 100%; }

.menu__row,
.menu__every {
  appearance: none;
  display: inline-block;
  border: 0;
  border-bottom: 1px solid transparent;
  padding: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 104, "wght" 500;
  font-size: clamp(1.75rem, 1.1rem + 2.8vw, 4rem);
  line-height: 1.08;
  letter-spacing: -0.035em;
  transition: color 160ms ease, font-variation-settings 160ms ease;
}

.menu__row:hover,
.menu__row:focus-visible,
.menu__every:hover,
.menu__every:focus-visible {
  color: var(--tally);
}

.menu__row[aria-pressed="true"],
.menu__every[aria-pressed="true"] {
  color: var(--tally);
  font-variation-settings: "wdth" 104, "wght" 680;
}

.menu__foot { margin-top: 0.35rem; }

.menu__every {
  color: var(--ink-soft);
  font-size: clamp(1rem, 0.85rem + 0.7vw, 1.5rem);
  letter-spacing: -0.02em;
}

/* Open: the index folds into one small line, held at the top of the
   screen while the work scrolls under it. */

.menu--open {
  align-items: start;
  padding-top: calc(var(--gutter) + 4.25rem);   /* clears the masthead */
}

.menu--open .menu__index {
  position: sticky;
  top: 0;
  z-index: 6;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  padding: 0.8rem var(--gutter);
  background: var(--paper);
  animation: index-in 240ms ease both;
  /* One line always: on a narrow screen it scrolls sideways instead of
     wrapping. Overflowing lines start-align, so nothing is cut off. */
  white-space: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}

.menu--open .menu__index::-webkit-scrollbar { display: none; }

.menu--open .menu__list,
.menu--open .menu__list > li,
.menu--open .menu__foot { display: inline; }

.menu--open .menu__list > li,
.menu--open .menu__foot {
  margin: 0 clamp(0.45rem, 1vw, 0.8rem);
  white-space: nowrap;
}

.menu--open .menu__row,
.menu--open .menu__every {
  font-size: clamp(1rem, 0.85rem + 0.7vw, 1.5rem);
  letter-spacing: -0.02em;
}

@keyframes index-in { from { opacity: 0; } }

/* Full-width work */

#work {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  padding: clamp(1.5rem, 4vw, 3rem) 0 clamp(4rem, 10vw, 8rem);
  text-align: left;
}

#work.work--enter {
  animation: work-slide-down 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes work-slide-down {
  from {
    opacity: 0;
    transform: translateY(-1rem);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Press: one ruled line per write-up, outlet, headline, project */

.press {
  width: min(100%, 60rem);
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 3rem) 0 clamp(4rem, 10vw, 8rem);
  text-align: left;
}

.press.work--enter {
  animation: work-slide-down 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.press__list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-bottom: 1px solid var(--rule);
}

.press__link {
  display: grid;
  grid-template-columns: 10rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 1.25rem;
  padding: 0.95rem 0;
  border-top: 1px solid var(--rule);
  color: var(--ink);
  text-decoration: none;
}

.press__outlet,
.press__about {
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--meta);
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.press__about { text-align: right; white-space: nowrap; }

.press__title {
  font-family: var(--font-display);
  font-variation-settings: "wdth" 100, "wght" 560;
  font-size: clamp(1rem, 0.9rem + 0.5vw, 1.375rem);
  line-height: 1.25;
  letter-spacing: -0.012em;
  transition: color 160ms ease;
}

/* Archivo has no Cyrillic: set a Russian headline wholly in a system face
   rather than let its Latin words alone stay in Archivo. */
.press__title:lang(ru) {
  font-family: "Helvetica Neue", Arial, sans-serif;
  font-weight: 500;
}

.press__link:hover .press__title,
.press__link:focus-visible .press__title { color: var(--tally); }

/* Contact: a ruled form in the press panel's measure */

.contact {
  width: min(100%, 40rem);
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 3rem) 0 clamp(4rem, 10vw, 8rem);
  text-align: left;
}

.contact.work--enter {
  animation: work-slide-down 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.contact__field {
  display: block;
  padding: 0.95rem 0 0.6rem;
  border-top: 1px solid var(--rule);
}

.contact__label,
.contact__status {
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--meta);
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.contact__field input,
.contact__field textarea {
  display: block;
  width: 100%;
  margin-top: 0.4rem;
  border: 0;
  padding: 0.2rem 0;
  background: none;
  color: var(--ink);
  font-family: var(--font-display);
  font-variation-settings: "wdth" 100, "wght" 500;
  font-size: clamp(1rem, 0.9rem + 0.5vw, 1.375rem);
  line-height: 1.35;
  letter-spacing: -0.012em;
  resize: vertical;
}

.contact__field input:focus,
.contact__field textarea:focus { outline: none; }

.contact__field:focus-within { border-top-color: var(--tally); }
.contact__field:focus-within .contact__label { color: var(--tally); }

.contact__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.contact__foot {
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}

.contact__send {
  appearance: none;
  border: 0;
  padding: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 104, "wght" 600;
  font-size: clamp(1.25rem, 1rem + 1vw, 1.75rem);
  letter-spacing: -0.03em;
  transition: color 160ms ease;
}

.contact__send:hover,
.contact__send:focus-visible { color: var(--tally); }
.contact__send:disabled { color: var(--ink-soft); cursor: progress; }

.contact__status { margin: 0; }
.contact__status[data-state="sent"] { color: var(--ink); }
.contact__status[data-state="error"] { color: var(--tally); }

.grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(0.75rem, 2vw, 2rem);
  row-gap: clamp(4rem, 10vw, 9rem);
}

.grid[data-active="coding"] {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Video rows sit closer: each card already carries its own credit line. */
.grid[data-active="music-videos"],
.grid[data-active="interactive"] {
  row-gap: clamp(2.5rem, 5vw, 4.5rem);
}

.card { grid-column: 1 / -1; }
.card--video,
.card--effect,
.card--game { grid-column: span 1; }
/* The arcade is two games to a row at every size, phones included. */
.grid.grid[data-active="arcade"] {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  row-gap: clamp(2.5rem, 5vw, 4.5rem);
  /* Narrow enough on a computer that the pair and their titles fit
     on one screen. */
  max-width: 60rem;
  margin-inline: auto;
}
.grid[data-active="design"] .card[data-category="design"],
.grid[data-active="coding"] .card[data-category="coding"] { grid-column: span 1; }
.grid[data-active="all"] .card { grid-column: span 1; }
.card[hidden] { display: none; }

/* Walls (Photography, Design): one full-width card holding every image,
   packed edge to edge on cells of the wall's aspect (--cell, width over
   height). Placement is set inline by main.js. */

.grid[data-active] .card.card--wall {
  grid-column: 1 / -1;
  container-type: inline-size;
}

.wall {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(var(--cols, 6), minmax(0, 1fr));
  grid-auto-rows: calc(100cqi / var(--cols, 6) / var(--cell, 1));
}

.wall__tile {
  min-width: 0;
  overflow: hidden;
  background: var(--paper-deep);
}

.wall__hit {
  appearance: none;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}

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

.wall__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 500ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

.wall__hit:hover .wall__img,
.wall__hit:focus-visible .wall__img { transform: scale(1.012); }

/* Cover showcase (Design): one cover at a time in the 3D case. The flat
   poster sits where the case's booklet will be, so the case fades in
   without a jump, and it is all a browser without WebGL shows. The
   merch showcase is the same, with garments instead of the case. */

.grid[data-active] .card.card--showcase { grid-column: 1 / -1; }

.showcase {
  --show-w: min(100%, 72svh, 48rem);
  display: grid;
  justify-items: center;
  gap: clamp(0.75rem, 2vw, 1.25rem);
  padding-inline: var(--gutter);
}

.showcase__stage {
  position: relative;
  width: var(--show-w);
  aspect-ratio: 1;
  background: var(--paper);
}

.showcase__stage:focus-visible { outline-offset: 2px; }

.showcase__poster {
  position: absolute;
  top: var(--poster-y, 19.4%);
  left: var(--poster-x, 26%);
  width: var(--poster-w, 57.2%);
  aspect-ratio: 1;
  object-fit: cover;
  box-shadow: 0 1.4rem 2rem -1.6rem rgb(0 0 0 / 45%);
}

/* Laid over the poster. A vertical swipe still scrolls the page; a
   sideways drag turns the case. */
.showcase__stage canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
  touch-action: pan-y;
  animation: case-in 400ms ease both;
}

.showcase__stage canvas.is-dragging { cursor: grabbing; }

/* Merch: the product photo fills the stage, its white backdrop taken
   down to the paper, but only where 3D can't run. Otherwise the stage
   stays bare paper until the garment fades in, already swaying, so it
   is never seen standing still. */
.showcase--merch .showcase__poster {
  top: 0;
  left: 0;
  width: 100%;
  box-shadow: none;
  mix-blend-mode: multiply;
}

.showcase--merch .showcase__stage:not(.is-flat) .showcase__poster { visibility: hidden; }

@keyframes case-in { from { opacity: 0; } }

.showcase__bar {
  width: var(--show-w);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.showcase__caption {
  flex: 1;
  margin: 0;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--meta);
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.showcase__dots {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.showcase__dot {
  appearance: none;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.showcase__dot::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  border: 1px solid var(--ink-soft);
  border-radius: 50%;
}

.showcase__dot:hover::before { border-color: var(--tally); }

.showcase__dot[aria-pressed="true"]::before {
  border-color: var(--ink);
  background: var(--ink);
}

.showcase__counter {
  flex: none;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--meta);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--track);
}

.showcase__thumbs {
  position: relative;
  width: var(--show-w);
  list-style: none;
  margin: 0;
  padding: 3px;
  display: grid;
  grid-template-columns: repeat(var(--count, 9), minmax(0, 1fr));
  gap: 0.4rem;
}

.showcase__thumb {
  appearance: none;
  display: block;
  width: 100%;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  background: var(--paper-deep);
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 160ms ease;
}

.showcase__thumb:hover,
.showcase__thumb[aria-current="true"] { opacity: 1; }

.showcase__thumb[aria-current="true"] {
  outline: 2px solid var(--tally);
  outline-offset: 1px;
}

.showcase__thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Only a couple of merch pieces: keep their thumbnails thumbnail-sized. */
.showcase--merch .showcase__thumbs {
  grid-template-columns: repeat(var(--count), minmax(0, 6rem));
  justify-content: center;
}

.showcase--merch .showcase__thumb-img { mix-blend-mode: multiply; }

.card__hit {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  font: inherit;
  text-align: left;
  text-decoration: none;
}

.card__frame {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--paper-deep);
  aspect-ratio: var(--ar, 16 / 9);
}

.card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 500ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

.card__hit:hover .card__img,
.card__hit:focus-visible .card__img { transform: scale(1.012); }

.card__cue {
  position: absolute;
  left: var(--gutter);
  bottom: var(--gutter);
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0.6rem;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: var(--track);
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(0.35rem);
  transition: opacity 180ms ease, transform 180ms ease;
}

.card__cue::before {
  content: "";
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: var(--tally);
}

.card__hit:hover .card__cue,
.card__hit:focus-visible .card__cue {
  opacity: 1;
  transform: none;
}

/* No hover on touch screens: a video's Play cue, and a filter's, show
   from the start. */
@media (hover: none) {
  .card--video .card__cue,
  .card--effect .card__cue {
    opacity: 1;
    transform: none;
  }
}

.card__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 var(--gutter);
  padding-top: 0.8rem;
  border-top: 1px solid var(--rule);
}

.card--video .card__meta,
.card--effect .card__meta {
  margin-inline: clamp(0.75rem, 1.5vw, 1.5rem);
}

.grid[data-active="design"] .card[data-category="design"] .card__meta,
.grid[data-active="coding"] .card[data-category="coding"] .card__meta,
.grid[data-active="all"] .card__meta {
  margin-inline: clamp(0.75rem, 1.5vw, 1.5rem);
}

.card--video .card__cue,
.card--effect .card__cue,
.grid[data-active="design"] .card[data-category="design"] .card__cue,
.grid[data-active="coding"] .card[data-category="coding"] .card__cue,
.grid[data-active="all"] .card__cue {
  left: clamp(0.75rem, 1.5vw, 1.5rem);
  bottom: clamp(0.75rem, 1.5vw, 1.5rem);
}

/* A filter's cue, on hover, is a band across the middle of its still.
   Touch screens keep the small one in the corner so the still shows. */
@media (hover: hover) {
  .grid .card--effect .card__cue {
    left: 0;
    right: 0;
    top: 50%;
    bottom: auto;
    justify-content: center;
    gap: 0.5em;
    padding: 0.45em 1rem;
    font-family: var(--font-display);
    font-variation-settings: "wdth" 104, "wght" 620;
    font-size: clamp(1.75rem, 1rem + 2.4vw, 3.25rem);
    letter-spacing: -0.025em;
    text-transform: none;
    transform: translateY(-50%) scaleY(0.4);
  }

  .grid .card--effect .card__cue::before {
    width: 0.32em;
    height: 0.32em;
  }

  .grid .card--effect .card__hit:hover .card__cue,
  .grid .card--effect .card__hit:focus-visible .card__cue {
    transform: translateY(-50%);
  }
}

.work__note {
  max-width: 62ch;
  margin: 0 auto clamp(2rem, 4vw, 3.5rem);
  padding-inline: clamp(0.75rem, 1.5vw, 1.5rem);
  text-align: center;
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-size: clamp(0.875rem, 0.82rem + 0.2vw, 1rem);
  line-height: 1.45;
}

.card__title {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 100, "wght" 560;
  font-size: clamp(1rem, 0.9rem + 0.5vw, 1.375rem);
  line-height: 1.2;
  letter-spacing: -0.012em;
}

.card__description {
  max-width: 62ch;
  margin: 0.55rem 0 0;
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-size: clamp(0.875rem, 0.82rem + 0.2vw, 1rem);
  line-height: 1.45;
}

.card__client {
  display: block;
  margin-top: 0.2rem;
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 400;
}

.card__spec {
  flex: none;
  margin: 0;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--meta);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--track);
  text-align: right;
  white-space: nowrap;
}

.card__spec span { display: block; }
.card__spec span + span { margin-top: 0.2rem; color: var(--rule); }

.grid__empty {
  margin: 0;
  padding: var(--gutter);
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--meta);
  letter-spacing: var(--track);
  text-align: center;
  text-transform: uppercase;
}

/* Media viewer */

.lb {
  width: max-content;
  max-width: min(92vw, 1400px);
  max-height: 92vh;
  margin: auto;
  padding: 0;
  overflow: visible;
  border: 0;
  background: var(--paper);
  color: var(--ink);
}

.lb::backdrop { background: rgb(16 17 20 / 93%); }

.lb__stage {
  width: min(92vw, 1400px, calc(80vh * var(--lb-arnum, 1.7778)));
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #000;
  aspect-ratio: var(--lb-ar, 16 / 9);
}

.lb__stage iframe { display: block; width: 100%; height: 100%; border: 0; }

/* A filter on the camera: the viewer letterboxes its canvas to 9:16
   inside .lb__tryon. Notes sit centred while there is no picture,
   and at the foot once the camera shows the visitor. */
.lb__stage:has(.lb__tryon) { position: relative; }
.lb__tryon { display: grid; place-items: center; width: 100%; height: 100%; }

.lb__note {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 1rem;
  padding: var(--gutter);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--meta);
  letter-spacing: 0.04em;
  line-height: 1.6;
  text-align: center;
  pointer-events: none;
}

.lb__note p { max-width: 30ch; margin: 0; }
.lb__note[data-state="face"] { display: none; }
.lb__note[data-state="no-face"] { place-content: end center; }
.lb__note[data-state="no-face"] p {
  padding: 0.35rem 0.6rem;
  background: rgb(16 17 20 / 60%);
}

.lb__again {
  appearance: none;
  border: 0;
  border-bottom: 1px solid var(--tally);
  padding: 0.15rem 0;
  background: none;
  color: inherit;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--meta);
  letter-spacing: var(--track);
  text-transform: uppercase;
  pointer-events: auto;
}
.lb__stage img { width: 100%; height: 100%; object-fit: contain; }

.lb__bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1rem;
  /* As wide as the stage, never wider: a long caption wraps rather than
     stretching the viewer past the picture. */
  box-sizing: border-box;
  width: 0;
  min-width: 100%;
}

.lb__caption {
  margin: 0;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--meta);
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.lb__nav {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
}

.lb__step,
.lb__close {
  appearance: none;
  border: 0;
  border-bottom: 1px solid transparent;
  padding: 0.15rem 0;
  background: none;
  color: inherit;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--meta);
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.lb__step:hover,
.lb__close:hover { border-bottom-color: var(--tally); }

.lb__counter {
  min-width: 3.5em;
  color: var(--rule);
  font-family: var(--font-mono);
  font-size: var(--meta);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--track);
  text-align: center;
}

.lb__close {
  position: absolute;
  top: -2.4rem;
  right: 0;
  color: var(--paper);
}

/* A game takes the whole screen: a thin strip for Close, the game
   under it. The game's own page fits itself to the frame. */
.lb.lb--game {
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100vh;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding-top: 2.6rem;
  box-sizing: border-box;
  background: rgb(16 17 20);
}
.lb--game::backdrop { background: rgb(16 17 20); }
.lb--game .lb__stage { width: 100%; height: 100%; aspect-ratio: auto; }
.lb--game .lb__bar { display: none; }
.lb--game .lb__close { top: 0.75rem; right: 1rem; }
html:has(.lb--game[open]) { overflow: hidden; overscroll-behavior: none; }

@media (max-width: 34rem) {
  .grid { grid-template-columns: 1fr; }
  .grid[data-active="coding"] { grid-template-columns: 1fr; }
  .card--video,
  .card--effect { grid-column: 1 / -1; }
  .masthead { top: 1rem; left: 1rem; }
  .lb__bar { flex-direction: column; align-items: stretch; gap: 0.6rem; }
  .showcase__bar { flex-wrap: wrap; }
  .showcase__caption { flex-basis: 100%; }
  .showcase__counter { margin-left: auto; }
  .showcase__thumbs {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 4.5rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .showcase__thumbs li { scroll-snap-align: center; }
  .press__link { grid-template-columns: minmax(0, 1fr) auto; row-gap: 0.35rem; }
  .press__title { grid-column: 1 / -1; grid-row: 2; }
  .lb__nav { justify-content: space-between; }
  .lb__close { top: -2.1rem; }
}

@media (min-width: 34.01rem) and (max-width: 56rem) {
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid[data-active="design"],
  .grid[data-active="all"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .card__cue { opacity: 1; transform: none; }
}

/* A filter's band still waits for hover; it just doesn't move in. */
@media (prefers-reduced-motion: reduce) and (hover: hover) {
  .grid .card--effect .card__cue { opacity: 0; transform: translateY(-50%); }
  .grid .card--effect .card__hit:hover .card__cue,
  .grid .card--effect .card__hit:focus-visible .card__cue { opacity: 1; }
}
