/* TJ Ventures — site stylesheet
   Tokens and measurements follow the design handoff (README.md). */

@font-face {
  font-family: "Unbounded";
  src: url("/fonts/unbounded-latin-var.woff2") format("woff2");
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --paper: #ecebe6;
  --ink: #111110;
  --green: #2fcf7d;
  --purple: #9f42fe;
  --pad: 72px;
  --micro: 12px;
}
@supports (color: oklch(0.72 0.2 145)) {
  :root { --green: oklch(0.72 0.2 145); }
}

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Unbounded", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-weight: 300;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}
h1, h2, p { margin: 0; }
a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 4px;
}

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

.micro {
  font-size: var(--micro);
  font-weight: 300;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ---------- Hero ---------- */

.hero {
  --cube: min(300px, 20vw);
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 640px;
  overflow: hidden;
  background: var(--paper);
}
.hero__slab,
.hero__cut,
.hero__accent,
.hero__label,
.hero__mark,
.hero__cube,
.hero__tagline { position: absolute; }

.hero__slab { left: 0; top: 0; width: 39%; height: 100%; background: var(--ink); }
.hero__cut { left: 28%; top: 33%; width: min(320px, 22vw); height: min(320px, 22vw); background: var(--paper); }
.hero__accent { left: 39%; top: 33%; width: min(160px, 11vw); height: min(160px, 11vw); background: var(--green); }

.hero__label { left: 53%; top: 72px; }

.hero__mark {
  left: -30px;
  top: 100%;
  transform: rotate(-90deg);
  transform-origin: left top;
  font-size: 210px;
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--paper);
  white-space: nowrap;
  will-change: transform;
}

/* Holds the cut-out and accent squares. Full hero on desktop; on mobile it
   takes the slab's box so the squares can anchor to the slab's bottom edge. */
.hero__notch { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.hero__cube { right: 8%; top: 18%; z-index: 2; }

/* A second, paper-lined copy of the cube that is only visible over the black
   slab. It sits at the exact same coordinates as the ink-lined cube, so the
   wireframe flips colour where it crosses the slab edge. */
.hero__invert {
  position: absolute;
  inset: 0;
  clip-path: inset(0 61% 0 0);
  pointer-events: none;
  z-index: 2;
}
.hero__invert .cube { --line: var(--paper); }

.hero__tagline {
  left: 53%;
  bottom: 72px;
  max-width: 540px;
  font-size: clamp(28px, 3vw, 42px);
  font-weight: 900;
  line-height: 1.05;
  letter-spacing: -0.03em;
  text-wrap: pretty;
}

/* ---------- Cube ---------- */

.cube {
  position: relative;
  width: var(--cube);
  height: var(--cube);
  perspective: calc(var(--cube) * 5);
}
.cube__tilt,
.cube__scroll,
.cube__spin {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
}
.cube__tilt { transform: rotateX(-24deg); }
.cube__scroll { will-change: transform; }
.cube__spin { animation: cube-spin 40s linear infinite; will-change: transform; }

.cube__face {
  position: absolute;
  inset: 0;
  border: 1.5px solid var(--line, var(--ink));
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.cube__face--front  { transform: translateZ(calc(var(--cube) / 2)); background: var(--green); }
.cube__face--right  { transform: rotateY(90deg) translateZ(calc(var(--cube) / 2)); }
.cube__face--back   { transform: rotateY(180deg) translateZ(calc(var(--cube) / 2)); }
.cube__face--left   { transform: rotateY(-90deg) translateZ(calc(var(--cube) / 2)); }
.cube__face--top    { transform: rotateX(90deg) translateZ(calc(var(--cube) / 2)); }
.cube__face--bottom { transform: rotateX(-90deg) translateZ(calc(var(--cube) / 2)); }

@keyframes cube-spin {
  to { transform: rotateY(360deg); }
}
/* 0.15deg per scrolled pixel */
@keyframes cube-scroll {
  to { transform: rotateY(360deg); }
}
@keyframes mark-shift-desktop {
  from { transform: rotate(-90deg) translate3d(0, 0, 0); }
  to   { transform: rotate(-90deg) translate3d(220px, 0, 0); }
}
@keyframes mark-shift-mobile {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, 120px, 0); }
}

