/* Trivertex Studio — home page */

@font-face { font-family: "Clash Grotesk"; src: url("assets/fonts/clashgrotesk-regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Clash Grotesk"; src: url("assets/fonts/clashgrotesk-medium.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Clash Grotesk"; src: url("assets/fonts/clashgrotesk-semibold.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Clash Grotesk"; src: url("assets/fonts/clashgrotesk-bold.woff2") format("woff2"); font-weight: 700; font-display: swap; }

:root {
  --page: #FFFFFF;
  --page-top: #F3F3F3;
  --ink: #020202;
  --ink-soft: #404040; /* the work row's secondary items, as in the Work export */
  --nav-dark: #0D0D0D;
  --nav-light: #535353;
  --nav-text: #FFFFFF;
  --accent: #F24848;

  /* One design unit = one pixel of the reference exports, which are
     4080px wide. The nav is measured in these units. */
  --u: calc(100vw / 4080);

  /* The strip is anchored to the viewport height instead, so it always
     runs off the bottom edge. In the 4080 × 2294 export the band starts at
     640 and is 1687 tall. */
  --strip-top: 27.9vh;
  --strip-height: 73.5vh;
  --strip-gap: 0px; /* images 1 and 2 touch in home.png */

  --hover-time: 400ms;
  --hover-curve: cubic-bezier(0.16, 0.84, 0.34, 1);
}

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

html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
  background: linear-gradient(to bottom, var(--page-top) 0, var(--page) calc(500 * var(--u))) no-repeat var(--page);
  color: var(--ink);
  font-family: "Clash Grotesk", system-ui, sans-serif;
  font-weight: 400;
}

/* Only the home page locks the viewport. */
body.home {
  height: 100vh;
  overflow: hidden;
}

ul { margin: 0; padding: 0; list-style: none; }
img { display: block; }
picture { display: contents; } /* the <img> inside lays out as if the wrapper were not there */
picture source { display: none; }


/* ---- Nav bar ---- */

.nav {
  position: fixed;
  left: calc(128 * var(--u) + env(safe-area-inset-left, 0px));
  top: calc(128 * var(--u) + env(safe-area-inset-top, 0px));
  height: calc(74 * var(--u));
  z-index: 10;
}

/* The square is a window the mark slides down into. */
.nav__logo {
  position: absolute;
  left: 0;
  top: 0;
  width: calc(74 * var(--u));
  height: calc(74 * var(--u));
  overflow: hidden;
}

.nav__logo img {
  width: 100%;
  height: 100%;
  transition: transform 200ms ease-in;
}

.nav__bar {
  position: relative;
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  width: calc(560 * var(--u));
  height: 100%;
  padding: 0 calc(28 * var(--u));
  background: linear-gradient(to right, var(--nav-light), var(--nav-dark));
  transition: transform 300ms ease-in-out 200ms;
}

.nav__bar li { display: flex; }

.nav__bar a {
  display: flex;
  align-items: center;
  color: var(--nav-text);
  font-size: calc(42 * var(--u));
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  text-decoration: none;
}

.nav__bar a[aria-current] { color: var(--accent); }

.nav__bar a:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* Home: the bar sits 82 units to the right, clear of the logo square. */
.nav--home .nav__bar { transform: translate3d(calc(82 * var(--u)), 0, 0); }

/* Arriving on home: the bar starts where every other page has it, slides
   right (300ms), then the mark drops in (200ms). */
.nav--home .nav__bar { animation: nav-bar-in 300ms ease-in-out backwards; }
.nav--home .nav__logo img { animation: nav-logo-in 200ms ease-out 300ms backwards; }

@keyframes nav-logo-in { from { transform: translate3d(0, -100%, 0); } }
@keyframes nav-bar-in { from { transform: translate3d(0, 0, 0); } }

/* Leaving home is the mirror: mark up (200ms), then bar back to the left
   (300ms), which is where the next page draws it. */
.nav--home.is-leaving .nav__logo img { transform: translate3d(0, -100%, 0); }
.nav--home.is-leaving .nav__bar { transform: translate3d(0, 0, 0); }


/* ---- The strip ---- */

/* Not clipped: a hovered image is meant to grow past the band. */
.strip {
  touch-action: pan-y; /* horizontal drags are ours; vertical ones stay the browser's */
  position: fixed;
  left: 0;
  right: 0;
  top: var(--strip-top);
  height: var(--strip-height);
}

.strip__track {
  display: flex;
  gap: var(--strip-gap);
  width: max-content;
  height: 100%;
  will-change: transform;
}

.strip__item {
  position: relative;
  display: block;
  flex: none;
  height: 100%;
  z-index: 1;
  transform-origin: center;
  will-change: transform;
  /* z-index drops only after the scale has settled back */
  transition: transform var(--hover-time) var(--hover-curve), z-index 0s var(--hover-time);
}

.strip__item img {
  width: auto;
  height: 100%;
  user-select: none;
}

.strip__light {
  position: absolute;
  inset: 0;
  background: var(--nav-text);
  mix-blend-mode: soft-light;
  opacity: 0;
  transition: opacity var(--hover-time) var(--hover-curve);
}

/* Hover effects only where the device can hover; touch gets none. */
@media (hover: hover) {
  .strip__item.is-near {
    transform: scale(1.06);
    z-index: 2;
    transition: transform var(--hover-time) var(--hover-curve), z-index 0s;
  }

  .strip__item.is-hover {
    transform: scale(1.15);
    z-index: 3;
    transition: transform var(--hover-time) var(--hover-curve), z-index 0s;
  }

  .strip__item.is-hover .strip__light { opacity: 0.5; }

  .strip__tag.is-on { opacity: 1; }

  .work__entry a:hover { transform: scale(var(--cover-scale)); }
  .work__entry a:hover .work__light { opacity: 0.5; }
}

/* Project name that follows the pointer over the strip. Styled as a piece
   of the nav bar; script.js moves the outer element, the inner one holds
   the offset from the pointer. */
.strip__tag {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 5;
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms ease-out;
  will-change: transform;
}

.strip__tag span {
  display: block;
  padding: 0 calc(28 * var(--u));
  background: linear-gradient(to right, var(--nav-light), var(--nav-dark));
  color: var(--nav-text);
  font-size: calc(42 * var(--u));
  line-height: calc(74 * var(--u));
  letter-spacing: -0.01em;
  white-space: nowrap;
  transform: translate(calc(32 * var(--u)), calc(32 * var(--u)));
}

/* Near the right edge the tag sits to the left of the pointer instead. */
.strip__tag.is-left span { transform: translate(calc(-100% - 32 * var(--u)), calc(32 * var(--u))); }

.strip__item:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  z-index: 4;
}


/* ---- Project page ---- */

.project {
  /* Not in any reference export: the grid gap, the space between the text
     and the grid, and the space under the grid. */
  --grid-gap: calc(16 * var(--u));
  --grid-top: calc(128 * var(--u));
  --grid-bottom: calc(128 * var(--u));

  padding: calc(481 * var(--u)) calc(128 * var(--u)) var(--grid-bottom);
}

.project__text {
  /* Starts 1208 from the page's left edge, like the export. */
  width: calc(1664 * var(--u));
  margin-left: calc(1080 * var(--u));
}

.project__title {
  margin: 0 0 calc(54 * var(--u));
  font-size: calc(136 * var(--u));
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.project__kind {
  margin: 0;
  font-size: calc(84 * var(--u));
  font-weight: 500;
  line-height: calc(100 * var(--u));
  letter-spacing: -0.01em;
}

.project__body {
  margin-top: calc(110 * var(--u));
  font-size: calc(69 * var(--u));
  font-weight: 400;
  line-height: calc(83.5 * var(--u));
}

.project__body p { margin: 0; }
.project__body p + p { margin-top: calc(83.5 * var(--u)); }

.grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--grid-gap);
  margin-top: var(--grid-top);
}

