/* ==========================================================================
   main.css — layout & components (v2 · lab file)
   All color, spacing and type values come from tokens.css.
   ========================================================================== */

/* ---------- Base ---------- */
html {
  scrollbar-gutter: stable;
}

html.no-scroll {
  overflow: hidden;
}

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

body {
  font-family: var(--font-mono);
  font-size: var(--type-body);
  line-height: var(--leading-base);
  color: var(--color-fg-invert);
  background: var(--color-paper);
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

:focus-visible {
  outline: var(--hairline) solid currentColor;
  outline-offset: 2px;
}

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

/* ---------- Page frame ----------
   The width limiter. Dashed rules are fixed to the viewport but offset to
   line up with the (centered, max-width) content column's edges. */
.frame {
  position: relative;
  width: 100%;
  max-width: var(--content-max-width);
  margin-inline: auto;
}

/* Vertical dashed rules — commented out.
.frame::before,
.frame::after {
  content: "";
  position: fixed;
  top: 0;
  bottom: 0;
  width: var(--hairline);
  z-index: 2;
  background-image: repeating-linear-gradient(
    to bottom,
    var(--color-ruler) 0 var(--dash-length),
    transparent var(--dash-length) calc(var(--dash-length) * 2)
  );
}

.frame::before { left: max(0px, calc((100vw - var(--content-max-width)) / 2)); }
.frame::after { right: max(0px, calc((100vw - var(--content-max-width)) / 2)); }
*/

/* Shared 8-column grid track */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  gap: var(--grid-gutter);
}

/* Mono meta text — the default voice of the interface */
.meta {
  font-family: var(--font-mono);
  font-size: var(--type-body);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
}

/* ---------- Masthead ----------
   Sticky, but negative z-index so page content scrolls over it. */
.masthead-sticky {
  position: sticky;
  top: 0;
  z-index: -1;
}

.masthead {
  padding-block: var(--space-md) var(--space-lg);
  padding-inline: var(--space-lg);
}

.masthead__worker {
  grid-column: 1 / -1;
}

.masthead__contact {
  grid-column: 1 / -1;
}

.masthead__worker,
.masthead__contact {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.masthead__contact {
  display: none;
}

.masthead__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-xs);
}

.masthead__links {
  display: none;
  gap: var(--space-md);
}

.rule {
  height: var(--hairline);
  background-image: repeating-linear-gradient(
    to right,
    var(--color-ruler) 0 var(--dash-length),
    transparent var(--dash-length) calc(var(--dash-length) * 2)
  );
}

/* ---------- File tabs ----------
   Each tab carries the color of its own file card, like a folder tab. */
.tabs {
  padding-top: var(--space-lg);
}

.tabs__list {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  align-items: flex-end;
}

.tabs__tab {
  font-family: var(--font-mono);
  font-size: var(--type-title);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--color-fg-invert);
  padding: var(--tab-padding-y) calc(var(--tab-padding-x) + 16px) var(--tab-padding-y) var(--tab-padding-x);
  text-align: left;
  transition: transform 0.25s ease;
  /* Overlap the file card by 5px so no gap shows while the tab and file
     slide up during the hover animation. */
  margin-bottom: -5px;
  position: relative;
  /* Folder-tab shape: rounded top-left corner and a sharp slanted edge. */
  border-radius: var(--tab-radius) 0 0 0;
  clip-path: polygon(0 0, calc(100% - 26px) 0, 100% 100%, 0 100%);
}

