/* ---------- Font ---------- */
@font-face {
  font-family: "Roboto Mono";
  src: url("fonts/RobotoMono-Light.woff") format("woff");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Roboto Mono";
  src: url("fonts/RobotoMono-Regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Roboto Mono";
  src: url("fonts/RobotoMono-Medium.woff") format("woff");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Roboto Mono";
  src: url("fonts/RobotoMono-Bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- Page transitions ---------- */
/* Native cross-document View Transitions: opt every same-origin navigation
   (nav words, brand link, back/forward) into a browser-captured crossfade —
   the new page fades in from transparent, no JS routing needed. Must be
   declared on every page's CSS (this file is shared by all of them).
   Unsupported browsers (Safari/Firefox as of now) just navigate normally —
   this rule is silently ignored there, nothing to fall back to. */
@view-transition {
  navigation: auto;
}

::view-transition-old(root) {
  animation: about-page-out 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
::view-transition-new(root) {
  animation: about-page-in 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
@keyframes about-page-out {
  to   { opacity: 0; }
}
@keyframes about-page-in {
  from { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*) { animation: none !important; }
}

/* Fallback for browsers without cross-document View Transitions (Safari,
   Firefox): a plain fade through the shared page background, driven by
   main.js. Opaque by default so it covers the very first paint — no flash
   of unstyled content before the script can react. Chrome/Edge remove this
   element immediately (see main.js) and never see it. */
.page-fade {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: #fcfcfc;
  opacity: 1;
  transition: opacity 0.32s ease;
}
.page-fade.is-hidden {
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .page-fade { transition: none; }
}

/* ---------- Reset ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; }

body {
  font-family: "Roboto Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  background: #fcfcfc;
  color: #2c2c2e;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* every other page is a single fixed-viewport stage with nothing to scroll;
   OFFZONE's item grid is genuinely taller than one screen, so it needs the
   real page scroll that the rule above blocks everywhere else. */
body.offzone-page { overflow-y: auto; }

/* ---------- Stage ---------- */
.stage {
  position: fixed;
  inset: 0;
  background: #fcfcfc;
  overflow: hidden;
}

/* ---------- Character video ---------- */
/* A plain ambient loop: he stands, looks at the camera and blinks.
   object-fit keeps the original composition and aspect ratio; the element
   never moves. */
.character {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
}
.character video {
  position: absolute;
  left: 50%;
  bottom: 0;                       /* seat the figure on the bottom edge */
  transform: translateX(-50%);
  height: 61vh;                    /* sized to match the reference framing */
  width: auto;
  max-width: 96vw;
  object-fit: contain;
}

/* ---------- Navigation words ---------- */
.nav-word {
  position: absolute;
  font-weight: 300;
  font-size: clamp(21px, 2.55vw, 40px);
  letter-spacing: -0.03em;
  color: #313134;
  text-decoration: none;
  white-space: nowrap;
  transition: opacity 0.25s ease;
}
.nav-word:hover { opacity: 0.55; }

.nav-portfolio {
  top: 22%;
  left: 50%;
  transform: translateX(-50%);
}
.nav-about {
  top: 65.5%;
  left: 8.9%;
}
.nav-contacts {
  top: 65.5%;
  right: 9%;
}

@media (max-width: 760px) {
  /* The clip's frame is 16:9 (wide) but the figure only occupies its centre
     ~46% — sizing by height like the desktop rule does left a tall, mostly
     empty box on a narrow screen (object-fit: contain letterboxing the
     unused width), pushing the figure far down and opening a big gap under
     "портфолио". Cropping to the figure's own ~0.84 aspect ratio via cover
     removes exactly that dead transparent margin — not the subject itself —
     so the figure sits right under the nav word at a natural size. */
  .character video {
    width: 90vw;
    height: auto;
    max-width: none;
    aspect-ratio: 1776 / 2116;
    object-fit: cover;
    object-position: center top;
  }
  .nav-portfolio { top: 44%; }
  /* the figure fills almost the whole width here, so the side words sit
     beside the chin, just above the shoulders, and hug the screen edges.
     The video is 90vw wide and seated on the bottom edge, i.e. ~107vw tall,
     so the chin line is a fixed ~62vw up from the bottom on any phone —
     anchoring to that (not to a % of screen height) keeps the words clear
     of the figure on short and tall screens alike. */
  .nav-about    { top: calc(100% - 62vw); left: 3%; }
  .nav-contacts { top: calc(100% - 62vw); right: 3%; }
}

/* ---------- Brand (top-right) ---------- */
.brand {
  position: absolute;
  top: 28px;
  right: 34px;
  font-weight: 400;
  font-size: clamp(20px, 1.9vw, 32px);
  letter-spacing: 0.04em;
  color: #313134;
  text-decoration: none;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
}
.brand:hover { opacity: 0.55; }

/* ---------- About page ---------- */
.about-stage {
  position: fixed;
  inset: 0;
  background: #fcfcfc;
  overflow: hidden;
}
.about-main {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: clamp(31px, 5.1vw, 102px);
  padding: 96px clamp(28px, 6vw, 96px) 48px clamp(48px, 9vw, 140px);
}

/* Exported as HEVC+Alpha (.mov) — the video itself carries real per-pixel
   transparency, decoded natively by the browser. No keying, no canvas. */
.about-video {
  flex: 0 0 auto;
  width: min(52vh, 39vw);
  aspect-ratio: 1 / 1;
  position: relative;
}
.about-video video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.about-text {
  flex: 1 1 420px;
  width: 100%;
  max-width: 660px;
}
.about-text p {
  font-weight: 300;
  font-size: clamp(15px, 1.55vw, 19px);
  line-height: 1.7;
  letter-spacing: -0.01em;
  color: #313134;
  margin: 0 0 28px;
}
.about-text p:last-child { margin-bottom: 0; }
.about-text b { font-weight: 700; color: #201f1e; }

@media (max-width: 760px) {
  .about-main {
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-y: auto;
    padding: 96px 24px 40px;
    gap: 28px;
  }
  .about-video { width: min(58vh, 74vw); }
}

/* ---------- Contacts page ---------- */
.contacts-stage {
  position: fixed;
  inset: 0;
  background: #fcfcfc;
  overflow: hidden;
}
.contacts-main {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: clamp(80px, 14vw, 260px);
  padding: 96px clamp(28px, 6vw, 96px) 48px clamp(48px, 9vw, 140px);
}
.contacts-video {
  flex: 0 0 auto;
  width: min(45vh, 36vw);
  aspect-ratio: 1 / 1;
  position: relative;
}
.contacts-video video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.contacts-text {
  flex: 1 1 260px;
  display: flex;
  flex-direction: column;
  gap: 30px;
}
.contacts-text a {
  font-weight: 300;
  font-size: clamp(18px, 2.1vw, 27px);
  letter-spacing: -0.01em;
  color: #313134;
  text-decoration: none;
}
.contacts-text a:hover { opacity: 0.55; }

@media (max-width: 760px) {
  .contacts-main {
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-y: auto;
    padding: 96px 24px 40px;
    gap: 28px;
  }
  .contacts-video { width: min(58vh, 74vw); }
}

/* ---------- Portfolio page ---------- */
.portfolio-stage {
  position: fixed;
  inset: 0;
  background: #fcfcfc;
  overflow-y: auto;
}
.portfolio-top {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(36px, 6vw, 120px);
  padding: 96px clamp(28px, 6vw, 96px) 12px clamp(48px, 9vw, 140px);
}
.portfolio-video {
  flex: 0 0 auto;
  width: min(42vh, 34vw);
  aspect-ratio: 1 / 1;
  position: relative;
}
.portfolio-video video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
}
.portfolio-resume {
  display: inline-flex;
  align-items: center;
  gap: 22px;
  text-decoration: none;
  color: #313134;
}
.portfolio-resume:hover { opacity: 0.6; }
.portfolio-resume span {
  font-weight: 300;
  font-size: clamp(15px, 1.5vw, 19px);
}
.portfolio-resume svg {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
}

.portfolio-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 56px 24px;
  max-width: 1080px;
  margin: 0 auto;
  padding: 40px clamp(28px, 6vw, 96px) 110px;
}
@media (max-width: 900px) {
  .portfolio-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .portfolio-top { padding-top: 96px; }
  .portfolio-grid { grid-template-columns: 1fr; }
}

/* Project card: a flat-design folder (built from plain CSS shapes, same
   house style as the rest of the site — no icon assets). 2-3 product
   renders peek out the top like papers half-pulled from the folder;
   the project name sits on the front pocket like a label. */
.project-card-link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: transform 0.25s ease;
}
.project-card-link:hover { transform: translateY(-6px) scale(1.03); }
.project-card-link:hover .folder-front { filter: brightness(1.12) saturate(1.15); }
.project-card-link:hover .folder-tab,
.project-card-link:hover .folder-body { filter: brightness(1.08); }

.project-card {
  position: relative;
  width: 143px;
  height: 125px;
  margin: 33px auto 0;
}

/* Dark folder again (the pale one didn't fit either) — this time a two-tone
   build closer to the reference: near-black tab/back, and a distinctly
   lighter grey "front pocket" flap with its own gradient + an inset shadow
   where it tucks under the black back, instead of one flat colour throughout. */
.folder-tab {
  position: absolute;
  top: 12px;
  left: 0;
  width: 52%;
  height: 25px;
  background: linear-gradient(160deg, #3a3a3a 0%, #0d0d0d 100%);
  border-radius: 12px 12px 0 0;
  box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.14);
  transition: filter 0.25s ease;
}
.folder-body {
  position: absolute;
  top: 22px;
  left: 0;
  width: 100%;
  height: calc(100% - 22px);
  background:
    radial-gradient(120% 90% at 12% 0%, rgba(255, 255, 255, 0.16) 0%, rgba(255, 255, 255, 0) 45%),
    linear-gradient(165deg, #2c2c2c 0%, #0a0a0a 100%);
  border-radius: 4px 14px 14px 14px;
  box-shadow: 0 16px 26px rgba(0, 0, 0, 0.36);
  transition: filter 0.25s ease;
}
.folder-front {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 68%;
  /* translucent frosted-glass pocket, layered: a diagonal shine streak on
     top of the base tint, so it reads as glass catching light at an angle
     rather than a single flat gradient — the black body still shows
     through lower down. */
  background:
    linear-gradient(115deg,
      rgba(255, 255, 255, 0.4) 0%,
      rgba(255, 255, 255, 0) 22%,
      rgba(255, 255, 255, 0) 78%,
      rgba(255, 255, 255, 0.16) 100%),
    linear-gradient(175deg,
      rgba(210, 219, 235, 0.45) 0%,
      rgba(145, 151, 163, 0.34) 35%,
      rgba(40, 40, 44, 0.52) 100%);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  border-radius: 4px 14px 14px 14px;
  clip-path: polygon(0% 32%, 100% 12%, 100% 100%, 0% 100%);
  /* shadow cast by the black back onto the pocket right at the fold, plus a
     faint top highlight on the pocket itself for a bit of material depth */
  box-shadow: inset 0 10px 12px -6px rgba(0, 0, 0, 0.4),
    inset 0 1px 0 0 rgba(255, 255, 255, 0.4);
  transition: filter 0.3s ease;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: 12px;
}
.project-title {
  color: #e4e4e4;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  padding: 0 10px;
}

/* ---------- OFFZONE 2025 project page ---------- */
/* Ordinary document flow + `position: sticky` for the header — deliberately
   NOT the earlier fixed-stage-with-an-internally-scrolling-grid setup. That
   nested "fixed ancestor, overflow:auto child" pattern is exactly the
   combination Safari (especially iOS) is known to mishandle: fixed
   descendants can visibly lag or detach during the child's own scroll, and
   the two scroll paths can fight and stall each other. A single normal page
   scroll with a sticky header is the boring, robust way to pin a header —
   no nested scroll container, no fixed-in-fixed edge cases. */
.offzone-stage {
  position: relative;
  min-height: 100vh;
  background: #fcfcfc;
}
.offzone-back {
  position: fixed;
  top: 30px;
  left: 34px;
  font-weight: 300;
  font-size: 16px;
  color: #313134;
  text-decoration: none;
  z-index: 6;
}
.offzone-back:hover { opacity: 0.55; }

/* .brand is shared across pages as position:absolute, anchored to each
   page's own position:fixed stage; this page's stage is a normal in-flow
   container instead (see the note above .offzone-stage), so pin brand to
   the viewport directly or it would scroll away with the grid. */
.offzone-stage .brand {
  position: fixed;
  z-index: 6;
}

.offzone-intro {
  padding: 96px clamp(28px, 6vw, 96px) 32px;
}
.offzone-intro h1 {
  font-weight: 400;
  font-size: clamp(28px, 3.6vw, 46px);
  letter-spacing: 0.01em;
  margin-bottom: 16px;
}
.offzone-intro p {
  font-weight: 300;
  font-size: clamp(14px, 1.3vw, 17px);
  line-height: 1.7;
  color: #313134;
  max-width: min(760px, 56vw);
  margin-bottom: 14px;
}
.offzone-intro p:last-child { margin-bottom: 0; }

/* An even, orderly grid — same cell size throughout, items centred inside
   their cell via object-fit so different product aspect ratios don't throw
   the rows out of line. */
.offzone-space {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(16px, 2.5vw, 40px);
  justify-items: center;
  align-items: center;
  padding: 0 clamp(28px, 6vw, 96px) 80px;
}
@media (max-width: 1000px) {
  .offzone-space { grid-template-columns: repeat(4, 1fr); }
}
@media (max-width: 760px) {
  .offzone-space { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 480px) {
  .offzone-space { grid-template-columns: repeat(2, 1fr); }
}

.floating-item {
  position: relative;
  width: 100%;
  max-width: 150px;
  aspect-ratio: 1 / 1;
  cursor: pointer;
  filter: drop-shadow(0 10px 18px rgba(44, 44, 46, 0.14));
  transform: scale(1);
  transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), filter 0.3s ease;
}
.floating-item:hover,
.floating-item:focus-visible {
  transform: scale(1.12);
  filter: drop-shadow(0 16px 26px rgba(44, 44, 46, 0.2));
}
.floating-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  user-select: none;
}
.floating-item.is-hidden-original { opacity: 0; }

.offzone-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(252, 252, 252, 0.92);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease;
  z-index: 10;
}
.offzone-backdrop.is-visible { opacity: 1; pointer-events: auto; }

/* The focused view: a single fixed layer reused for whichever item was
   clicked. Opening/closing is a FLIP — offzone.js sets the render's start
   rect as plain inline left/top/width/height (matching the clicked item's
   current on-screen box exactly, mid-drift), then toggling .is-open swaps
   in the centred/enlarged target via a class rule. Because that target rule
   carries !important, it wins over the inline "from" values without needing
   any JS animation loop — only the transition below, on the same properties,
   does the animating. */
.offzone-focus {
  position: fixed;
  inset: 0;
  z-index: 20;
  visibility: hidden;
  pointer-events: none;
}
.offzone-focus.is-visible { visibility: visible; }

.offzone-focus-render {
  position: fixed;
  pointer-events: auto;
  transition:
    left 0.48s cubic-bezier(0.2, 0.8, 0.2, 1),
    top 0.48s cubic-bezier(0.2, 0.8, 0.2, 1),
    width 0.48s cubic-bezier(0.2, 0.8, 0.2, 1),
    height 0.48s cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 0.48s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.offzone-focus-render img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 20px 40px rgba(44, 44, 46, 0.18));
}
.offzone-focus.is-open .offzone-focus-render {
  left: 50% !important;
  top: 50% !important;
  width: min(42vw, 380px) !important;
  height: min(42vw, 380px) !important;
  transform: translate(-50%, -50%) !important;
}
.offzone-focus.has-photo.is-open .offzone-focus-render {
  left: calc(50% - min(21vw, 190px) - 16px) !important;
}

.offzone-focus-photo {
  position: fixed;
  left: 50%;
  top: 50%;
  width: min(42vw, 380px);
  height: min(42vw, 380px);
  transform: translate(-50%, -50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s ease 0.12s,
    left 0.48s cubic-bezier(0.2, 0.8, 0.2, 1),
    top 0.48s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.offzone-focus.has-photo.is-open .offzone-focus-photo {
  left: calc(50% + min(21vw, 190px) + 16px);
  opacity: 1;
}
/* Photos keep their own aspect ratio (portrait shots, screenshots, square
   cut-outs all mix), so the square slot just centres them and never crops. */
.offzone-focus-photo {
  display: flex;
  align-items: center;
  justify-content: center;
}
.offzone-focus-photo img,
.offzone-focus-photo video {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 12px;
  filter: drop-shadow(0 20px 40px rgba(44, 44, 46, 0.18));
}
/* the slot shows either the photo carousel or (for `video: true` items) a clip */
.offzone-focus-photo.is-video img { display: none; }
.offzone-focus-photo:not(.is-video) video { display: none; }
.offzone-focus-photo video { height: 100%; background: #0e0e10; }

/* Prev/next + dots only show once there's more than one live photo to flip
   through (.has-multiple, toggled by offzone.js) — a single photo looks
   exactly like before, no carousel chrome. */
.offzone-photo-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: rgba(252, 252, 252, 0.92);
  box-shadow: 0 2px 10px rgba(44, 44, 46, 0.18);
  color: #313134;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, background 0.2s ease;
}
.offzone-photo-nav.prev { left: 10px; }
.offzone-photo-nav.next { right: 10px; }
.offzone-photo-nav:hover { background: rgba(252, 252, 252, 0.98); }
.offzone-focus-photo.has-multiple .offzone-photo-nav {
  opacity: 1;
  pointer-events: auto;
}

.offzone-photo-dots {
  position: absolute;
  left: 50%;
  top: 100%;
  margin-top: 14px;
  transform: translateX(-50%);
  display: flex;
  gap: 7px;
}
.offzone-photo-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 0;
  background: rgba(49, 49, 52, 0.22);
  cursor: pointer;
  padding: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, background 0.2s ease, transform 0.2s ease;
}
.offzone-focus-photo.has-multiple .offzone-photo-dot {
  opacity: 1;
  pointer-events: auto;
}
.offzone-photo-dot.is-active {
  background: #313134;
  transform: scale(1.3);
}

.offzone-focus-name {
  position: fixed;
  left: 50%;
  bottom: 9%;
  transform: translateX(-50%);
  font-weight: 300;
  font-size: clamp(16px, 2vw, 22px);
  color: #313134;
  opacity: 0;
  width: max-content;
  max-width: min(86vw, 560px);
  text-align: center;
  line-height: 1.35;
  pointer-events: none;
  transition: opacity 0.3s ease 0.2s;
}
.offzone-focus.is-open .offzone-focus-name { opacity: 1; }

.offzone-close {
  position: fixed;
  top: 28px;
  right: 34px;
  width: 40px;
  height: 40px;
  border: 0;
  background: none;
  cursor: pointer;
  font-size: 26px;
  font-weight: 300;
  line-height: 1;
  color: #313134;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease 0.2s;
}
.offzone-focus.is-open .offzone-close { opacity: 1; pointer-events: auto; }
.offzone-close:hover { opacity: 0.55 !important; }

@media (max-width: 760px) {
  .offzone-focus.is-open .offzone-focus-render,
  .offzone-focus-photo {
    width: min(66vw, 300px) !important;
    height: min(66vw, 300px) !important;
  }
  .offzone-focus.has-photo.is-open .offzone-focus-render {
    left: 50% !important;
    top: calc(50% - min(66vw, 300px) / 2 - 10px) !important;
  }
  .offzone-focus.has-photo.is-open .offzone-focus-photo {
    left: 50%;
    top: calc(50% + min(66vw, 300px) / 2 + 10px);
  }
  .offzone-intro { max-width: 78vw; }
  .offzone-intro p { max-width: none; }
}

@media (max-width: 760px) {
  /* photo slot sits below the render here, and its dots below that — keep the
     item name clear of them */
  .offzone-focus-name { bottom: 3%; }
}

/* ---------- Showcase pages (video player + photo viewer) ---------- */
/* Used by pages whose content is a few clips / photos rather than a grid of
   product renders (China Joy, VK Fest, MKB, ...). Driven by projects/showcase.js. */
.sc {
  --sc-maxh: clamp(320px, calc(100vh - 340px), 780px);
  padding: 8px clamp(28px, 6vw, 96px) 96px;
}

.sc-stage {
  --ratio: 1.7778;
  position: relative;
  width: min(100%, calc(var(--sc-maxh) * var(--ratio)));
  aspect-ratio: var(--ratio);
  margin: 0 auto;
  border-radius: 18px;
  overflow: hidden;
  background: #0e0e10;
  box-shadow: 0 30px 60px -20px rgba(44, 44, 46, 0.35), 0 8px 20px rgba(44, 44, 46, 0.12);
  color: #fff;
  outline: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.sc-stage.is-photo { background: #ececee; }
.sc-view {
  position: absolute;
  inset: 0;
  opacity: 1;
  transition: opacity 0.18s ease;
}
.sc-stage.is-swapping .sc-view { opacity: 0; }
.sc-video,
.sc-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.sc-video { cursor: pointer; background: #0e0e10; }
.sc-stage.is-idle.is-playing .sc-video { cursor: none; }

/* big centre button: play / replay */
.sc-big {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 86px;
  height: 86px;
  margin: -43px 0 0 -43px;
  border: 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
  color: #1d1d1f;
  background: rgba(252, 252, 252, 0.9);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.32);
  transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.25s ease;
}
.sc-big:hover { transform: scale(1.08); }
.sc-big svg { width: 34px; height: 34px; fill: currentColor; }
.sc-big .i-replay { display: none; }
.sc-stage.is-ended .sc-big .i-play { display: none; }
.sc-stage.is-ended .sc-big .i-replay { display: block; }
.sc-stage.is-playing .sc-big { opacity: 0; pointer-events: none; transform: scale(0.85); }
.sc-stage.is-photo .sc-big { display: none; }

.sc-spinner {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 38px;
  height: 38px;
  margin: -19px 0 0 -19px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.25);
  border-top-color: #fff;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.sc-stage.is-loading .sc-spinner { opacity: 1; animation: sc-spin 0.8s linear infinite; }
.sc-stage.is-loading .sc-big { opacity: 0; }
@keyframes sc-spin { to { transform: rotate(360deg); } }

/* floating glass control bar */
.sc-bar {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 7px 12px 7px 8px;
  border-radius: 16px;
  background: rgba(24, 24, 27, 0.55);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 10px 30px rgba(0, 0, 0, 0.28);
  transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.sc-stage.is-photo .sc-bar { display: none; }
.sc-stage.is-idle.is-playing .sc-bar { opacity: 0; transform: translateY(10px); pointer-events: none; }

.sc-btn {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  transition: background 0.2s ease;
}
.sc-btn:hover,
.sc-btn:focus-visible { background: rgba(255, 255, 255, 0.16); }
.sc-btn svg { width: 20px; height: 20px; fill: currentColor; }
.sc-btn .i-pause,
.sc-btn .i-muted,
.sc-btn .i-fs-exit { display: none; }
.sc-stage.is-playing .sc-toggle .i-play { display: none; }
.sc-stage.is-playing .sc-toggle .i-pause { display: block; }
.sc-stage.is-muted .sc-mute .i-vol { display: none; }
.sc-stage.is-muted .sc-mute .i-muted { display: block; }
.sc-stage.is-fs .sc-full .i-fs-enter { display: none; }
.sc-stage.is-fs .sc-full .i-fs-exit { display: block; }

.sc-time {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 300;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, 0.92);
  white-space: nowrap;
}

/* progress: 24px-tall hit area around a thin track that thickens on hover */
.sc-track {
  position: relative;
  flex: 1 1 auto;
  min-width: 40px;
  height: 24px;
  cursor: pointer;
  touch-action: none;
}
.sc-track::before,
.sc-buffered,
.sc-played {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  height: 4px;
  margin-top: -2px;
  border-radius: 2px;
  transition: height 0.15s ease, margin-top 0.15s ease;
}
.sc-track::before { right: 0; background: rgba(255, 255, 255, 0.22); }
.sc-buffered { width: 0; background: rgba(255, 255, 255, 0.28); }
.sc-played { width: 0; background: #fff; }
.sc-track:hover::before,
.sc-track:hover .sc-buffered,
.sc-track:hover .sc-played,
.sc-track.is-drag::before,
.sc-track.is-drag .sc-buffered,
.sc-track.is-drag .sc-played { height: 6px; margin-top: -3px; }
.sc-knob {
  position: absolute;
  top: 50%;
  left: 0;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
  transform: scale(0);
  transition: transform 0.15s ease;
  pointer-events: none;
}
.sc-track:hover .sc-knob,
.sc-track.is-drag .sc-knob,
.sc-track:focus-visible .sc-knob { transform: scale(1); }

.sc-volume {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
}
.sc-vol-range {
  -webkit-appearance: none;
  appearance: none;
  width: 0;
  height: 4px;
  margin: 0;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.3);
  cursor: pointer;
  opacity: 0;
  transition: width 0.25s ease, opacity 0.2s ease, margin 0.25s ease;
}
.sc-vol-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  border: 0;
}
.sc-vol-range::-moz-range-thumb { width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 0; }
@media (hover: hover) {
  .sc-stage:not(.is-narrow) .sc-volume:hover .sc-vol-range,
  .sc-stage:not(.is-narrow) .sc-vol-range:focus-visible {
    width: 74px;
    opacity: 1;
    margin: 0 8px 0 4px;
  }
}

/* prev/next arrows for photo viewers */
.sc-arrow {
  position: absolute;
  top: 50%;
  width: 42px;
  height: 42px;
  margin-top: -21px;
  border: 0;
  border-radius: 50%;
  background: rgba(252, 252, 252, 0.92);
  color: #313134;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 12px rgba(44, 44, 46, 0.22);
  opacity: 0;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.sc-arrow.prev { left: 14px; }
.sc-arrow.next { right: 14px; }
.sc-stage.is-photo.has-many .sc-arrow { opacity: 1; }
.sc-arrow:hover { transform: scale(1.08); }
.sc-stage:not(.is-photo) .sc-arrow { display: none; }

/* fullscreen: the stage itself fills the screen, the video letterboxes */
.sc-stage:fullscreen { width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; background: #000; box-shadow: none; }
.sc-stage:-webkit-full-screen { width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; background: #000; box-shadow: none; }
.sc-stage.is-fs .sc-bar { left: 24px; right: 24px; bottom: 24px; }

/* thumbnails */
.sc-thumbs {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 14px;
  flex-wrap: wrap;
  margin: 26px auto 0;
  max-width: 1100px;
}
.sc-thumb {
  position: relative;
  display: block;
  width: 132px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: #313134;
  cursor: pointer;
  text-align: left;
}
.sc-thumb-frame {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: 11px;
  overflow: hidden;
  background: #0e0e10;
  opacity: 0.55;
  box-shadow: 0 8px 18px -8px rgba(44, 44, 46, 0.4);
  transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.25s ease;
}
.sc-thumb:hover .sc-thumb-frame { opacity: 0.9; transform: translateY(-3px); }
.sc-thumb.is-active .sc-thumb-frame {
  opacity: 1;
  box-shadow: 0 0 0 2px #fcfcfc, 0 0 0 4px #313134, 0 12px 22px -8px rgba(44, 44, 46, 0.45);
}
.sc-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sc-thumb-play {
  position: absolute;
  left: 8px;
  bottom: 8px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(252, 252, 252, 0.9);
  color: #1d1d1f;
}
.sc-thumb-play svg { width: 10px; height: 10px; fill: currentColor; margin-left: 1px; }
.sc-thumb-dur {
  position: absolute;
  right: 7px;
  bottom: 7px;
  padding: 2px 6px;
  border-radius: 6px;
  font-size: 10px;
  letter-spacing: 0.03em;
  color: #fff;
  background: rgba(14, 14, 16, 0.6);
}
.sc-thumb-title {
  display: block;
  margin-top: 9px;
  font-size: 12px;
  font-weight: 300;
  text-align: center;
}

@media (max-width: 760px) {
  .sc { padding-left: 16px; padding-right: 16px; --sc-maxh: min(66vh, 640px); }
  .sc-stage { border-radius: 14px; }
  .sc-bar { left: 8px; right: 8px; bottom: 8px; gap: 6px; padding: 5px 8px 5px 4px; }
  .sc-big { width: 68px; height: 68px; margin: -34px 0 0 -34px; }
  .sc-big svg { width: 28px; height: 28px; }
  .sc-time { font-size: 11px; }
  .sc-thumbs { gap: 10px; }
  .sc-thumb { width: 104px; }
}
@media (prefers-reduced-motion: reduce) {
  .sc-view, .sc-bar, .sc-big, .sc-thumb-frame { transition: none; }
}

/* ---------- Case page (Embro): brief, stats, reviews ---------- */
.offzone-intro .case-sub {
  margin-bottom: 18px;
  font-weight: 500;
  font-size: clamp(16px, 1.7vw, 22px);
  line-height: 1.4;
  color: #2c2c2e;
}

.case {
  max-width: 1280px;
  padding: 24px clamp(28px, 6vw, 96px) 120px;
}
.case .sc { padding: 0; }

/* goals / approach / tools / results — label on the left, text on the right */
.case-brief { border-top: 1px solid rgba(49, 49, 52, 0.14); max-width: 1000px; }
.case-row {
  display: grid;
  grid-template-columns: minmax(150px, 230px) 1fr;
  gap: 10px clamp(24px, 4vw, 56px);
  padding: 28px 0;
  border-bottom: 1px solid rgba(49, 49, 52, 0.14);
}
.case-row h3 {
  font-weight: 700;
  font-size: clamp(15px, 1.5vw, 19px);
  line-height: 1.5;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #2c2c2e;
}
.case-row p,
.case-list li {
  font-weight: 300;
  font-size: clamp(14px, 1.3vw, 17px);
  line-height: 1.7;
  color: #313134;
}
.case-row p { margin-bottom: 12px; }
.case-row p:last-child { margin-bottom: 0; }
.case-row b { font-weight: 400; }
.case-list { list-style: none; margin: 0; padding: 0; }
.case-list li { position: relative; padding-left: 28px; margin-bottom: 10px; }
.case-list li:last-child { margin-bottom: 0; }
.case-list li::before { content: "—"; position: absolute; left: 0; color: #8d8d92; }
.case-row--result .case-list li { font-size: clamp(16px, 1.7vw, 22px); }

.case-section { margin-top: clamp(64px, 9vw, 120px); }
.case-h2 {
  font-weight: 700;
  font-size: clamp(30px, 3.8vw, 50px);
  line-height: 1.15;
  letter-spacing: -0.005em;
  color: #2c2c2e;
  margin-bottom: 34px;
}
.case-h3 {
  font-weight: 700;
  font-size: clamp(15px, 1.5vw, 19px);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #2c2c2e;
  margin: 56px 0 20px;
}
.case-h3:first-of-type { margin-top: 0; }
.case-h4 {
  font-weight: 500;
  font-size: clamp(19px, 2vw, 26px);
  color: #2c2c2e;
  margin: 38px 0 18px;
}

/* screenshot tiles */
.case-tile { margin: 0; }
.case-zoom {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: 16px;
  overflow: hidden;
  background: #fff;
  cursor: zoom-in;
  box-shadow: 0 14px 30px -14px rgba(44, 44, 46, 0.4), 0 0 0 1px rgba(49, 49, 52, 0.07);
  transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.3s ease;
}
.case-zoom:hover,
.case-zoom:focus-visible {
  transform: translateY(-4px);
  box-shadow: 0 22px 38px -14px rgba(44, 44, 46, 0.45), 0 0 0 1px rgba(49, 49, 52, 0.1);
}
.case-zoom img { display: block; width: 100%; height: auto; }
.case-tile figcaption {
  margin-top: 12px;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.03em;
  color: #3f3f43;
}

.case-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(18px, 3vw, 40px);
  align-items: start;
  max-width: 920px;
}

/* the viral clip: its screenshot next to the headline numbers */
.case-feature {
  display: grid;
  grid-template-columns: minmax(240px, 400px) 1fr;
  gap: clamp(28px, 6vw, 90px);
  align-items: center;
}
.case-figures {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 30px 28px;
  margin: 0;
}
.case-fig dd {
  margin: 0;
  font-weight: 300;
  font-size: clamp(26px, 3.1vw, 46px);
  line-height: 1.05;
  white-space: nowrap;
  letter-spacing: -0.01em;
  color: #2c2c2e;
}
.case-fig dt {
  order: 2;
  margin-top: 8px;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #8d8d92;
}
.case-fig { display: flex; flex-direction: column; }
.case-fig:first-child { grid-column: 1 / -1; }
.case-fig:first-child dd { font-size: clamp(40px, 5.8vw, 86px); }

/* masonry: screenshots keep their own proportions */
.case-masonry { columns: 3 260px; column-gap: clamp(16px, 2vw, 26px); }
.case-masonry .case-tile { break-inside: avoid; margin-bottom: clamp(16px, 2vw, 26px); }
.case-masonry--reviews { columns: 4 220px; }


@media (max-width: 760px) {
  .case-row { grid-template-columns: 1fr; padding: 22px 0; }
  .case-pair { grid-template-columns: 1fr; }
  .case-feature { grid-template-columns: 1fr; }
  .case-masonry { columns: 2 140px; }
  .case-masonry--reviews { columns: 2 140px; }
}
@media (prefers-reduced-motion: reduce) {
  .case-zoom { transition: none; }
}

/* ---------- Lightbox (projects/lightbox.js) ---------- */
html.lb-lock { overflow: hidden; }
.lb {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  background: rgba(252, 252, 252, 0.95);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, visibility 0s linear 0.25s;
}
.lb.is-open { opacity: 1; visibility: visible; transition: opacity 0.25s ease; }
.lb-img {
  max-width: min(92vw, 1100px);
  max-height: 86vh;
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 30px 70px -20px rgba(44, 44, 46, 0.5), 0 0 0 1px rgba(49, 49, 52, 0.08);
  transform: scale(0.97);
  transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
  cursor: zoom-out;
}
.lb.is-open .lb-img { transform: scale(1); }
.lb-btn {
  position: absolute;
  top: 50%;
  width: 46px;
  height: 46px;
  margin-top: -23px;
  border: 0;
  border-radius: 50%;
  background: rgba(252, 252, 252, 0.95);
  box-shadow: 0 2px 14px rgba(44, 44, 46, 0.22);
  color: #313134;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
}
.lb-btn[hidden] { display: none; }
.lb-prev { left: clamp(10px, 2.5vw, 34px); }
.lb-next { right: clamp(10px, 2.5vw, 34px); }
.lb-close {
  position: absolute;
  top: 24px;
  right: 30px;
  width: 40px;
  height: 40px;
  border: 0;
  background: none;
  color: #313134;
  font-size: 28px;
  font-weight: 300;
  cursor: pointer;
}
.lb-close:hover { opacity: 0.55; }
.lb-count {
  position: absolute;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: #6b6b70;
}

/* portrait-only playlists (Embro): slim portrait thumbnails */
.sc-thumbs.is-tall { gap: 10px; }
.sc-thumbs.is-tall .sc-thumb { width: 62px; }
.sc-thumbs.is-tall .sc-thumb-frame { aspect-ratio: 9 / 14; border-radius: 9px; }
.sc-thumbs.is-tall .sc-thumb-play { left: 5px; bottom: 5px; width: 18px; height: 18px; }
.sc-thumbs.is-tall .sc-thumb-play svg { width: 8px; height: 8px; }
.sc-thumbs.is-tall .sc-thumb-dur { display: none; }

/* stat screenshots keep reading order (left to right), tops aligned */
.case-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(18px, 2.4vw, 32px) clamp(16px, 2vw, 26px);
  align-items: start;
}
@media (max-width: 760px) {
  .case-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  .case-grid { grid-template-columns: 1fr; }
}

/* ---------- Client logo: top right of a project's header ---------- */
.offzone-intro { position: relative; }
.client-logo {
  position: absolute;
  top: 100px;
  right: clamp(28px, 6vw, 96px);
  display: block;
  width: auto;
  height: auto;
  max-width: 230px;
  max-height: 60px;
  object-fit: contain;
  pointer-events: none;
  user-select: none;
}
.client-logo.is-square { max-width: 84px; max-height: 84px; }
/* keep a long title clear of the logo */
.offzone-intro.has-logo h1 { padding-right: min(290px, 26vw); }
@media (max-width: 760px) {
  .client-logo,
  .client-logo.is-square {
    position: static;
    margin: 0 0 20px;
    max-width: 150px;
    max-height: 44px;
  }
  .client-logo.is-square { max-width: 52px; max-height: 52px; }
  .offzone-intro.has-logo h1 { padding-right: 0; }
}

/* ---------- Portfolio folders: the client logo sits above the folder ---------- */
.folder-logo {
  position: absolute;
  left: 0;
  right: 0;
  top: -35px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.folder-logo img {
  display: block;
  width: auto;
  height: auto;
  max-width: 86px;
  max-height: 24px;
  object-fit: contain;
}
.folder-logo img.is-square { max-height: 28px; max-width: 28px; }
.project-title.is-long { font-size: 10px; letter-spacing: 0.06em; line-height: 1.35; }

/* a project with a single item: show it big instead of a lone thumbnail */
.offzone-space.is-single { grid-template-columns: minmax(0, 340px); justify-items: start; }
.offzone-space.is-single .floating-item { max-width: 340px; }
@media (max-width: 480px) {
  .offzone-space.is-single { grid-template-columns: minmax(0, 260px); }
  .offzone-space.is-single .floating-item { max-width: 260px; }
}

/* a project with only a few wide items (СБСЖ): bigger thumbnails, left-aligned */
.offzone-space.is-large {
  grid-template-columns: repeat(auto-fill, minmax(0, 250px));
  justify-content: start;
  justify-items: start;
  gap: clamp(24px, 4vw, 56px);
}
.offzone-space.is-large .floating-item { max-width: 250px; }
@media (max-width: 480px) {
  .offzone-space.is-large { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
