/* ==========================================================================
   Maximilian Kinsella – Portfolio
   Built from the Figma file "Portfolio Page V2" (frames are 1728 px wide).

   Layout system
   -------------
   Every desktop measurement is a Figma pixel multiplied by --u, where
   1 --u = 1 Figma pixel at the current viewport width (1728 px viewport → 1px).
   That keeps the composition identical on every desktop width. Below 900 px a
   separate mobile layout takes over (see the bottom of this file).

   Absolutely placed elements use the .place helper with inline custom
   properties copied straight from Figma:  style="--x:705; --y:197; --w:348; --h:258"
   --y is the frame y coordinate; the stage origin (--oy, default: the 102px
   header) is subtracted automatically.
   ========================================================================== */

@font-face {
  font-family: "Roboto";
  src: url("../assets/fonts/roboto-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Roboto";
  src: url("../assets/fonts/roboto-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Roboto";
  src: url("../assets/fonts/roboto-italic-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Roboto";
  src: url("../assets/fonts/roboto-italic-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- tokens ---------- */

:root {
  --ink: #000;
  --paper: #fff;
  --muted: #555;
  --design-w: 1728;
  --header-h: 102;
  /* 1 Figma px. body is a size container on desktop, so 100cqw excludes the scrollbar. */
  --u: calc(min(100vw, 2400px) / var(--design-w));
  --fs: max(11px, calc(12 * var(--u)));
  --ease: cubic-bezier(0.42, 0, 0.58, 1); /* Figma "ease in and out" */
  --spring: cubic-bezier(0.3, 1.5, 0.5, 1);
}

@supports (width: 1cqw) {
  :root { --u: calc(min(100cqw, 2400px) / var(--design-w)); }
  body { container-type: inline-size; }
}

/* ---------- base ---------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Roboto", "Helvetica Neue", Arial, sans-serif;
  font-size: var(--fs);
  font-weight: 400;
  line-height: normal;
  overflow-x: clip;
}

img, video, svg { display: block; }
img { -webkit-user-drag: none; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
p, h1, h2, h3, dl, dd { margin: 0; font: inherit; }
button { font: inherit; color: inherit; }

:focus-visible { outline: 1px solid var(--ink); outline-offset: 3px; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* Page frame: centred once the viewport is wider than the 2400px cap */
.page {
  position: relative;
  display: flow-root; /* keep the first child's margin inside, so .place offsets stay exact */
  width: calc(var(--design-w) * var(--u));
  margin: 0 auto;
}

/* ---------- placement helpers ---------- */

.place {
  position: absolute;
  left: calc(var(--x) * var(--u));
  top: calc((var(--y) - var(--oy, var(--header-h))) * var(--u));
  width: calc(var(--w) * var(--u));
  height: calc(var(--h) * var(--u));
}

/* Image crops exported from Figma: the <img> is sized/offset in % of its box */
.crop { overflow: hidden; }
.crop > img,
.crop > video {
  position: absolute;
  left: var(--il, 0%);
  top: var(--it, 0%);
  width: var(--iw, 100%);
  height: var(--ih, 100%);
  max-width: none;
}
.cover > img,
.cover > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.flip-x > img { transform: scaleX(-1); }
.fill > img { width: 100%; height: 100%; }

/* ==========================================================================
   Header
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  width: calc(var(--design-w) * var(--u));
  height: calc(var(--header-h) * var(--u));
  margin: 0 auto;
  background: var(--paper);
}

.site-header .hx {
  position: absolute;
  top: calc(39 * var(--u));
  left: calc(var(--x) * var(--u));
  white-space: nowrap;
}

/* name + signature: the gap puts the logo at x=278 at 1728px, and keeps the
   two apart on narrower screens where the text stops shrinking at 11px */
.identity {
  display: flex;
  align-items: flex-start;
  gap: max(16px, calc(51.7 * var(--u)));
}
.brand { display: block; }
.brand span { display: block; }

/* The handwritten K. On sub pages (desktop) it morphs into a hand-drawn back arrow
   on hover – the arrow is made from the K's own outline (see js/main.js). */
.logo {
  position: relative;
  display: block;
  flex: none;
  width: calc(84 * var(--u));
  height: calc(30 * var(--u));
}
.logo-svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: var(--ink);
}

.burger { display: none; }
.header-lever { display: none; }
.site-menu { display: none; }

.nav-link { display: inline-block; }
.nav-link:hover,
.nav-link:focus-visible,
.nav-link[aria-current="page"] {
  font-weight: 700;
  text-decoration: underline;
  text-underline-position: from-font;
}
/* sub pages (and About) show the section bold but without underline, as in Figma */
.nav-link.is-section { font-weight: 700; }
.nav-link.is-section[aria-current="page"]:not(:hover) { text-decoration: none; }

/* CATEGORIES / CLIENTS: CLIENTS lands at x=1261 at 1728px */
.view-toggle {
  display: flex;
  gap: max(10px, calc(15.8 * var(--u)));
}
.toggle-link {
  position: relative;
  display: inline-flex;
  flex-direction: column;
}
/* reserve the bold width so hovering doesn't nudge the neighbour */
.toggle-link::after {
  content: attr(data-label);
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 700;
}
.toggle-link[aria-current="page"],
.toggle-link:hover { font-weight: 700; }

/* the little arrow pointing at the active toggle (Figma: 26px arrow rotated -45°),
   14px below and ~23px left of the label it points at. JS slides it to the hovered label. */
.toggle-arrow {
  position: absolute;
  top: calc(14 * var(--u));
  left: calc(var(--dx) * var(--u));
  width: calc(18.385 * var(--u));
  height: calc(18.385 * var(--u));
  pointer-events: none;
  transform: translateX(var(--shift, 0px));
  transition: transform 0.3s var(--ease);
}
.toggle-arrow img {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(26.5 * var(--u));
  height: calc(7.364 * var(--u));
  transform: translate(-50%, -50%) rotate(-45deg);
}

.clock {
  position: absolute;
  top: calc(38 * var(--u));
  /* x=1515 as in Figma, but never closer than 62px-units to the right edge */
  left: min(calc(1515 * var(--u)), calc(100% - 62 * var(--u) - 140px));
  display: grid;
  grid-template-columns: auto auto;
  column-gap: calc(6 * var(--u));
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- CLIENTS / CATEGORIES switch (mobile header + menu) ---------- */

.lever {
  display: flex;
  align-items: center;
  gap: 12px;
}
.lever[data-state="clients"] .lever-label:first-child,
.lever[data-state="categories"] .lever-label:last-child { font-weight: 700; }
.lever-switch {
  position: relative;
  flex: none;
  width: 44px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 13px;
  background: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.lever-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--paper);
  box-shadow: 0 2px 5px rgb(0 0 0 / 0.25);
  transition: transform 0.28s cubic-bezier(0.3, 0.7, 0.4, 1);
}
.lever-switch:active .lever-knob { width: 26px; } /* the little stretch of an iOS switch */
.lever[data-state="categories"] .lever-knob { transform: translateX(18px); }
.lever[data-state="categories"] .lever-switch:active .lever-knob { transform: translateX(14px); }

/* ==========================================================================
   Shared: project / client table
   ========================================================================== */

.table {
  position: relative;
  margin-left: calc(65 * var(--u));
  margin-right: calc(64 * var(--u));
}

.table-head,
.row {
  display: grid;
  grid-template-columns: calc(392 * var(--u)) calc(476 * var(--u)) 1fr auto;
  align-items: start;
}

.table-head {
  height: calc(16 * var(--u));
  font-weight: 700;
}
.table-head .col-year { padding-top: calc(8 * var(--u)); } /* YEAR sits 8px lower in Figma */

.rows { margin-top: calc(63 * var(--u)); }

.row {
  position: relative;
  min-height: calc(16 * var(--u));
  margin-bottom: calc(5 * var(--u));
}
.row > span { padding-right: calc(12 * var(--u)); }
/* years end at x=1660 in Figma, 4px before the rule's right end */
.row > .col-year,
.table-head > .col-year { padding-right: calc(4 * var(--u)); text-align: right; }

/* active row: bold + 1px rule 3px under the text, following rows move down 4px */
.row::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(-4 * var(--u));
  height: 1px;
  background: var(--ink);
  opacity: 0;
}
.row.is-active,
.row.is-current { font-weight: 700; margin-bottom: calc(9 * var(--u)); }
.row.is-active::after,
.row.is-current::after { opacity: 1; }

a.row { cursor: pointer; }
/* category tables: linked rows react like the home list */
.category-detail a.row:hover { font-weight: 700; margin-bottom: calc(9 * var(--u)); }
.category-detail a.row:hover::after { opacity: 1; }

/* ==========================================================================
   Shared: object ticker – an endless loop (one set = 1737px, 10s, linear).
   Every object links to a category (ID card → About, folder → Contact).
   Hover pauses the loop and lifts the object.
   ========================================================================== */

.ticker {
  position: relative;
  display: block;
  width: calc(1600 * var(--u));
  height: calc(229 * var(--u));
  margin-left: calc(64 * var(--u));
  overflow: hidden;
}
.ticker-track {
  position: absolute;
  inset: 0;
  animation: ticker 10s linear infinite;
}
.ticker:hover .ticker-track,
.ticker:focus-within .ticker-track { animation-play-state: paused; }
.ticker .place { top: calc(var(--y) * var(--u)); }

.ticker-item {
  display: block;
  transition: transform 0.3s var(--ease);
  transform-origin: 50% 55%;
}
.ticker-img { position: absolute; inset: 0; }
.ticker-item:hover,
.ticker-item:focus-visible { z-index: 2; transform: scale(1.14); }

@keyframes ticker {
  to { transform: translateX(calc(-1737 * var(--u))); }
}

/* ==========================================================================
   Rotatable 3D objects (sprite sheets made from the rotating GIFs)
   ========================================================================== */

[data-spin] { background-repeat: no-repeat; }
[data-spin].is-sprite {
  touch-action: pan-y;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}
[data-spin].is-dragging { cursor: grabbing; }
[data-spin].is-sprite > img { visibility: hidden; }
.object-3d > img { width: 100%; height: 100%; object-fit: contain; }

/* ==========================================================================
   Home / clients
   ========================================================================== */

.home-hero {
  position: relative;
  width: calc(1602 * var(--u));
  height: calc(356 * var(--u));
  margin: calc(24 * var(--u)) 0 0 calc(62 * var(--u));
  overflow: hidden;
  background: #d9d4c8;
}
.hero-layer { position: absolute; inset: 0; overflow: hidden; visibility: hidden; }
.hero-layer.is-visible { visibility: visible; }

.object-stage { display: none; }

.home-table {
  height: calc(347 * var(--u)); /* fixed so the ticker never moves when rows expand */
  margin-top: calc(37 * var(--u));
}

.home-ticker { margin-bottom: calc(22 * var(--u)); }

.preview {
  z-index: 5;
  pointer-events: none;
  visibility: hidden;
}
.preview.is-visible { visibility: visible; }
.preview img { width: 100%; height: 100%; object-fit: cover; }

/* ==========================================================================
   Work / categories
   ========================================================================== */

.categories { position: relative; height: calc((1117 - var(--header-h)) * var(--u)); }

/* .cat is an unpositioned group on desktop: image, label and pointer line are
   all placed against the .categories stage; hovering the image opens the group. */
.cat-img {
  display: block;
  z-index: 1;
  transition: transform 0.125s var(--ease);
}
.cat-img > img { transition: opacity 0.15s; }
.cat.is-open .cat-img { z-index: 3; transform: scale(var(--s)); }

.cat-label,
.cat-line {
  position: absolute;
  z-index: 6; /* text and line always sit above the (scaled) images */
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.125s var(--ease);
}
.cat.is-open .cat-label,
.cat.is-open .cat-line { opacity: 1; }

/* labels are positioned relative to the .categories stage, not the image */
.cat-label {
  top: calc((var(--ly) - var(--header-h)) * var(--u));
  white-space: nowrap;
}
.cat-label--left { right: calc((var(--design-w) - var(--lx)) * var(--u)); text-align: right; }
.cat-label--right { left: calc(var(--lx) * var(--u)); }
.cat-label strong { display: block; font-weight: 700; line-height: calc(20 * var(--u)); }
.cat-label ul { margin-top: calc(19 * var(--u)); }
.cat-label li { height: calc(16 * var(--u)); margin-bottom: calc(5.5 * var(--u)); }
.cat-open,
.work-hint { display: none; }

.cat-line svg { width: 100%; height: 100%; overflow: visible; }
.cat-line line { stroke: var(--ink); stroke-width: 1; vector-effect: non-scaling-stroke; }

/* ---- hover effects ---- */

/* phone: a small slideshow of digital projects on the (cracked) screen */
.fx-screen {
  position: absolute;
  inset: 0;
  clip-path: polygon(26.7% 20.7%, 73.7% 20.1%, 74.3% 78%, 27.1% 78.5%);
  opacity: 0;
  transition: opacity 0.2s var(--ease);
  pointer-events: none;
}
.fx-screen img {
  position: absolute;
  left: 26.5%;
  top: 20%;
  width: 48%;
  height: 58.6%;
  object-fit: cover;
  opacity: 0;
}
.cat.is-open .fx-screen { opacity: 1; }
.cat.is-open .fx-screen img { animation: fx-slide 4.8s steps(1) var(--d, 0s) infinite; }
@keyframes fx-slide {
  0% { opacity: 1; }
  25%, 100% { opacity: 0; }
}

/* knob: turns up (to 11) and back */
.cat-img--music > img { transform-origin: 52% 48%; }
.cat.is-open .cat-img--music > img { animation: fx-knob 2.4s var(--ease) infinite alternate; }
@keyframes fx-knob {
  from { transform: rotate(0deg); }
  to { transform: rotate(150deg); }
}

/* mouse & keyboard: hovering (or focusing) an object opens it */
@media (hover: hover) and (min-width: 900px) {
  .cat:hover .cat-img,
  .cat:focus-within .cat-img { z-index: 3; transform: scale(var(--s)); }
  .cat:hover .cat-label,
  .cat:hover .cat-line,
  .cat:focus-within .cat-label,
  .cat:focus-within .cat-line { opacity: 1; }
  .cat:hover .fx-screen { opacity: 1; }
  .cat:hover .fx-screen img { animation: fx-slide 4.8s steps(1) var(--d, 0s) infinite; }
  .cat:hover .cat-img--music > img { animation: fx-knob 2.4s var(--ease) infinite alternate; }
}

/* ==========================================================================
   Category pages
   ========================================================================== */

.category-detail { padding-bottom: calc(361 * var(--u)); }
.category-hero {
  position: relative;
  height: calc(var(--hh, 757) * var(--u));
  margin-top: calc(77 * var(--u));
}
.category-image {
  position: absolute;
  top: 0;
  left: calc(var(--cx) * var(--u));
  width: calc(var(--w) * var(--u));
  height: calc(var(--h) * var(--u));
}
.category-label {
  position: absolute;
  top: calc(20 * var(--u));
  right: calc((var(--design-w) - var(--lx)) * var(--u));
  text-align: right;
  white-space: nowrap;
}
.category-label strong { display: block; font-weight: 700; }
.category-label ul { margin-top: calc(19 * var(--u)); }
.category-label li { margin-bottom: calc(5.5 * var(--u)); }
.category-detail .table { margin-top: calc(125 * var(--u)); }

/* ==========================================================================
   Turnable 3D cards (contact envelope, about ID card)
   ========================================================================== */

.card3d {
  z-index: 2;
  perspective: calc(2400 * var(--u));
  touch-action: pan-y;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.card3d.is-dragging { cursor: grabbing; }
.card3d-inner {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
}
.card3d-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.card3d-face > img { width: 100%; height: 100%; pointer-events: none; }
.card3d-back { transform: rotateY(180deg); }
.card3d-link { position: absolute; display: block; cursor: pointer; }
/* links only react on the side that is facing you */
.card3d.shows-back .card3d-front .card3d-link,
.card3d:not(.shows-back) .card3d-back .card3d-link { pointer-events: none; }
.card3d-hint {
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
  color: var(--muted);
}

/* ==========================================================================
   Contact
   ========================================================================== */

.contact-stage { position: relative; height: calc((866 - var(--header-h)) * var(--u)); }
.envelope-shadow { z-index: 0; pointer-events: none; }
.envelope-shadow img { width: 100%; height: 100%; }
.contact-ticker { margin-bottom: calc(22 * var(--u)); }

/* ==========================================================================
   About
   ========================================================================== */

.about-stage { position: relative; height: calc((3545 - var(--header-h)) * var(--u)); }

.about-title,
.about-year,
.about-subtitle { font-style: italic; white-space: nowrap; }
.about-title,
.about-subtitle { font-size: calc(26 * var(--u)); }
.about-year { font-size: calc(21 * var(--u)); }

.about-rule { height: 0; border-top: 1px solid var(--ink); }

.about-text {
  font-size: calc(25 * var(--u));
  font-weight: 300;
  text-align: right;
}
.about-text p + p { margin-top: calc(29.3 * var(--u)); }

.skills li {
  position: absolute;
  left: calc(103 * var(--u));
  top: calc((var(--y) - var(--header-h)) * var(--u));
  font-size: calc(26 * var(--u));
  font-weight: 300;
  white-space: nowrap;
}

.skill-scale-labels span {
  position: absolute;
  top: calc((2798 - var(--header-h)) * var(--u));
  font-size: calc(15 * var(--u));
  white-space: nowrap;
}

.about-objects a { transition: transform 0.3s var(--ease); }
.about-objects a:hover,
.about-objects a:focus-visible { transform: scale(1.08); }

/* ==========================================================================
   Project pages
   ========================================================================== */

/* Freely composed parts of a page: every block is placed at its design position.
   --oy: frame y where this stage starts (default: under the header),
   --frame-h: frame y where it ends. Images may bleed past the edges. */
.project-stage {
  position: relative;
  overflow: hidden;
  height: calc((var(--frame-h) - var(--oy, var(--header-h))) * var(--u));
}

/* rotated images: the outer .place is Figma's bounding box,
   the inner box has the unrotated size (--rw × --rh) and is turned by --r */
.rot > .rot-inner {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--rw) * var(--u));
  height: calc(var(--rh) * var(--u));
  transform: translate(-50%, -50%) rotate(var(--r));
}

.project-text { white-space: nowrap; }
.project-text--bold { font-weight: 700; }
.project-text--italic { font-style: italic; }
.project-text--light { font-weight: 300; }
.project-rule { height: 0; border-top: 1px solid var(--ink); }

.project-meta { display: none; }

/* ---- project text block: edit the copy freely, the layout follows ---- */
.project-copy {
  margin: calc(110 * var(--u)) calc(64 * var(--u)) calc(140 * var(--u)) calc(65 * var(--u));
}
.copy-lead {
  max-width: calc(1180 * var(--u));
  font-size: max(20px, calc(30 * var(--u)));
  font-weight: 700;
  line-height: 1.2;
}
.copy-grid {
  display: grid;
  grid-template-columns: calc(868 * var(--u)) 1fr;
  margin-top: calc(90 * var(--u));
}
.copy-facts { max-width: calc(700 * var(--u)); border-top: 1px solid var(--ink); }
.copy-facts div {
  display: grid;
  grid-template-columns: calc(160 * var(--u)) 1fr;
  gap: calc(12 * var(--u));
  padding: calc(9 * var(--u)) 0;
  border-bottom: 1px solid var(--ink);
}
.copy-facts dt { font-weight: 700; }
.copy-body {
  max-width: calc(620 * var(--u));
  font-size: max(14px, calc(17 * var(--u)));
  line-height: 1.45;
}
.copy-body p + p { margin-top: 1em; }

/* chapters: number + title in the first column, text across the others – like the tables */
.project-chapters {
  margin: calc(110 * var(--u)) calc(64 * var(--u)) calc(140 * var(--u)) calc(65 * var(--u));
}
.chapter {
  display: grid;
  grid-template-columns: calc(392 * var(--u)) 1fr;
  padding: calc(14 * var(--u)) 0 calc(56 * var(--u));
  border-top: 1px solid var(--ink);
}
.chapter h2 { font-weight: 700; }
.chapter h2 span { display: inline-block; min-width: calc(40 * var(--u)); font-weight: 400; }
.chapter-text {
  max-width: calc(760 * var(--u));
  font-size: max(15px, calc(22 * var(--u)));
  font-weight: 300;
  line-height: 1.35;
}
.chapter-text p + p { margin-top: 0.8em; }

/* credits: the people behind the project */
.project-credits {
  display: grid;
  grid-template-columns: calc(392 * var(--u)) calc(476 * var(--u)) 1fr;
  margin: calc(110 * var(--u)) calc(64 * var(--u)) calc(140 * var(--u)) calc(65 * var(--u));
  padding-top: calc(14 * var(--u));
  border-top: 1px solid var(--ink);
}
.project-credits > h2 { font-weight: 700; }
.credit { padding-right: calc(40 * var(--u)); }
.credit h3 { font: inherit; font-weight: 700; margin: 0; }
.credit-role { margin-top: calc(4 * var(--u)); color: var(--muted); }
.credit-bio {
  max-width: calc(520 * var(--u));
  margin-top: calc(18 * var(--u));
  font-size: max(14px, calc(17 * var(--u)));
  line-height: 1.45;
}

.project-pager {
  display: flex;
  justify-content: space-between;
  margin: 0 calc(64 * var(--u)) calc(90 * var(--u)) calc(65 * var(--u));
  padding-top: calc(10 * var(--u));
  border-top: 1px solid var(--ink);
  font-weight: 700;
}
.project-pager span { display: block; margin-bottom: calc(4 * var(--u)); font-weight: 400; }
.pager-next { text-align: right; }
.project-pager a:hover { text-decoration: underline; text-underline-position: from-font; }

.rimowa-gallery-link { cursor: pointer; }
.rimowa-gallery-link .place { transition: transform 0.3s var(--ease); }
.rimowa-gallery-link:hover .place { transform: translateY(calc(-8 * var(--u))); }
.rimowa-gallery-hint {
  position: absolute;
  font-weight: 700;
  white-space: nowrap;
}

/* ==========================================================================
   RIMOWA configurator: drag the train, the section behind the case is
   printed on it. The platform stays put, only the train moves.
   ========================================================================== */

.configurator {
  position: relative;
  height: calc((1117 - var(--header-h)) * var(--u));
  overflow: hidden;
  touch-action: pan-y;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}
.configurator.is-dragging { cursor: grabbing; }
.configurator:focus { outline: none; }
.configurator:focus-visible .cfg-progress { height: 3px; }

.cfg-train {
  position: absolute;
  left: 0;
  top: calc((235 - var(--header-h)) * var(--u));
  width: calc(6529 * var(--u));
  height: calc(730 * var(--u));
  max-width: none;
  object-fit: cover;
  transform: translateX(var(--tx, 0px));
}
/* the platform never moves; its bench is always centred under the case */
.cfg-platform { z-index: 1; left: calc(50% - 2747 * var(--u)); }

/* the case stands on the bench, centred in the stage (--cx is set by JS);
   a soft white glow lifts it off the train behind it */
.cfg-case {
  position: absolute;
  z-index: 3;
  left: var(--cx, calc(674 * var(--u)));
  top: calc((442 - var(--header-h)) * var(--u));
  width: calc(380 * var(--u));
  height: calc(338 * var(--u));
  isolation: isolate;
  pointer-events: none;
  filter:
    drop-shadow(0 0 calc(4 * var(--u)) rgb(255 255 255 / 0.95))
    drop-shadow(0 0 calc(18 * var(--u)) rgb(255 255 255 / 0.85))
    drop-shadow(0 0 calc(46 * var(--u)) rgb(255 255 255 / 0.6));
}
.cfg-case > img { position: absolute; inset: 0; width: 100%; height: 100%; }
/* front face of the case (inside the aluminium rim) */
.cfg-face {
  position: absolute;
  left: 0.6%;
  top: 11.4%;
  width: 98.8%;
  height: 87.4%;
  overflow: hidden;
  border-radius: calc(11 * var(--u));
  mix-blend-mode: multiply;
}
.cfg-face > .cfg-print {
  position: absolute;
  /* the print is the train itself, lined up with the train behind the case */
  left: calc(-1 * var(--fx, 0px));
  top: calc(-1 * var(--fy, 0px));
  width: calc(6529 * var(--u));
  height: calc(730 * var(--u));
  max-width: none;
  object-fit: cover;
  transform: translateX(var(--tx, 0px));
}
.cfg-case > .cfg-number {
  inset: auto;
  left: 0.6%;
  top: 11.4%;
  width: 34.4%;
  height: auto;
  border-top-left-radius: calc(11 * var(--u));
  filter: brightness(0.7) contrast(1.5); /* deeper black, the digits stay white */
}
.cfg-sheen { mix-blend-mode: screen; opacity: 0.35; }
.cfg-shadow {
  position: absolute;
  z-index: 2;
  left: var(--cx, calc(674 * var(--u)));
  top: calc((768 - var(--header-h)) * var(--u));
  width: calc(380 * var(--u));
  height: calc(18 * var(--u));
  background: radial-gradient(closest-side, rgb(0 0 0 / 0.45), transparent);
  pointer-events: none;
}
.cfg-ui {
  position: absolute;
  z-index: 4;
  left: calc(65 * var(--u));
  right: calc(64 * var(--u));
  bottom: calc(22 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(20 * var(--u));
  pointer-events: none;
}
.cfg-ui strong { white-space: nowrap; }
.cfg-progress { position: relative; flex: 1; height: 1px; background: rgb(0 0 0 / 0.25); }
.cfg-progress span {
  position: absolute;
  top: -3px;
  left: calc(var(--p, 0) * (100% - 40px));
  width: 40px;
  height: 7px;
  background: var(--ink);
}
.cfg-buttons { display: flex; gap: 8px; pointer-events: auto; }
.cfg-buttons button {
  width: 32px;
  height: 32px;
  border: 1px solid var(--ink);
  border-radius: 50%;
  background: var(--paper);
  cursor: pointer;
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .ticker-track { animation: none; }
  .cat-img, .cat-label, .cat-line { transition: none; }
  .cat-img--music > img, .cat { animation: none !important; }
}

/* ==========================================================================
   Mobile & small tablets (< 900px)
   ========================================================================== */

@media (max-width: 899px) {
  :root { --fs: 12px; --bar-h: 56px; }
  /* no size container on mobile, so the fixed menu is relative to the viewport */
  body { container-type: normal; }

  .page,
  .site-header { width: auto; }

  /* ---- header: name + logo stay pinned; nav + lever scroll away,
          and the logo turns into a burger once you scroll ---- */
  .site-header {
    position: sticky;
    height: var(--bar-h);
    padding: 0 16px;
    display: flex;
    align-items: center;
  }
  .site-header .hx,
  .clock { position: static; }
  .identity { flex: 1; justify-content: space-between; align-items: center; }
  .logo { width: 64px; height: 23px; transition: opacity 0.2s, transform 0.3s var(--ease); }
  .clock, .view-toggle { display: none; }

  .main-nav,
  .header-lever {
    position: absolute;
    left: 16px;
    right: 16px;
    transition: opacity 0.2s var(--ease), transform 0.3s var(--ease);
  }
  .main-nav { top: calc(var(--bar-h) + 4px); display: flex; gap: 22px; }
  .header-lever { top: calc(var(--bar-h) + 38px); display: block; }
  .page { margin-top: 40px; }
  .has-toggle ~ .page { margin-top: 82px; }

  .burger {
    position: absolute;
    right: 0;
    top: 50%;
    display: block;
    width: 44px;
    height: 44px;
    margin-top: -22px;
    padding: 0;
    border: 0;
    background: none;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s var(--ease);
    -webkit-tap-highlight-color: transparent;
  }
  .identity { position: relative; }
  .burger span {
    position: absolute;
    right: 10px;
    width: 26px;
    height: 2px;
    background: var(--ink);
    transform: scaleX(0);
    transform-origin: 100% 50%;
    transition: transform 0.3s var(--ease), top 0.3s var(--ease), rotate 0.3s var(--ease);
  }
  .burger span:nth-child(1) { top: 14px; }
  .burger span:nth-child(2) { top: 21px; transition-delay: 0.04s; }
  .burger span:nth-child(3) { top: 28px; transition-delay: 0.08s; }

  .site-header.is-compact .logo { opacity: 0; transform: scale(0.6) rotate(-8deg); pointer-events: none; }
  .site-header.is-compact .burger,
  .site-header.menu-open .burger { opacity: 1; pointer-events: auto; }
  .site-header.is-compact .burger span,
  .site-header.menu-open .burger span { transform: scaleX(1); }
  .site-header.is-compact .main-nav,
  .site-header.is-compact .header-lever,
  .site-header.menu-open .main-nav,
  .site-header.menu-open .header-lever { opacity: 0; transform: translateY(-8px); pointer-events: none; }

  /* burger → X while the menu is open */
  .site-header.menu-open .logo { opacity: 0; }
  .site-header.menu-open .burger span { transform-origin: 50% 50%; }
  .site-header.menu-open .burger span:nth-child(1) { top: 21px; rotate: 45deg; }
  .site-header.menu-open .burger span:nth-child(2) { transform: scaleX(0); }
  .site-header.menu-open .burger span:nth-child(3) { top: 21px; rotate: -45deg; }

  .site-menu {
    position: fixed;
    inset: 0;
    z-index: 45;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: calc(var(--bar-h) + 40px) 16px 40px;
    background: var(--paper);
    opacity: 0;
    transition: opacity 0.25s var(--ease);
  }
  .site-menu[hidden] { display: none; }
  .site-menu.is-open { opacity: 1; }
  .site-menu-nav { display: flex; flex-direction: column; gap: 10px; font-size: 40px; font-weight: 300; }
  .site-menu-nav a[aria-current="page"] { font-weight: 700; }
  .site-menu .lever { font-size: 14px; }
  html.menu-locked { overflow: hidden; }

  /* ---- table: one block per project ---- */
  .table { margin: 0 16px; }
  .table-head { display: none; }
  .rows { margin-top: 0; }
  .row {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "client year"
      "project project"
      "desc desc";
    row-gap: 2px;
    padding: 10px 0;
    margin: 0;
    border-top: 1px solid var(--ink);
  }
  .row:last-child { border-bottom: 1px solid var(--ink); }
  .row::after { display: none; }
  .row.is-active { margin-bottom: 0; font-weight: 400; }
  .row.is-current { margin-bottom: 0; font-weight: 400; background: rgb(0 0 0 / 0.04); }
  .category-detail a.row:hover { margin-bottom: 0; font-weight: 400; }
  .row > span { padding-right: 0; }
  .row > .col-project { grid-area: project; }
  .row > .col-client { grid-area: client; font-weight: 700; }
  .row > .col-desc { grid-area: desc; color: var(--muted); }
  .row > .col-year { grid-area: year; }

  /* ---- ticker: bigger objects, labels always visible, tap to open ---- */
  .ticker { --u: 0.62px; width: auto; margin-left: 0; height: calc(250 * var(--u)); }
  .ticker-item:hover { transform: none; }

  /* ---- home: the client photos give way to the rotatable 3D objects ---- */
  .home-hero { display: none; }
  .object-stage {
    display: block;
    position: relative;
    margin: 0 16px;
  }
  .object-stage .spin {
    position: relative;
    width: min(78vw, 340px);
    aspect-ratio: 1;
    margin: 0 auto;
    background-size: 1000% 600%;
  }
  .object-stage-bar {
    display: grid;
    grid-template-columns: 44px 1fr 44px;
    align-items: center;
    text-align: center;
  }
  .object-stage-bar button {
    height: 44px;
    border: 0;
    background: none;
    font-size: 20px;
    cursor: pointer;
  }
  .stage-caption strong { display: block; }
  .stage-caption span { display: block; color: var(--muted); font-size: 11px; margin-top: 2px; }
  .stage-hint { margin-top: 6px; text-align: center; color: var(--muted); font-size: 11px; }
  .home-table { height: auto; margin-top: 24px; }
  .home-ticker { margin: 32px 0 24px; }
  .preview { display: none; }

  /* ---- work: the objects float around; tap shows the description, tap again opens ---- */
  .categories {
    height: 175vw;
    max-height: 820px;
    margin: 0 8px;
  }
  .cat {
    position: absolute;
    left: var(--mx);
    top: var(--my);
    width: var(--mw);
    animation: cat-float var(--fd, 7s) ease-in-out var(--fdel, 0s) infinite alternate;
  }
  .cat-img {
    position: relative;
    left: auto;
    top: auto;
    width: 100%;
    height: auto;
    aspect-ratio: var(--w) / var(--h);
  }
  .cat:hover .cat-img { transform: none; }
  .cat.is-open .cat-img { transform: scale(1.12); }
  .cat-line { display: none; }
  .cat-label {
    position: absolute;
    left: 0;
    right: auto;
    top: calc(100% + 8px);
    padding: 8px 10px;
    background: rgb(255 255 255 / 0.92);
    text-align: left;
  }
  .cat[data-label-side="above"] .cat-label { top: auto; bottom: calc(100% + 8px); }
  .cat[data-label-side="right"] .cat-label { left: auto; right: 0; text-align: right; }
  .cat.is-open .cat-label { pointer-events: auto; }
  .cat-label strong { line-height: normal; }
  .cat-label ul { margin-top: 6px; }
  .cat-label li { height: auto; margin-bottom: 2px; }
  .cat-open { display: inline-block; margin-top: 8px; font-weight: 700; text-decoration: underline; }
  .cat.is-open { z-index: 5; animation-play-state: paused; }
  .work-hint { display: block; position: absolute; left: 8px; right: 8px; bottom: 0; text-align: center; color: var(--muted); font-size: 11px; }

  @keyframes cat-float {
    0% { translate: 0 0; rotate: -2deg; }
    50% { translate: 6px -10px; rotate: 1.5deg; }
    100% { translate: -5px 6px; rotate: -1deg; }
  }

  /* ---- category pages ---- */
  .category-detail { padding-bottom: 48px; }
  .category-hero { height: auto; margin: 8px 16px 28px; display: flex; flex-direction: column-reverse; gap: 16px; }
  .category-image {
    position: relative;
    left: auto;
    width: min(100%, calc(var(--w) / var(--h) * 60vh));
    height: auto;
    aspect-ratio: var(--w) / var(--h);
    margin: 0 auto;
  }
  .category-label { position: static; text-align: left; }
  .category-label ul { margin-top: 6px; }
  .category-label li { margin-bottom: 2px; }
  .category-detail .table { margin-top: 0; }

  /* ---- 3D cards ---- */
  .contact-stage { height: auto; padding: 36px 16px 8px; }
  .about-stage .card3d,
  .contact-stage .card3d { position: relative; left: auto; top: auto; width: 100%; height: auto; aspect-ratio: var(--w) / var(--h); perspective: 1400px; }
  .envelope-shadow { display: none; }
  .card3d-hint { position: static; margin-top: 14px; font-size: 11px; }
  .contact-ticker { margin: 32px 0 24px; }

  /* ---- about ---- */
  .about-stage { height: auto; padding: 16px 16px 32px; display: flex; flex-direction: column; }
  .about-stage .place:not(.card3d) { position: relative; left: auto; top: auto; width: auto; height: auto; }
  .about-portrait { aspect-ratio: 485 / 628; width: 70% !important; margin-top: 40px; }
  .about-heading-row { display: flex; justify-content: space-between; align-items: baseline; margin-top: 28px; }
  .about-title, .about-subtitle { font-size: 16px; }
  .about-year { font-size: 14px; }
  .about-rule { margin-top: 6px; }
  .about-text { font-size: 16px; text-align: left; margin-top: 20px; }
  .about-text p + p { margin-top: 14px; }
  .about-subtitle { margin-top: 48px; }
  .skills { position: relative; margin-top: 16px; }
  .skills li { position: static; font-size: 14px; margin-bottom: 14px; }
  .skills li::after {
    content: "";
    display: block;
    height: 10px;
    margin-top: 6px;
    border: 0.75px solid #231f20;
    border-radius: 5px;
    background: linear-gradient(to right, rgb(120 120 120 / 0.23) calc(var(--lvl) * 100%), transparent 0);
  }
  .skill-bars, .skill-scale, .skill-scale-labels { display: none !important; }
  .about-objects { display: none !important; }

  /* ---- project pages: info on top, image composition scales, text is full width ---- */
  .project-meta { display: block; padding: 8px 16px 20px; }
  .project-meta dt { font-weight: 700; margin-top: 10px; }
  .project-meta dd { margin: 2px 0 0; }
  .project-stage .project-text,
  .project-stage .project-rule { display: none; }
  .project-copy { margin: 36px 16px 48px; }
  .copy-lead { font-size: 20px; }
  .project-chapters { margin: 36px 16px 48px; }
  .chapter { display: block; padding: 10px 0 32px; }
  .chapter-text { max-width: none; margin-top: 14px; font-size: 17px; }
  .project-credits { display: block; margin: 36px 16px 48px; padding-top: 10px; }
  .credit { margin-top: 24px; padding-right: 0; }
  .credit-bio { max-width: none; font-size: 15px; }
  .copy-grid { display: block; margin-top: 28px; }
  .copy-facts { max-width: none; }
  .copy-facts div { grid-template-columns: 90px 1fr; padding: 8px 0; }
  .copy-body { max-width: none; margin-top: 24px; font-size: 15px; }
  .project-pager { margin: 0 16px 40px; padding-top: 10px; }
  .object-3d.is-sprite { background-size: 1000% 600%; }

  /* ---- configurator ---- */
  .configurator { --u: 0.54px; }
  .cfg-ui { left: 16px; right: 16px; bottom: 14px; flex-wrap: wrap; row-gap: 10px; font-size: 11px; }
  .cfg-ui strong { flex-basis: 100%; }
}