.grid img {
  width: 100%;
  height: auto;
}

.grid .half { grid-column: span 3; }
.grid .third { grid-column: span 2; }
.grid .full { grid-column: span 6; }


/* ---- Work index ---- */

.work {
  /* Not in the export, which shows a single entry. */
  --entry-gap: calc(128 * var(--u));
  --cover-scale: 1.04;

  padding: calc(752 * var(--u)) 0 calc(45 * var(--u));
  overflow-x: clip; /* the scaled cover runs past both edges */
}

.work__entry + .work__entry { margin-top: var(--entry-gap); }

/* Same hover as the home strip, with a smaller scale: the cover is the full
   page width, so 1.15 would bury the row above it. */
.work__entry a {
  position: relative;
  display: block;
  transform-origin: center;
  transition: transform var(--hover-time) var(--hover-curve);
}

.work__light {
  position: absolute;
  inset: 0;
  background: var(--nav-text);
  mix-blend-mode: soft-light;
  opacity: 0;
  transition: opacity var(--hover-time) var(--hover-curve);
}

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

.work__meta {
  display: flex;
  align-items: baseline;
  gap: calc(211 * var(--u));
  padding: 0 calc(128 * var(--u));
  margin: 0 0 calc(47 * var(--u));
  color: var(--ink-soft);
  font-size: calc(49 * var(--u));
  font-weight: 500;
  line-height: calc(70 * var(--u));
  white-space: nowrap;
}