/* Scroll-linked motion runs on the compositor where scroll timelines exist.
   site.js provides a requestAnimationFrame fallback everywhere else. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .cube__scroll {
      animation: cube-scroll 1ms linear both;
      animation-timeline: scroll(root block);
      animation-range: 0px 2400px;
    }
    .hero__mark {
      animation: mark-shift-desktop 1ms linear both;
      animation-timeline: scroll(root block);
      animation-range: 0px 629px;
    }
  }
}

/* ---------- Portfolio rows ---------- */

.row {
  position: relative;
  display: block;
  padding: var(--pad);
  border-top: 2px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  transition: color 0.35s ease, opacity 0.7s ease, transform 0.7s cubic-bezier(.2, .7, .2, 1);
}
.row--soon { cursor: default; }
.row:focus-visible { outline-offset: -10px; }

.js .row { opacity: 0; transform: translateY(40px); }
.js .row.is-in { opacity: 1; transform: none; }

.row__fill {
  position: absolute;
  inset: 0;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.55s cubic-bezier(.7, 0, .2, 1);
  pointer-events: none;
}
.row--ec .row__fill { background: var(--purple); }
.row--voxel .row__fill { background: var(--green); }

.row__grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(120px, 200px) minmax(0, 1.45fr) minmax(0, 1fr);
  gap: 40px;
  align-items: end;
}
.row__name {
  min-width: 0;
  /* Sized so the longest word ("Creations") always fits the name column. */
  font-size: clamp(36px, calc((100vw - 424px) * 0.095), 96px);
  font-weight: 900;
  line-height: 0.95;
  letter-spacing: -0.04em;
  overflow-wrap: anywhere;
  text-wrap: pretty;
  transition: transform 0.5s cubic-bezier(.2, .7, .2, 1), color 0.35s ease;
}
.row--soon .row__name {
  color: transparent;
  -webkit-text-stroke: 2px var(--ink);
}
.row__body { display: flex; flex-direction: column; gap: 24px; }
.row__desc { font-size: 17px; line-height: 1.5; text-wrap: pretty; }
.row__cta {
  display: inline-block;
  align-self: flex-start;
  transition: transform 0.5s cubic-bezier(.2, .7, .2, 1);
}

