/* ------------------------------------------------------------
   Selected projects
   Builds on styles.css and the shared bar in landing.css.
   The cards are built from projects.md by projects.js.
   ------------------------------------------------------------ */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Scroll area ----------
   The page itself stays put; the projects scroll inside the frame,
   between the bar and the bottom line */

.projects-page .content {
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  padding: calc(46 * var(--u)) calc(43 * var(--u)) calc(60 * var(--u));
}

.projects-page .content::-webkit-scrollbar {
  display: none;
}

/* ---------- Grid ----------
   Three columns, two in narrower windows; projects run row by row
   from left to right. Lines: outline around the grid, and the
   column lines drawn by the grid itself, so they always run the
   full height (also below the last row and past empty cells). */

.projects-grid {
  --columns: 3;
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--columns), 1fr);
  margin: 0;
  padding: 0 0 calc(41 * var(--u));
  list-style: none;
  box-shadow: inset 0 0 0 var(--stroke) var(--ink); /* not border: browsers round thin borders down */
}

.projects-grid::before,
.projects-grid::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: var(--stroke);
  background: var(--ink);
  pointer-events: none;
}

.projects-grid::before { left: calc(100% / var(--columns)); }
.projects-grid::after  { left: calc(200% / var(--columns)); }

@media (max-width: 1100px) {
  .projects-grid {
    --columns: 2;
  }

  .projects-grid::after {
    display: none;
  }
}

.project {
  padding: max(16px, calc(41 * var(--u))) max(14px, calc(39 * var(--u))) 0;
  /* No fade: the cards simply appear, the first rows one after another */
  animation: show 0.01s steps(1) calc(var(--t0) + min(var(--i), 8) * 0.08s) backwards;
}

/* No project left: "nothing to see here", centred in the area
   below the bar */
.projects-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  animation: show 0.01s steps(1) backwards;
}

.projects-empty[hidden],
.projects-grid[hidden] {
  display: none;
}

.projects-empty img {
  display: block;
  width: max(70px, calc(120 * var(--u)));
  height: auto;
}

/* ---------- Card ----------
   Sizes inside the card follow its width (cqw = 1% of it), so the
   hover panel looks the same in three or two columns */

.project__link {
  position: relative;
  display: block;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  container-type: inline-size;
  color: var(--ink);
  text-decoration: none;
}

/* Outline on top of image and panel */
.project__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  box-shadow: inset 0 0 0 var(--stroke) var(--ink);
  pointer-events: none;
}

.project__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Hover: a white panel with lettering and subtitle slides up */
.project__info {
  position: absolute;
  z-index: 1;
  left: 0;
  right: 0;
  bottom: 0;
  height: 38%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.6cqw;
  padding: 0 8.2cqw;
  box-shadow: inset 0 var(--stroke) 0 0 var(--ink);
  background: var(--bg);
  transform: translateY(101%);
  transition: transform 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}

.project__link:hover .project__info,
.project__link:focus-visible .project__info {
  transform: none;
}

/* All letterings at the same letter size (--scale: see projects.js);
   only if one ever were too wide would it shrink to fit */
.project__lettering {
  display: block;
  height: calc(3.6cqw * var(--scale, 1));
  max-width: 100%;
  object-fit: contain;
  object-position: left center;
}

.project__name {
  font-size: 5cqw;
  line-height: 1;
}

.project__subtitle {
  font-size: max(13.5px, 4cqw);
  line-height: 1.15;
}

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

/* The imprint / privacy pop-up takes the place of the content,
   the filters make room as well */
.legal-open .filters {
  visibility: hidden;
}

/* ---------- Filters (filters.js) ----------
   Fixed on the left frame line. Closed it is a small button; open,
   it grows to the right and down to the bottom line. The title and
   the upper groups stay in place, the last group scrolls behind
   them. */

.filters {
  --muted: #b4b4b4;
  --top: calc(var(--margin) + var(--bar-height) + 130 * var(--u));
  --width: calc(163 * var(--tu));
  --height: calc(83 * var(--tu));
  position: fixed;
  z-index: 5;
  left: var(--margin);
  top: var(--top);
  display: flex;
  flex-direction: column;
  width: var(--width);
  height: var(--height);
  overflow: hidden;
  background: var(--bg);
  font-size: calc(19 * var(--tu));
  transition:
    width 0.45s cubic-bezier(0.65, 0, 0.35, 1),
    height 0.45s cubic-bezier(0.65, 0, 0.35, 1);
  animation: show 0.01s steps(1) var(--t0) backwards;
}

/* Outline on top of the contents */
.filters::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  box-shadow: inset 0 0 0 var(--stroke) var(--ink); /* not border: browsers round thin borders down */
  pointer-events: none;
}