.work__code {
  color: var(--ink);
  font-size: calc(70 * var(--u));
  letter-spacing: -0.02em;
}

.work__entry img {
  width: 100%;
  height: auto;
}


/* ---- Info ---- */

.info { padding: calc(511 * var(--u)) calc(128 * var(--u)) calc(686 * var(--u)); }

.info__column {
  width: calc(1664 * var(--u));
  margin-left: calc(1080 * var(--u));
}

.info__mark {
  width: calc(237 * var(--u));
  height: auto;
  margin-bottom: calc(137 * var(--u));
}

.info__body {
  font-size: calc(75 * var(--u));
  line-height: calc(90 * var(--u));
}

.info__body p { margin: 0; }
.info__body p + p { margin-top: calc(90 * var(--u)); }
.info__body strong { font-weight: 500; }

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

.info a.textlink { text-decoration: underline; }

.info a:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

.label {
  margin: 0;
  font-size: calc(37 * var(--u));
  font-weight: 700;
  line-height: 1;
  text-transform: uppercase;
}

.info__contact { margin-top: calc(125 * var(--u)); }
.info__links { margin-top: calc(99 * var(--u)); }
.info__links + .info__links { margin-top: calc(105 * var(--u)); } /* PHONE sits as far below INSTAGRAM as LINKS does below the address */

.info__email {
  margin: calc(33 * var(--u)) 0 0;
  font-size: calc(75 * var(--u));
  line-height: calc(90 * var(--u));
}

.info__address {
  margin: calc(1 * var(--u)) 0 0;
  font-size: calc(60 * var(--u));
  line-height: calc(84 * var(--u));
}

.info__links ul { margin-top: calc(36.5 * var(--u)); }

.info__links li {
  font-size: calc(37 * var(--u));
  font-weight: 500;
  line-height: calc(56 * var(--u));
  text-transform: uppercase;
}


/* ---- Reduced motion ---- */

@media (prefers-reduced-motion: reduce) {
  .nav--home .nav__logo img,
  .nav--home .nav__bar { animation: none; transition: none; }
  .strip__item,
  .strip__light,
  .work__entry a,
  .work__light { transition: none; }
  .work__entry a:hover { transform: none; }
  .strip__item.is-near,
  .strip__item.is-hover { transform: none; }
}

/* ---- Mobile: one breakpoint ---- */

