:root {
  --bg: #0e0e0e;
  --fg: #f2f2f0;
  --muted: #8a8a86;
  --line: #262626;
  --tab-line: #4a4a47;
  --tab-fill: #d6d6d2;
  --subtab-fill: #2a2a28;
  --surface: #1a1a1a;
  --gutter: 16px;
  --section-gap: 72px;
  --max-width: 1400px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  color-scheme: dark;
}

@media (min-width: 768px) {
  :root {
    --gutter: 32px;
    --section-gap: 96px;
  }
}

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

html {
  scrollbar-gutter: stable;
  /* No font inflation when a phone turns to landscape */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* No grey flash on tap. Each control has its own :active state instead. */
  -webkit-tap-highlight-color: transparent;
}

/* No page scroll behind the open lightbox */
html:has(.lightbox[open]) {
  overflow: hidden;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

img,
video {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
}

/* Controls: no wait for a possible double tap, and no text selection or menu on a long press.
   The contact links are content, so people can still select and copy the email address. */
a,
button {
  touch-action: manipulation;
}

button,
.logo,
nav a {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 4px;
}

/* Header */

/* On a narrow phone, the menu moves to its own line under the logo */
.site-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px 24px;
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 24px var(--gutter);
}

/* Bold italic capitals, cut by thin diagonal stripes that lean like a backslash, against the italic letters.
   The cuts are a mask, so they show the page background through the letters. */