.filters.is-open {
  --width: calc(208 * var(--tu));
  --height: calc(100svh - var(--top) - var(--margin));
}

.filters__toggle {
  --bold-stretch: 96.25%;
  position: relative;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  height: calc(83 * var(--tu));
  padding: 0 0 0 calc(41 * var(--tu));
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  letter-spacing: 0.01em;
  text-align: left;
  text-transform: uppercase;
  cursor: pointer;
  /* Hover: eases into bold, the width axis keeps the text size */
  transition:
    padding 0.45s cubic-bezier(0.65, 0, 0.35, 1),
    font-weight 0.4s ease,
    font-stretch 0.4s ease;
}

.filters.is-open .filters__toggle {
  padding-left: calc(26 * var(--tu));
  font-weight: 700;
  font-stretch: var(--bold-stretch);
}

.filters__toggle:hover,
.filters__toggle:focus-visible {
  font-weight: 700;
  font-stretch: var(--bold-stretch);
}

/* Close cross, only when open; on hover its outline thickens */
.filters__close {
  position: absolute;
  right: calc(22 * var(--tu));
  top: 50%;
  width: calc(24 * var(--tu));
  margin-top: calc(-12 * var(--tu));
  overflow: visible;
  fill: currentColor;
  stroke: currentColor;
  stroke-width: 0;
  opacity: 0;
  transition: opacity 0.3s ease, stroke-width 0.35s ease;
}

.filters.is-open .filters__close {
  opacity: 1;
  /* only once the panel is wide enough */
  transition-delay: 0.4s, 0s;
}

.filters.is-open .filters__toggle:hover .filters__close,
.filters.is-open .filters__toggle:focus-visible .filters__close {
  stroke-width: 7px;
}

.filters__panel {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.filters.is-open .filters__panel {
  opacity: 1;
  transition: opacity 0.3s ease 0.2s;
}

/* Groups, each with a line on top */
.filters__group {
  flex-shrink: 0;
  padding: calc(12 * var(--tu)) 0;
  box-shadow: inset 0 var(--stroke) 0 0 var(--ink);
  background: var(--bg);
}

.filters__scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
}

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

/* One option: box + label; long labels wrap by whole words */
.filters__option {
  display: flex;
  align-items: flex-start;
  gap: calc(17 * var(--tu));
  width: 100%;
  padding: calc(9 * var(--tu)) calc(20 * var(--tu)) calc(9 * var(--tu)) calc(24 * var(--tu));
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-weight: 500;
  line-height: 1.15;
  text-align: left;
  overflow-wrap: normal;
  hyphens: none;
  cursor: pointer;
}

.filters__box {
  flex-shrink: 0;
  width: calc(17 * var(--tu));
  height: calc(17 * var(--tu));
  margin-top: 0.08em;
  box-shadow: inset 0 0 0 var(--stroke) var(--ink);
  background: transparent;
  transition: background-color 0.2s ease;
}

/* Selected = filled. On hover the box shows the other state */
.filters__option[aria-checked="true"] .filters__box,
.filters__option[aria-checked="false"]:hover .filters__box,
.filters__option[aria-checked="false"]:focus-visible .filters__box {
  background: var(--ink);
}

.filters__option[aria-checked="true"]:hover .filters__box,
.filters__option[aria-checked="true"]:focus-visible .filters__box {
  background: transparent;
}

/* Topic group fully selected: a click selects only that topic, so
   the hover previews it: the others turn to outlines */
.filters__scroll.is-full:has(.filters__option:not(:disabled):hover) .filters__option .filters__box {
  background: transparent;
}

.filters__scroll.is-full .filters__option:not(:disabled):hover .filters__box,
.filters__scroll.is-full .filters__option:not(:disabled):focus-visible .filters__box {
  background: var(--ink);
}

/* Topics that would leave no project: greyed out, not clickable */
.filters__option:disabled {
  color: var(--muted);
  cursor: default;
}

.filters__option:disabled .filters__box,
.filters__option:disabled:hover .filters__box {
  background: transparent;
  box-shadow: inset 0 0 0 var(--stroke) var(--muted);
}

/* Scroll hint: arrow pointing down in its own strip at the bottom,
   while more filters follow */
.filters__more {
  flex-shrink: 0;
  align-self: flex-end;
  width: calc(26 * var(--tu));
  height: calc(26 * var(--tu));
  margin: calc(10 * var(--tu)) calc(20 * var(--tu)) calc(16 * var(--tu));
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
}

.filters__more[hidden] {
  visibility: hidden;
  display: block;
}

.filters__more svg {
  display: block;
  width: 100%;
  fill: currentColor;
  transform: rotate(90deg);
}

.filters__toggle:focus-visible,
.filters__option:focus-visible,
.filters__more:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: -4px;
}