@media (max-width: 768px) {
  :root {
    /* --mu is 1px on a 390px-wide phone and grows a little on wider ones.
       Mobile sizes are written in it. --u is re-based so the nav, which is
       still measured in --u, comes out at a readable size (42u = 14px). */
    --mu: clamp(1px, calc(100vw / 390), 1.4px);
    --u: calc(var(--mu) / 3);
    --side: calc(24 * var(--mu));

    /* The strip no longer runs off the bottom: 35% of the height, centred. */
    --strip-top: 32.5vh;
    --strip-height: 35vh;
  }

  @supports (height: 100dvh) {
    :root {
      --strip-top: 32.5dvh;
      --strip-height: 35dvh;
    }
    body.home { height: 100dvh; }
  }

  body.home { overscroll-behavior: none; }

  .nav {
    left: calc(var(--side) + env(safe-area-inset-left, 0px));
    top: calc(20 * var(--mu) + env(safe-area-inset-top, 0px));
  }

  /* 44px tap targets without changing how the bar looks: an invisible area
     centred on each item, as wide as the item plus the space around it. */
  .nav__bar a { position: relative; }

  .nav__bar a::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(44px, calc(100% + 47 * var(--u)));
    height: max(44px, 100%);
    transform: translate(-50%, -50%);
  }

  /* Project page */
  .project {
    padding: calc(96 * var(--mu)) calc(var(--side) + env(safe-area-inset-right, 0px)) calc(48 * var(--mu)) calc(var(--side) + env(safe-area-inset-left, 0px));
  }

  .project__text {
    width: auto;
    margin-left: 0;
  }

  .project__title {
    margin-bottom: calc(10 * var(--mu));
    font-size: calc(26 * var(--mu));
    line-height: 1.1;
    white-space: normal;
  }

  .project__kind {
    font-size: calc(17 * var(--mu));
    line-height: 1.25;
  }

  .project__body {
    margin-top: calc(28 * var(--mu));
    font-size: calc(16 * var(--mu));
    line-height: 1.35;
  }

  .project__body p + p { margin-top: 1.35em; }

  .grid {
    grid-template-columns: 1fr;
    margin-top: calc(40 * var(--mu));
  }

  .grid .half,
  .grid .third,
  .grid .full { grid-column: auto; }

  /* Work index */
  .work { padding: calc(96 * var(--mu)) 0 calc(24 * var(--mu)); }

  .work__meta {
    flex-wrap: wrap;
    gap: calc(2 * var(--mu)) calc(16 * var(--mu));
    padding: 0 var(--side);
    margin-bottom: calc(14 * var(--mu));
    font-size: calc(14 * var(--mu));
    line-height: 1.4;
  }

  .work__code {
    flex-basis: 100%;
    font-size: calc(20 * var(--mu));
  }

  /* Info */
  .info {
    padding: calc(96 * var(--mu)) calc(var(--side) + env(safe-area-inset-right, 0px)) calc(64 * var(--mu)) calc(var(--side) + env(safe-area-inset-left, 0px));
  }

  .info__column {
    width: auto;
    margin-left: 0;
  }

  .info__mark {
    width: calc(64 * var(--mu));
    margin-bottom: calc(36 * var(--mu));
  }

  .info__body {
    font-size: calc(18 * var(--mu));
    line-height: 1.3;
  }

  .info__body p + p { margin-top: 1.3em; }

  .label { font-size: calc(12 * var(--mu)); }

  .info__contact { margin-top: calc(44 * var(--mu)); }
  .info__links,
  .info__links + .info__links { margin-top: calc(32 * var(--mu)); }

  /* Email and links get a 44px-tall line so they are easy to tap. */
  .info__email {
    margin-top: calc(2 * var(--mu));
    font-size: calc(18 * var(--mu));
    line-height: 44px;
  }

  .info__address {
    margin-top: 0;
    font-size: calc(15 * var(--mu));
    line-height: 1.4;
  }

  .info__links ul { margin-top: calc(4 * var(--mu)); }

  .info__links li {
    font-size: calc(13 * var(--mu));
    line-height: 44px;
  }

  .info__links li a { display: inline-block; }
}