.logo {
  flex-shrink: 0;
  /* The padding of the first word moves the visible letters off the gutter, this pulls them back */
  margin-left: -0.1em;
  font-size: 22px;
  font-weight: 800;
  font-style: italic;
  line-height: 1;
  white-space: nowrap;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.logo span {
  display: inline-block;
  /* Room for the slanted letters on both sides, so the mask does not cut off their edges */
  padding-inline: 0.1em;
  /* A cut of 0.12em in every 0.76em, leaning like a backslash, 40 degrees from vertical.
     Each edge fades over 1.2px, because a hard edge in a diagonal gradient looks jagged. */
  -webkit-mask-image: repeating-linear-gradient(
    50deg,
    #000 0 calc(0.6em - 0.6px),
    transparent calc(0.6em + 0.6px) calc(0.72em - 0.6px),
    #000 calc(0.72em + 0.6px) 0.76em
  );
  mask-image: repeating-linear-gradient(
    50deg,
    #000 0 calc(0.6em - 0.6px),
    transparent calc(0.6em + 0.6px) calc(0.72em - 0.6px),
    #000 calc(0.72em + 0.6px) 0.76em
  );
}

nav {
  display: flex;
  gap: 16px;
}

@media (min-width: 768px) {
  nav {
    gap: 24px;
  }
}

/* The padding makes the tap area 44px high, and the negative margin keeps the layout the same */
nav a {
  padding-block: 10px;
  margin-block: -10px;
  color: var(--muted);
  transition: color 150ms ease;
}

nav a:active {
  color: var(--fg);
}

@media (hover: hover) and (pointer: fine) {
  nav a:hover {
    color: var(--fg);
  }
}

/* Main */

/* A gap, not margins, so a hidden section leaves no empty space */
main {
  display: flex;
  flex-direction: column;
  gap: var(--section-gap);
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

section[id] {
  scroll-margin-top: 24px;
}

h2 {
  margin: 0 0 24px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Hero */

/* Wide like a cinema screen from 768px. 16:9 on a phone, because 21:9 is too low there.
   The box keeps its size while the video list loads, so the page below does not jump. */
.hero {
  aspect-ratio: 16 / 9;
  background: var(--surface);
}

@media (min-width: 768px) {
  .hero {
    aspect-ratio: 21 / 9;
  }
}

.hero video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Category tabs */

/* Square tabs that stand on a line. The open tab is filled light grey with dark text. */

.tabs {
  display: flex;
  border-bottom: 1px solid var(--tab-line);
  overflow-x: auto;
  scrollbar-width: none;
}

.tabs::-webkit-scrollbar {
  display: none;
}

.tab {
  flex: 0 0 auto;
  padding: 12px 20px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.4;
  cursor: pointer;
  transition:
    color 150ms ease,
    background-color 150ms ease;
}

.tab:focus-visible {
  outline-offset: -4px;
}

.tab[aria-pressed="true"] {
  background: var(--tab-fill);
  color: var(--bg);
  font-weight: 500;
}

.tab[aria-pressed="true"]:focus-visible {
  outline-color: var(--bg);
}

.tab:not([aria-pressed="true"]):active {
  background: var(--surface);
  color: var(--fg);
}

@media (hover: hover) and (pointer: fine) {
  .tab:not([aria-pressed="true"]):hover {
    background: var(--surface);
    color: var(--fg);
  }
}

/* Subcategory tabs: a smaller second row under the line. The open one has a dark fill, so the
   light fill of the category tab above stays the strongest mark. */

.subtabs {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}

.subtabs[hidden] {
  display: none;
}

.subtabs::-webkit-scrollbar {
  display: none;
}

.subtab {
  flex: 0 0 auto;
  padding: 6px 12px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.4;
  cursor: pointer;
  transition:
    color 150ms ease,
    background-color 150ms ease;
}

.subtab:focus-visible {
  outline-offset: -3px;
}

.subtab[aria-pressed="true"] {
  background: var(--subtab-fill);
  color: var(--fg);
}

.subtab:not([aria-pressed="true"]):active {
  color: var(--fg);
}

@media (hover: hover) and (pointer: fine) {
  .subtab:not([aria-pressed="true"]):hover {
    color: var(--fg);
  }
}

/* Larger tap areas for a finger */
@media (pointer: coarse) {
  .subtab {
    padding: 10px 14px;
  }
}

/* Each tab row sits in a scroller with an arrow on each side. main.js shows an arrow only
   when the row has more tabs on that side. The arrows fade the tabs under them into the page. */

.scroller {
  position: relative;
}

.scroller:has(> .tabs) {
  margin-bottom: 24px;
}

.scroller:has(> .subtabs) {
  margin: -12px 0 24px;
}

.scroller:has(> .subtabs[hidden]) {
  display: none;
}

.scroll-arrow {
  position: absolute;
  top: 0;
  /* Keeps the line under the category tabs visible */
  bottom: 1px;
  z-index: 1;
  display: flex;
  align-items: center;
  width: 44px;
  padding: 0 6px;
  border: 0;
  color: var(--fg);
  cursor: pointer;
  transition: transform 160ms ease-out;
}

.scroll-arrow[hidden] {
  display: none;
}

.scroll-arrow--left {
  left: 0;
  justify-content: flex-start;
  background: linear-gradient(to right, var(--bg) 55%, transparent);
}

.scroll-arrow--right {
  right: 0;
  justify-content: flex-end;
  background: linear-gradient(to left, var(--bg) 55%, transparent);
}

.scroll-arrow svg {
  width: 10px;
  height: 18px;
}

.scroll-arrow:active {
  transform: scale(0.95);
}

/* Video carousel. On a phone the arrows sit over the video, from 768px they sit beside it. */

.carousel {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
}

.carousel-viewport {
  min-width: 0;
  overflow: hidden;
  /* main.js handles the sideways swipe, the browser keeps the vertical page scroll */
  touch-action: pan-y;
}

.carousel-track {
  display: flex;
  transition: transform 400ms var(--ease-out);
}

/* 4:5 on a phone, so vertical videos are not tiny. Wide videos then get bars above and below. */
.carousel-slide {
  flex: 0 0 100%;
  aspect-ratio: 4 / 5;
  background: #000;
  transition: opacity 200ms ease-out;
}

@media (min-width: 768px) {
  .carousel-slide {
    aspect-ratio: 16 / 9;
  }
}

@starting-style {
  .carousel-slide {
    opacity: 0;
  }
}

.carousel-slide img,
.carousel-slide video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Large thin chevrons without a background */
.carousel-arrow {
  position: absolute;
  top: 50%;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 48px;
  height: 80px;
  padding: 0;
  translate: 0 -50%;
  border: 0;
  background: transparent;
  color: var(--fg);
  opacity: 0.85;
  cursor: pointer;
  /* Keeps the chevron visible over a light video on a phone */
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.6));
  transition:
    opacity 150ms ease,
    transform 160ms ease-out;
}

.carousel-arrow svg {
  width: 24px;
  height: 48px;
}

.carousel-arrow path {
  vector-effect: non-scaling-stroke;
}

.carousel-arrow[hidden] {
  display: none;
}

.carousel-arrow--prev {
  left: 0;
}

.carousel-arrow--next {
  right: 0;
}

.carousel-arrow:active {
  transform: scale(0.95);
}

@media (hover: hover) and (pointer: fine) {
  .carousel-arrow:hover {
    opacity: 1;
  }
}

@media (min-width: 768px) {
  .carousel {
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 8px;
  }

  .carousel-arrow {
    position: static;
    width: 56px;
    height: 120px;
    translate: none;
    opacity: 0.6;
    filter: none;
  }

  .carousel-arrow svg {
    width: 36px;
    height: 80px;
  }
}

/* Thumbnail row under the carousel */

.thumbs {
  position: relative;
  display: flex;
  gap: 8px;
  margin-top: 16px;
  padding: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}

.thumbs::-webkit-scrollbar {
  display: none;
}

/* Centers the row when it fits, and keeps the first thumbnail reachable when it does not */
.thumb:first-child {
  margin-left: auto;
}

.thumb:last-child {
  margin-right: auto;
}

.thumb {
  flex: 0 0 auto;
  width: 88px;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 0;
  border-radius: 4px;
  overflow: hidden;
  background: var(--surface);
  cursor: pointer;
  opacity: 0.4;
  transition:
    opacity 150ms ease,
    transform 160ms ease-out;
}

@media (min-width: 768px) {
  .thumb {
    width: 120px;
  }
}

.thumb img,
.thumb video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

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

.thumb:active {
  transform: scale(0.95);
}

@media (hover: hover) and (pointer: fine) {
  .thumb:not([aria-current="true"]):hover {
    opacity: 0.75;
  }
}

/* Photo grid: 2 columns on a phone, 4 from 768px */

.photo-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

@media (min-width: 768px) {
  .photo-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.photo {
  aspect-ratio: 4 / 5;
  padding: 0;
  border: 0;
  overflow: hidden;
  background: var(--surface);
  cursor: zoom-in;
  transition:
    opacity 200ms ease-out,
    transform 160ms ease-out;
}

@starting-style {
  .photo {
    opacity: 0;
  }
}

.photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 150ms ease;
}

.photo:active {
  transform: scale(0.98);
}

@media (hover: hover) and (pointer: fine) {
  .photo:hover img {
    opacity: 0.85;
  }
}

/* Lightbox. It closes faster than it opens. */

.lightbox {
  max-width: none;
  max-height: none;
  padding: 0;
  border: 0;
  overflow: visible;
  background: transparent;
  opacity: 0;
  transform: scale(0.96);
  transition:
    opacity 150ms ease-out,
    transform 150ms ease-out,
    overlay 150ms ease-out allow-discrete,
    display 150ms ease-out allow-discrete;
}

.lightbox[open] {
  opacity: 1;
  transform: none;
  transition-duration: 200ms;
}

@starting-style {
  .lightbox[open] {
    opacity: 0;
    transform: scale(0.96);
  }
}

.lightbox::backdrop {
  background: rgb(0 0 0 / 0);
  transition:
    background-color 150ms ease-out,
    overlay 150ms ease-out allow-discrete,
    display 150ms ease-out allow-discrete;
}

.lightbox[open]::backdrop {
  background: rgb(0 0 0 / 0.85);
  transition-duration: 200ms;
}

@starting-style {
  .lightbox[open]::backdrop {
    background: rgb(0 0 0 / 0);
  }
}

.lightbox img {
  width: auto;
  height: auto;
  max-width: min(100vw - 32px, 1100px);
  max-height: 80vh;
  max-height: 80dvh;
}

.lightbox-close {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: rgb(14 14 14 / 0.7);
  cursor: pointer;
  transition: transform 160ms ease-out;
}

.lightbox-close:active {
  transform: scale(0.95);
}

/* About and contact */

#about p {
  max-width: 60ch;
  margin: 0 0 16px;
  font-size: 18px;
}

#about p:last-child {
  margin-bottom: 0;
}

/* The opening statement: what he delivers, larger than the rest */
#about .about-lead {
  max-width: 20ch;
  margin-bottom: 32px;
  font-size: clamp(28px, 5vw, 44px);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.contact-links {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 24px;
}

.contact-links a {
  transition: color 150ms ease;
}

.contact-links a:active {
  color: var(--muted);
}

@media (hover: hover) and (pointer: fine) {
  .contact-links a:hover {
    color: var(--muted);
  }
}

/* Footer */

.site-footer {
  max-width: var(--max-width);
  margin: var(--section-gap) auto 0;
  padding: 32px var(--gutter);
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 14px;
}

/* Reduced motion: no sliding or scaling, the fades stay */

@media (prefers-reduced-motion: reduce) {
  .carousel-track {
    transition: none;
  }

  .lightbox,
  .lightbox[open] {
    transform: none;
  }

  @starting-style {
    .lightbox[open] {
      transform: none;
    }
  }
}