.row--link:focus-visible .row__fill { transform: scaleX(1); }
.row--link:focus-visible .row__name { transform: translateX(28px); }
.row--link:focus-visible .row__cta { transform: translateX(10px); }
.row--ec:focus-visible { color: #fff; }

@media (hover: hover) and (pointer: fine) {
  .row--link:hover .row__fill { transform: scaleX(1); }
  .row:hover .row__name { transform: translateX(28px); }
  .row--link:hover .row__cta { transform: translateX(10px); }
  .row--ec:hover { color: #fff; }
  .row--soon:hover .row__name { color: var(--ink); }
}

/* ---------- Footer ---------- */

.footer {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 24px;
  padding: 40px var(--pad);
  border-top: 2px solid var(--ink);
}
.footer__links { display: flex; flex-wrap: wrap; gap: 8px 32px; }
.footer a, .legal-head a { padding: 6px 0; }
.footer a:hover, .legal-head a:hover, .legal a:hover { text-decoration: underline; }
.footer__mail { text-transform: none; }

/* ---------- Legal pages + 404 ---------- */

.page { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; }
.legal-head {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  padding: 40px var(--pad);
}
.legal {
  flex: 1;
  width: 100%;
  max-width: 1100px;
  padding: 80px var(--pad) 120px;
}
.legal h1 {
  margin-bottom: 48px;
  font-size: clamp(40px, 7vw, 96px);
  font-weight: 900;
  line-height: 0.95;
  letter-spacing: -0.04em;
  overflow-wrap: anywhere;
}
.legal__block {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 24px;
  padding: 28px 0;
  border-top: 1px solid var(--ink);
}
.legal__block h2 {
  padding-top: 4px;
  font-size: 11px;
  font-weight: 300;
  line-height: 1.5;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.legal__block p {
  font-size: 15px;
  line-height: 1.6;
  text-wrap: pretty;
  overflow-wrap: anywhere;
}
.legal__block p + p { margin-top: 1.6em; }
.legal__block--note p { grid-column: 2; }
.legal a { text-decoration: underline; text-underline-offset: 3px; }

.lost {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 40px;
  padding: 80px var(--pad) 120px;
}
.lost h1 {
  font-size: clamp(120px, 28vw, 420px);
  font-weight: 900;
  line-height: 0.85;
  letter-spacing: -0.06em;
}
.lost h1 span { color: var(--green); -webkit-text-stroke: 0; }
.lost__msg { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 40px; }
.lost__msg p { font-size: clamp(20px, 3vw, 42px); font-weight: 900; line-height: 1.05; letter-spacing: -0.03em; }
.lost__msg a { padding: 6px 0; }
.lost__msg a:hover { text-decoration: underline; }
.lost__square { width: 80px; height: 80px; background: var(--green); }

/* ---------- Mobile (< 820px) ---------- */

@media (max-width: 819.98px) {
  :root { --pad: 20px; --micro: 10px; }

  /* The slab edge sits at 60% of the hero, but never so high that the
     cut-out square (160px, flush with the edge) would bite into the wordmark on short viewports. */
  .hero {
    --cube: min(150px, 36vw);
    --mark-top: 64px;
    --mark-size: min(86px, 23vw);
    --edge: max(60%, calc(var(--mark-top) + var(--mark-size) * 2.7 + 164px));
  }
  @supports (height: 1svh) {
    .hero { --cube: min(150px, 36vw, 18svh); --mark-top: clamp(42px, calc(20svh - 90px), 64px); }
  }
  .hero__slab { width: 100%; height: var(--edge); }
  /* Both squares end exactly on the slab's bottom edge: one continuous line. */
  .hero__notch { inset: 0 0 auto 0; height: var(--edge); }
  .hero__cut { left: auto; right: 0; top: auto; bottom: 0; width: 160px; height: 160px; }
  .hero__accent { left: auto; right: 80px; top: auto; bottom: 0; width: 80px; height: 80px; }
  .hero__label { left: 20px; top: 20px; color: var(--paper); }
  .hero__mark {
    left: 14px;
    top: var(--mark-top);
    transform: none;
    font-size: var(--mark-size);
    line-height: 0.9;
    letter-spacing: -0.05em;
    white-space: normal;
  }
  .hero__mark span { display: block; }

  /* The cube straddles the slab edge: upper half on black (paper lines),
     lower half on paper (ink lines). */
  .hero__cube { left: 32px; right: auto; top: calc(var(--edge) - var(--cube) / 2); }
  .hero__invert { clip-path: inset(0 0 calc(100% - var(--edge)) 0); }

  .hero__tagline { left: 20px; right: 20px; bottom: 28px; max-width: none; font-size: min(26px, 6.6vw); }

  @supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: no-preference) {
      .hero__mark {
        animation-name: mark-shift-mobile;
        animation-range: 0px 480px;
      }
    }
  }

  .row { padding: 32px 20px 40px; }
  .row__grid { display: flex; flex-direction: column; align-items: stretch; gap: 28px; }
  .row__name { font-size: 52px; }
  .row--soon .row__name { -webkit-text-stroke-width: 1.5px; }
  .row__desc { font-size: 14px; }
  .row--link:focus-visible .row__name { transform: translateX(12px); }
  @media (hover: hover) and (pointer: fine) {
    .row:hover .row__name { transform: translateX(12px); }
  }

  .footer { flex-direction: column; align-items: flex-start; gap: 12px; padding: 28px 20px; }

  .legal-head { padding: 20px; }
  .legal { padding: 40px 20px 80px; }
  /* Keeps "Datenschutz-" on one line down to 360px. */
  .legal h1 { font-size: min(40px, 9.4vw); }
  .legal__block { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .legal__block--note p { grid-column: auto; }
  .lost { padding: 40px 20px 80px; }
}

/* ---------- Reduced motion: static cube, no parallax, no reveals ---------- */

@media (prefers-reduced-motion: reduce) {
  .cube__spin { animation: none; transform: rotateY(-32deg); }
  .hero__mark { will-change: auto; }
  .js .row { opacity: 1; transform: none; }
  .row, .row__fill, .row__name, .row__cta { transition: none; }
}