/* The slant clips the default focus outline — use an underline instead. */
.tabs__tab:focus-visible {
  outline: none;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* The active tab stays attached on top of its file; the inactive tab is
   tucked behind the file card so its extended 5px sits underneath. */
.tabs__tab[aria-selected="true"] {
  z-index: 2;
}

.tabs__tab[aria-selected="false"] {
  z-index: 0;
}

@media (hover: hover) and (pointer: fine) {
  .tabs__tab[aria-selected="false"]:hover,
  .case-open .tabs__tab:hover {
    transform: translateY(-10px);
  }
}

.tabs__tab[data-file-tab="index"] {
  grid-column: 1 / 3;
  background: var(--color-fg-invert);
  color: var(--color-fg);
}

.tabs__tab[data-file-tab="worker"] {
  grid-column: 3 / 5;
  background: var(--color-accent);
  color: var(--color-fg-invert);
}

/* ---------- File cards ---------- */
main {
  position: relative;
}

.file {
  transition: transform 0.25s ease;
}

/* Active file sits in normal flow and defines the card height. */
.file.is-active {
  position: relative;
  z-index: 1;
}

/* Inactive file is layered behind the active one so it can peek up on hover. */
.file:not(.is-active) {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 0;
  max-height: 100%;
  overflow: hidden;
}

.file.is-peeking {
  transform: translateY(-10px);
}

/* -- Project index: white sheet with black text -- */
.file--index {
  background: var(--color-fg-invert);
  color: var(--color-fg);
  padding: var(--space-lg);
}

.index__bar {
  display: flex;
  justify-content: space-between;
  gap: var(--space-md);
  padding-bottom: var(--space-lg);
}

.index__divider {
  height: var(--hairline);
  background: var(--color-fg);
  margin-bottom: var(--space-xl);
}

.index__views {
  display: flex;
  gap: var(--space-md);
}

.index__view[aria-pressed="false"] {
  opacity: 0.7;
}

.projects {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

/* The whole project card opens its case study — show a click cursor. */
.project {
  cursor: pointer;
}

.project__header {
  padding-bottom: var(--space-md);
  row-gap: var(--space-xs);
}

.project__index {
  grid-column: 1 / 3;
  grid-row: 1;
  font-family: var(--font-mono);
  font-size: var(--type-index);
  letter-spacing: var(--tracking);
}

.project__title {
  grid-column: 1 / -1;
  grid-row: 2;
  align-self: end;
  font-family: var(--font-sans);
  font-size: var(--type-title);
  font-weight: 400;
  line-height: var(--leading-tight);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.project__title a {
  text-decoration: none;
}

.project__year {
  grid-column: 1 / -1;
  grid-row: 3;
  justify-self: start;
  align-self: start;
  font-family: var(--font-mono);
  font-size: var(--type-title);
  letter-spacing: var(--tracking);
}

.project__media {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border: var(--hairline) solid var(--color-border);
  background: var(--color-sheet);
}

.project__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* -- Worker file: light sheet with black text -- */
.file--worker {
  background: var(--color-sheet);
  color: var(--color-fg);
  padding: var(--space-lg);
  align-content: start;

}

/* Red banner stretched across the full card width, with a square portrait
   inside it sized to match the grid columns */
.worker__banner {
  grid-column: 1 / -1;
  margin-top: calc(-1 * var(--space-lg));
  margin-inline: calc(-1 * var(--space-lg));
  background: var(--color-accent);
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  gap: var(--grid-gutter);
  padding: 0;
}

.worker__portrait {
  grid-column: 1 / -1;
  aspect-ratio: 1 / 1;
  background: var(--color-accent);
  position: relative;
  overflow: hidden;
}

.worker__portrait img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transform: scaleX(-1);
}

.worker__column {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.worker__column--left {
  grid-column: 1 / -1;
}

.worker__column--right {
  grid-column: 1 / -1;
}

.field__label {
  font-family: var(--font-mono);
  font-size: var(--type-index);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  margin-bottom: var(--space-xs);
}

/* Worker file descriptions are set in the condensed sans */
.field__value {
  font-family: var(--font-mono);
  font-size: var(--type-title);
  line-height: var(--leading-base);
}

.field__rows {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-xs) var(--space-xl);
  font-family: var(--font-mono);
  font-size: var(--type-title);
}

.field__rows dt {
  font-variant-numeric: tabular-nums;
}

/* ---------- Crop marks (plus crosses, inset deep into the image) ---------- */
.crop {
  --crop-color: var(--color-fg-invert);
  position: absolute;
  width: var(--crop-size);
  height: var(--crop-size);
  pointer-events: none;
}

.crop::before,
.crop::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: var(--crop-color);
}

.crop::before {
  width: 100%;
  height: var(--hairline);
}

.crop::after {
  width: var(--hairline);
  height: 100%;
}

.crop--tl { top: var(--crop-inset); left: var(--crop-inset); }
.crop--tr { top: var(--crop-inset); right: var(--crop-inset); }
.crop--bl { bottom: var(--crop-inset); left: var(--crop-inset); }
.crop--br { bottom: var(--crop-inset); right: var(--crop-inset); }

.project__media--light .crop {
  --crop-color: var(--color-fg);
}

/* ---------- Footer ---------- */
.footer__mark {
  display: flex;
  justify-content: center;
  padding-block: var(--space-xxl);
}

.footer__mark svg {
  width: clamp(90px, 9.4vw, 180px);
  height: auto;
}

/* Sticky to the bottom, content scrolls over it */
.footer-sticky {
  position: sticky;
  bottom: 0;
  z-index: -1;
}

.footer__bar {
  padding-block: var(--space-lg);
  padding-inline: var(--space-lg);
}

.footer__motto {
  grid-column: 1 / -1;
}

.footer__links {
  grid-column: 1 / -1;
  display: flex;
  gap: var(--space-md);
  justify-content: flex-start;
}

/* ---------- Load-in ----------
   The site holds the masthead and foreground content hidden until the page
   is fully loaded (scripts, fonts, images), then the masthead decrypts and
   the foreground glides up as one group. */
html.is-booting .masthead,
html.is-booting .tabs,
html.is-booting main,
html.is-booting .footer-sticky {
  visibility: hidden;
}

/* Foreground slide-in is disabled for now.
html:not(.is-booting) .tabs,
html:not(.is-booting) main,
html:not(.is-booting) .footer-sticky {
  animation: rise-in 0.8s cubic-bezier(0.22, 1, 0.36, 1) backwards;
}
*/

@keyframes rise-in {
  from { transform: translateY(100px); }
  to   { transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  html:not(.is-booting) .tabs,
  html:not(.is-booting) main,
  html:not(.is-booting) .footer-sticky {
    animation: none;
  }
}

/* ---------- Case study sheet ----------
   Fixed to the viewport (aligned to the frame column) and slides in from
   the bottom until its top edge meets the bottom edge of the tabs. */
/* While a case study is open, the page behind (masthead, tabs and files)
   is frozen in place and the case study scrolls over it with the page. */
html.case-open {
  overscroll-behavior-y: none;
  /* Clicking outside the study closes it — show a click cursor there. */
  cursor: pointer;
}

html.case-open .case__sheet {
  cursor: auto;
}

.case-open .page {
  position: fixed;
  top: 0;
  left: max(0px, calc((100vw - var(--content-max-width)) / 2));
  right: max(0px, calc((100vw - var(--content-max-width)) / 2));
}

/* The study is the last content: take the sticky footer out of flow so the
   page can't scroll past the bottom of the sheet. */
html.case-open .footer-sticky {
  display: none;
}

.case {
  position: fixed;
  top: 0;
  left: max(0px, calc((100vw - var(--content-max-width)) / 2));
  right: max(0px, calc((100vw - var(--content-max-width)) / 2));
  z-index: 3;
  pointer-events: none;
  visibility: hidden;
  transform: translateY(100vh);
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.case.is-open {
  position: static;
  padding-top: var(--case-top, 0px);
  visibility: visible;
  transform: translateY(0);
}

.case__sheet {
  background: var(--color-sheet);
  color: var(--color-fg);
  pointer-events: auto;
}

/* The sheet is focused programmatically on open — no outline wanted. */
.case__sheet:focus,
.case__sheet:focus-visible {
  outline: none;
}

.case__body {
  padding: var(--space-lg);
}

/* -- Intro: title + context on the left, project info on the right -- */
.case__intro {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  gap: var(--grid-gutter);
  row-gap: var(--space-xl);
}

.case__lead {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.case__display-title {
  font-family: var(--font-mono);
  font-size: var(--type-title);
  font-weight: 400;
  line-height: var(--leading-tight);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.case__context {
  font-family: var(--font-mono);
  font-size: var(--type-title);
  line-height: var(--leading-base);
}

.case__info {
  grid-column: 1 / -1;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.case__divider {
  height: var(--hairline);
  margin-top: var(--space-xl);
  margin-bottom: var(--space-section);
  background: var(--color-border);
}

/* -- Figures -- */
.case__figures {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  gap: var(--space-xl);
}

.case__figure {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin: 0;
}

.case__figure-media {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border: var(--hairline) solid var(--color-border);
  background: var(--color-paper);
}

.case__figure-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.case__figure-label {
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: var(--type-index);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
}

/* ==========================================================================
   Responsive breakpoints
   --------------------------------------------------------------------------
   Structural changes only (column spans, stacking). Fluid sizing (type,
   spacing) is handled entirely by the clamp() tokens in tokens.css and
   needs no media queries. Breakpoint values must match --bp-tablet /
   --bp-desktop in tokens.css (media queries can't read custom properties).
   ========================================================================== */

/* ---- Tablet and up (>= 720px): switch to the 8-column grid ---- */
@media (min-width: 720px) {
  :root {
    --grid-columns: 8;
  }

  .masthead__worker {
    grid-column: 1 / 5;
  }

  .masthead__contact {
    grid-column: 5 / 9;
    display: flex;
  }

  .masthead__worker,
  .masthead__contact {
    gap: 0;
  }

  .masthead__links {
    display: flex;
  }

  .masthead__row {
    grid-template-columns: clamp(90px, 7.8vw, 150px) 1fr max-content;
    gap: var(--space-md);
  }

  .tabs__tab[data-file-tab="index"] {
    grid-column: 1 / 3;
  }

  .tabs__tab[data-file-tab="worker"] {
    grid-column: 3 / 5;
  }

  .project__title {
    grid-column: 1 / 7;
    grid-row: 2;
  }

  .project__media {
    aspect-ratio: 16 / 10;
  }

  .case__figure-media {
    aspect-ratio: 16 / 10;
  }

  .project__year {
    grid-column: 8 / 9;
    grid-row: 2;
    justify-self: end;
    align-self: end;
  }

  .case__lead {
    grid-column: 1 / 5;
  }

  .case__info {
    grid-column: 5 / 9;
  }

  .case__figure--pair {
    grid-column: span 4;
  }

  .worker__column--left {
    grid-column: 1 / 5;
  }

  .worker__column--right {
    grid-column: 5 / 9;
  }

  .worker__banner {
    padding: 0;
  }

  .worker__portrait {
    grid-column: span 2;
  }

  .footer__motto {
    grid-column: 1 / 5;
  }

  .footer__links {
    grid-column: 5 / 9;
    justify-content: flex-end;
  }
}

/* ---- Desktop and up (>= 1024px) ----
   Add wide-viewport-only overrides here as they come up. */
@media (min-width: 1024px) {
}
