/* =========================================================================
   PŘÍBĚHY A SNY — full servis produkce
   Style: monopo-saigon cinematic editorial · primary BLACK · secondary RED
   ========================================================================= */

:root {
  /* --- Colors -------------------------------------------------------- */
  --color-ink-black: #000000;   /* primary surface */
  --color-carbon:    #0b0b0b;   /* raised dark surface */
  --color-carbon-2:  #141414;   /* card / hover surface */
  --color-paper:     #ffffff;   /* text on dark, light editorial */
  --color-ash:       #8a8a8a;   /* muted body / metadata */
  --color-ash-dim:   #5c5c5c;   /* tertiary */
  --color-hairline:  rgba(255,255,255,0.14);
  --color-hairline-strong: rgba(255,255,255,0.28);

  --color-red:        #E10600;  /* SECONDARY — full red */
  --color-red-bright: #ff2a1f;  /* hover / active */
  --color-red-deep:   #a30400;  /* red-on-red hairlines */
  --on-red-hairline:  rgba(255,255,255,0.30);

  /* --- Type ---------------------------------------------------------- */
  --font-display: 'Inter', ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-body:    'Inter', ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-alt:     'Raleway', var(--font-display);
  --font-mono:    'Space Mono', ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  --w-light: 300;
  --w-reg:   400;
  --w-semi:  600;

  /* fluid type scale */
  --text-hero:      clamp(3.75rem, 13.5vw, 12.5rem);  /* 60 -> 200px */
  --text-display:   clamp(2.75rem, 7vw, 5.875rem);    /* 44 -> 94px */
  --text-heading:   clamp(2rem, 4.6vw, 3.375rem);     /* 32 -> 54px */
  --text-heading-sm:clamp(1.6rem, 3vw, 2.4rem);
  --text-sub:       clamp(1.25rem, 2vw, 1.875rem);
  --text-body-lg:   1.125rem;                          /* 18 */
  --text-body:      1rem;                               /* 16 */
  --text-label:     0.75rem;                            /* 12 */
  --text-micro:     0.6875rem;                          /* 11 */

  /* --- Space / shape -------------------------------------------------- */
  --page-max: 1440px;
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --section-pad: clamp(5rem, 11vw, 9.5rem);
  --radius-pill: 75px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* --- Reset-ish ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}

body {
  margin: 0;
  background: var(--color-ink-black);
  color: var(--color-paper);
  font-family: var(--font-body);
  font-weight: var(--w-reg);
  font-size: var(--text-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; background: none; border: none; }

::selection { background: var(--color-red); color: #fff; }

:focus-visible {
  outline: 2px solid var(--color-red-bright);
  outline-offset: 3px;
}

.shell { max-width: var(--page-max); margin-inline: auto; padding-inline: var(--gutter); }

/* keyboard-only escape hatch past the nav */
.skip {
  position: fixed; top: 8px; left: 8px; z-index: 400;
  transform: translateY(-160%);
  padding: 10px 20px; border-radius: var(--radius-pill);
  background: var(--color-red); color: #fff;
  font-size: var(--text-label); letter-spacing: 0.12em; text-transform: uppercase;
  transition: transform 0.25s var(--ease);
}
.skip:focus-visible { transform: none; }

.mono {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* utility: hide the currently inactive language spans */
[data-cz][data-en] { }

/* =========================================================================
   NAV
   ========================================================================= */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: clamp(1rem, 2vw, 1.6rem) var(--gutter);
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease);
  border-bottom: 1px solid transparent;
}
.nav.is-solid { border-bottom: 1px solid var(--color-hairline); }
/* blur lives on a pseudo-element, not .nav itself — backdrop-filter on a real
   ancestor makes it the containing block for position:fixed descendants, which
   broke .nav__menu's fullscreen mobile overlay (it collapsed to the header's own
   small box instead of the viewport once .is-solid kicked in after any scroll) */
.nav::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: rgba(6,6,6,0.82);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
}
.nav.is-solid::before { opacity: 1; }
.nav__brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-display);
  font-weight: var(--w-semi);
  font-size: var(--text-label);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  white-space: nowrap;
}
.nav__brand .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--color-red);
  box-shadow: 0 0 0 0 rgba(225,6,0,0.6);
  animation: recpulse 1.8s infinite;
}
/* motion.css owns the big reduced-motion block, but this dot is style.css-only and was the one
   thing sitewide that kept animating regardless of that OS setting */
@media (prefers-reduced-motion: reduce) {
  .nav__brand .dot { animation: none; }
}
.nav__right { display: flex; align-items: center; gap: clamp(1rem, 2.4vw, 2.2rem); }
.nav__menu { display: flex; gap: clamp(1rem, 2vw, 1.8rem); }
.nav__menu a {
  font-size: var(--text-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-paper);
  opacity: 0.82;
  position: relative;
  padding-block: 4px;
  transition: opacity 0.25s var(--ease);
}
.nav__menu a::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: var(--color-red);
  transform: scaleX(0); transform-origin: left; transition: transform 0.35s var(--ease);
}
.nav__menu a:hover { opacity: 1; }
.nav__menu a:hover::after { transform: scaleX(1); }

/* language toggle */
.lang {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--color-hairline-strong);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.lang button {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.1em;
  padding: 5px 11px;
  color: var(--color-ash);
  transition: color 0.2s var(--ease), background 0.2s var(--ease);
}
.lang button.is-active { color: #fff; background: var(--color-red); }

/* burger — 44x44 tap zone (only ever shown ≤760px); bars stay the original 30x18 icon, centered */
.burger { display: none; width: 44px; height: 44px; position: relative; }
.burger span { position: absolute; left: 50%; width: 30px; margin-left: -15px; height: 1.5px; background: #fff; transition: transform 0.35s var(--ease), opacity 0.2s; }
.burger span:nth-child(1) { top: 13px; }
.burger span:nth-child(2) { top: 21px; }
.burger span:nth-child(3) { top: 29px; }
body.menu-open .burger span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
body.menu-open .burger span:nth-child(2) { opacity: 0; }
body.menu-open .burger span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* =========================================================================
   HERO — cinematic viewfinder
   ========================================================================= */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 8rem var(--gutter) 5rem;
  /* transparent — the fixed .bg-canvas smoke shows through and continues below */
  background: transparent;
}
/* viewfinder frame — the signature */
.viewfinder { position: absolute; inset: clamp(1rem,3vw,2.2rem); pointer-events: none; z-index: 3; }
.viewfinder .reticle { position: absolute; top: 50%; left: 50%; width: 26px; height: 26px; transform: translate(-50%,-50%); opacity: 0.5; }
.viewfinder .reticle::before, .viewfinder .reticle::after { content: ""; position: absolute; background: var(--on-red-hairline); }
.viewfinder .reticle::before { left: 50%; top: 0; width: 1px; height: 100%; transform: translateX(-0.5px); }
.viewfinder .reticle::after { top: 50%; left: 0; height: 1px; width: 100%; transform: translateY(-0.5px); }

.hero__inner { position: relative; z-index: 4; width: 100%; max-width: var(--page-max); margin-inline: auto; }
.hero__eyebrow {
  color: var(--color-red);
  margin-bottom: clamp(2.2rem, 4vw, 3.2rem);
  display: flex; align-items: center; gap: 0.9rem;
}
.hero__eyebrow::before { content: ""; width: clamp(28px,4vw,56px); height: 1px; background: var(--color-red); display: inline-block; }
.hero__title {
  font-family: var(--font-display);
  font-weight: var(--w-light);
  font-size: var(--text-hero);
  line-height: 0.82;
  letter-spacing: -0.02em;
  margin: 0;
  text-transform: uppercase;
}
.hero__title .amp {
  font-family: var(--font-alt);
  font-style: italic;
  font-weight: var(--w-reg);
  color: var(--color-red);
  text-transform: none;
}
.hero__lead {
  margin-top: clamp(1.6rem, 3vw, 2.6rem);
  max-width: 40ch;
  font-size: var(--text-body-lg);
  line-height: 1.55;
  color: var(--color-ash);
}
.hero__lead strong { color: var(--color-paper); font-weight: var(--w-semi); }
.hero__cta { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-top: clamp(1.8rem, 3vw, 2.6rem); }

/* =========================================================================
   SECTION scaffolding
   ========================================================================= */
.section { padding-block: var(--section-pad); }
/* osoba.html stacks 5-6 short sections in one profile (unlike a project page's few, deliberately
   spacious blocks) — full --section-pad on every one of them reads as a wall of empty space.
   Same value on every section keeps the gap between any two of them equal by construction. */
.section--tight { padding-block: clamp(2.5rem, 4vw, 3.5rem); }
/* translucent carbon layer over the fixed smoke — shared by Projekty / Klienti / Galerie */
.section--glass { position: relative; overflow: hidden; }
.section--glass > .shell { position: relative; z-index: 2; }
.section__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem; flex-wrap: wrap; margin-bottom: clamp(2.5rem, 5vw, 4.5rem); }
.section__index { color: var(--color-red); }
.section__title {
  font-family: var(--font-display);
  font-weight: var(--w-light);
  font-size: var(--text-display);
  /* >=1.06 so Czech carons/acutes (Ř Í Ě Ů) clear the line above */
  line-height: 1.06;
  letter-spacing: -0.015em;
  margin: 0.4rem 0 0;
  text-transform: uppercase;
}
/* right-hand side of a section head: sits on the title's baseline, not below it */
.section__note { color: var(--color-ash); padding-bottom: 0.6rem; text-align: right; margin: 0; }
.section__lead { margin: 0 0 0.4rem; max-width: 34ch; text-align: right; color: var(--color-ash); font-size: var(--text-body-lg); line-height: 1.55; }
.eyebrow { color: var(--color-red); display: inline-flex; align-items: center; gap: 0.7rem; }
.eyebrow::before { content: ""; width: 26px; height: 1px; background: currentColor; }

/* --- About / manifesto --------------------------------------------- */
.about { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(2rem, 6vw, 6rem); align-items: start; }
.about__lead {
  font-family: var(--font-display);
  font-weight: var(--w-light);
  font-size: var(--text-heading);
  line-height: 1.14;
  letter-spacing: -0.01em;
  margin: 0;
}
.about__lead b { font-weight: var(--w-light); color: var(--color-red); }
.about__body { color: var(--color-ash); font-size: var(--text-body-lg); line-height: 1.65; }
.about__body p + p { margin-top: 1.1rem; }

/* =========================================================================
   PROJEKTY — glass tiles over the fixed smoke (background lives in motion.css)
   ========================================================================= */
.projekty { color: #fff; }

.grid {
  display: grid;
  /* minmax(0,1fr) not plain 1fr: a bare 1fr track's automatic minimum is its content's
     min-content width, so an unwrapping element (the .pill CTA's one-line label) was flooring
     the column wider than the track and blowing the grid out past the viewport at 2-up phone
     widths — overflow-x:hidden on body hid the scrollbar but the card was still clipped. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.4rem, 2.4vw, 2.4rem);
}
/* a 2-person roster (osobni-brand's #p-people) shouldn't stretch across the same 4-column grid
   the homepage's 8-tile projects grid uses — capped and centered so it reads as a deliberate
   small pair, not two cards lost in a wide row */
.grid--people { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 640px; margin-inline: auto; }
/* Spotify track embeds on a person page — same 3-across rhythm as .gallery's wide tiles,
   stacking to 1 column on mobile since the embed iframe has a fixed 352px min-height. */
.music-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem; }
.music-grid iframe { width: 100%; border-radius: 12px; display: block; }
@media (max-width: 780px) { .music-grid { grid-template-columns: 1fr; } }

/* --- Reels 3D carousel (osoba.html) ----------------------------------- */
/* Full-bleed on purpose (outside .shell) — a coverflow ring needs runway on both sides for
   cards to swing into as they rotate; capping it to the shell's max-width would clip them.
   Geometry (radius, per-card rotateY/translateZ/scale/opacity) is computed and applied every
   frame by reel-carousel.js; this stylesheet only owns static sizing and the 3D stage setup. */
.reel-ring {
  position: relative; width: 100%; overflow: hidden;
  height: clamp(230px, 27vw, 360px);
  perspective: 1600px;
  cursor: grab;
  touch-action: pan-y;
}
.reel-ring:active { cursor: grabbing; }
.reel-ring__stage { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; }
.reel-card {
  position: absolute; top: 50%; left: 50%;
  width: clamp(130px, 15vw, 200px); aspect-ratio: 9/16;
  will-change: transform, opacity;
}
.reel-card .vfig { width: 100%; height: 100%; aspect-ratio: auto; border-radius: 10px; }
.reel-views { text-align: center; margin-top: clamp(2rem, 4vw, 3rem); }
.reel-views__num {
  display: block; font-family: var(--font-display); font-weight: var(--w-light);
  font-size: var(--text-display); color: #fff; font-variant-numeric: tabular-nums; line-height: 1;
}
.reel-views__label { display: block; margin-top: 0.6rem; color: var(--color-red); letter-spacing: 0.14em; text-transform: uppercase; }
/* .reveal (scroll entrance) and [data-tilt] (hover) both drive `transform`.
   Sharing one element let the reveal's 0.9s transition + per-card delay eat the
   tilt entirely on data-d="2"/"3". The wrapper owns the entrance, .card owns the tilt. */
.card-wrap { display: flex; min-width: 0; }
/* min-width:0 — a flex item's automatic minimum is otherwise its content's min-content width
   (same rule as bare `1fr` grid tracks), and the .pill CTA's one-line label was flooring it;
   at 2-up phone widths that pushed the card past its own grid cell into the next column. */
.card, .card--cta { flex: 1; min-width: 0; }
.card { display: flex; flex-direction: column; text-align: center; }
.card__media {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: rgba(255,255,255,0.04);
  border-radius: 12px;
}
.card__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 0.7s var(--ease), filter 0.5s var(--ease), opacity 0.6s var(--ease);
}
.card:hover .card__media img { transform: scale(1.06); }
/* new-tab affordance, lives on the media so it survives the tilt layer */
.card__ext {
  position: absolute; z-index: 3; top: 10px; right: 10px;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 13px; line-height: 1; color: #fff;
  background: rgba(0,0,0,0.5); border: 1px solid var(--color-hairline);
  opacity: 0; transform: translateY(-4px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), background 0.3s var(--ease);
}
.card:hover .card__ext, .card__media:focus-visible .card__ext { opacity: 1; transform: none; background: var(--color-red); }
.card__title {
  font-family: var(--font-display); font-weight: var(--w-semi);
  font-size: 1.35rem; letter-spacing: 0.02em; text-transform: uppercase;
  margin: clamp(1.1rem,2vw,1.6rem) 0 0.6rem;
}
.card__sub { color: var(--color-ash); font-size: var(--text-body); line-height: 1.45; min-height: 2.9em; margin: 0 auto 1.3rem; max-width: 26ch; }
.card__cta { margin-top: auto; }
/* explicit width, not the pill's default content-hugging inline-flex: at 2-up phone widths the
   card column (~130px) is narrower than the label's unwrapping min-content width (~165px), and
   an intrinsic width doesn't shrink for that — an explicit one does, same fix as the grid track
   and card-wrap min-width above, one layer deeper. Padding scales down with clamp so the label
   still has room to breathe instead of just clipping. */
.card__cta .pill { display: flex; width: 100%; justify-content: center; padding-inline: clamp(0.9rem, 5vw, 1.875rem); }

/* 8th cell: 7 projects would leave an orphan hole in a 4-col grid — make it a CTA */
/* padding + glass surface come from the shared .card rule in motion.css */
.card--cta {
  display: grid; place-items: center; gap: 0.9rem; text-align: center;
  min-height: 220px; align-content: center;
}
.card--cta .card__title { margin: 0; }
.card--cta__sub { color: var(--color-ash); font-size: var(--text-body); margin: 0; max-width: 22ch; }
.card--cta__arrow {
  width: 54px; height: 54px; border-radius: 50%;
  display: grid; place-items: center; font-size: 1.4rem;
  border: 1px solid var(--color-red); color: var(--color-red);
  transition: background 0.35s var(--ease), color 0.35s var(--ease), transform 0.35s var(--ease);
}
.card--cta:hover .card--cta__arrow { background: var(--color-red); color: #fff; transform: translate(3px, -3px); }

/* pill button */
.pill {
  display: inline-flex; align-items: center; gap: 0.6rem;
  font-family: var(--font-display); font-weight: var(--w-semi);
  font-size: var(--text-label); letter-spacing: 0.16em; text-transform: uppercase;
  padding: 13px 30px;
  border-radius: var(--radius-pill);
  transition: transform 0.3s var(--ease), background 0.3s var(--ease), color 0.3s var(--ease);
}
.pill--red { background: var(--color-red); color: #fff; }
.pill--red:hover { background: var(--color-red-bright); transform: translateY(-2px); }
.pill--ghost { border: 1px solid var(--color-hairline-strong); color: #fff; }
.pill--ghost:hover { border-color: var(--color-red); color: var(--color-red); }
.pill .arr { transition: transform 0.3s var(--ease); }
.pill:hover .arr { transform: translateX(4px); }

/* =========================================================================
   CONTACT + FOOTER
   ========================================================================= */
.contact {
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, rgba(0,0,0,0.55), rgba(0,0,0,0.85));
}
.contact .shell { position: relative; z-index: 2; }
.contact__grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 6vw, 5rem); align-items: center; }
.contact__title {
  font-family: var(--font-display); font-weight: var(--w-light);
  font-size: var(--text-display);
  /* 1.0 made the carons of "PŘÍBĚH?" collide with the line above it */
  line-height: 1.08;
  letter-spacing: -0.02em; text-transform: uppercase; margin: 0.6rem 0 0;
}
.contact__pitch { color: var(--color-ash); font-size: var(--text-body-lg); margin: 1.2rem 0 0; max-width: 34ch; }
.contact__mail {
  display: inline-block; margin-top: 1.6rem; font-size: var(--text-sub); letter-spacing: -0.01em;
  background-image: linear-gradient(var(--color-red), var(--color-red));
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  transition: background-size 0.4s var(--ease), color 0.3s var(--ease);
}
.contact__mail:hover { color: var(--color-red); background-size: 100% 1px; }
.contact__list { display: grid; gap: 1.1rem; }
.contact__row { display: flex; justify-content: space-between; gap: 1rem; padding-bottom: 1.1rem; border-bottom: 1px solid var(--color-hairline); }
.contact__row .k { font-family: var(--font-mono); font-size: var(--text-micro); letter-spacing: 0.14em; color: var(--color-ash); text-transform: uppercase; }
.contact__row .v { text-align: right; }
.contact__row .v a:hover { color: var(--color-red); }

.footer { background: var(--color-carbon); padding: clamp(2.5rem,5vw,3.5rem) 0; border-top: 1px solid var(--color-hairline); }
.footer__grid { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
.footer__brand { font-family: var(--font-display); font-weight: var(--w-semi); letter-spacing: 0.3em; text-transform: uppercase; font-size: var(--text-label); }
.footer__meta { font-family: var(--font-mono); font-size: var(--text-micro); letter-spacing: 0.12em; color: var(--color-ash-dim); }
.footer__legal { margin-top: clamp(1.4rem,3vw,2rem); padding-top: clamp(1.4rem,3vw,2rem); border-top: 1px solid var(--color-hairline); }
.footer__legal p { font-family: var(--font-mono); font-size: var(--text-micro); letter-spacing: 0.04em; color: var(--color-ash-dim); line-height: 1.7; max-width: 68ch; }

/* =========================================================================
   PROJECT DETAIL PAGE
   ========================================================================= */
.detail-hero {
  position: relative;
  min-height: 88svh;
  display: flex;
  align-items: flex-end;
  padding: 7rem var(--gutter) clamp(2.5rem,5vw,4rem);
  overflow: hidden;
}
.detail-hero__bg { position: absolute; inset: 0; z-index: 0; }
.detail-hero__bg img { width: 100%; height: 100%; object-fit: cover; }
.detail-hero__bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.35) 30%, rgba(0,0,0,0.55) 60%, rgba(0,0,0,0.95) 100%); }
.detail-hero__inner { position: relative; z-index: 2; width: 100%; max-width: var(--page-max); margin-inline: auto; }
.detail-hero__cat { color: var(--color-red); margin-bottom: 1rem; }
.detail-hero__title {
  font-family: var(--font-display); font-weight: var(--w-light);
  font-size: var(--text-display); line-height: 0.98; letter-spacing: -0.02em; text-transform: uppercase; margin: 0; max-width: 16ch;
}
.detail-hero__sub { margin-top: 1.2rem; color: var(--color-ash); font-size: var(--text-body-lg); max-width: 46ch; }

.detail-meta { border-top: 1px solid var(--color-hairline); border-bottom: 1px solid var(--color-hairline); }
.detail-meta__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem; padding-block: clamp(1.6rem,3vw,2.4rem); }
.detail-meta__cell .k { font-family: var(--font-mono); font-size: var(--text-micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-red); display: block; margin-bottom: 0.5rem; }
.detail-meta__cell .v { font-size: var(--text-body-lg); }

/* --- Project films --------------------------------------------------- */
/* Self-hosted <video> in our own chrome. No embed frame, no third-party player furniture —
   the film is a block of the page that happens to move. */
.vstage { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(0.8rem,1.6vw,1.4rem); }
/* person pages (osoba.html) — no "lead" clip, all clips render the same size, 3-across */
.vstage--trio { grid-template-columns: repeat(3, 1fr); }
.vfig {
  position: relative; margin: 0; overflow: hidden;
  aspect-ratio: 16/9; border-radius: 12px; background: #000;
}
/* The lead film is always full width. An even clip count leaves the last one orphaned in the
   2-col grid (2 and 4 clips both do) — give it the full row instead of a hole beside it.
   Scoped to DIRECT children of .vstage: unscoped, this also matched the 4th tile inside
   .vshorts (also an even-count last-child) and doubled it into a second row. */
.vstage > .vfig--lead, .vstage > .vfig:last-child:nth-child(even) { grid-column: span 2; }
.vfig__el { width: 100%; height: 100%; object-fit: cover; display: block; }

/* A row of vertical (Shorts-format) clips, e.g. Laphont's 4 micro-world spots. It sits as one
   item inside .vstage, so it needs its own full-row span — same reasoning as .vfig--lead. Each
   tile keeps its real 9:16 box (set inline from data) rather than being cropped into 16:9. */
.vshorts { grid-column: span 2; display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(0.8rem,1.6vw,1.4rem); }

/* Ramps late and hard rather than fading from halfway: the control bar only needs the bottom
   ~20%, and a shallow gradient greys out the middle of the frame without ever making the band
   under the mono labels dark enough to read against. */
.vfig__scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,0) 58%, rgba(0,0,0,0.55) 80%, rgba(0,0,0,0.94) 100%);
  opacity: 0; transition: opacity 0.4s var(--ease);
}
.vfig:hover .vfig__scrim, .vfig:focus-within .vfig__scrim, .vfig.is-live .vfig__scrim { opacity: 1; }

.vfig__hit { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; }
.vfig__play {
  width: clamp(54px, 6vw, 78px); aspect-ratio: 1; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--color-red); color: #fff; font-size: 1.3rem;
  padding-left: 4px;                    /* ▶ has no left bearing — nudge it onto the optical centre */
  box-shadow: 0 10px 40px rgba(0,0,0,0.5);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), background 0.3s var(--ease);
}
.vfig__hit:hover .vfig__play { transform: scale(1.08); background: var(--color-red-bright); }
/* Once the muted loop is running the button would only be in the way; hovering reveals the bar,
   whose SOUND control is the real affordance from here on. */
.vfig.is-playing .vfig__play { opacity: 0; transform: scale(0.8); }
/* play() got rejected (autoplay policy / Low Power Mode) — without this the button just sits
   there looking untouched, so a real failure and "haven't tapped it yet" were indistinguishable.
   Reuses the nav dot's own pulse keyframe rather than adding a new one; runs twice then stops
   since the button itself is already the retry target — no need to nag forever. */
.vfig.is-blocked .vfig__play { animation: recpulse 1.4s ease-out 2; }

.vfig__ui {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.5rem 0.9rem; padding: clamp(0.8rem, 2vw, 1.3rem);
  opacity: 0; transition: opacity 0.35s var(--ease);
  /* gaps must fall through to the play/sound hit area behind — only the controls take clicks */
  pointer-events: none;
}
.vfig__ui > * { pointer-events: auto; }
.vfig:hover .vfig__ui, .vfig:focus-within .vfig__ui, .vfig.is-live .vfig__ui { opacity: 1; }
.vfig__label { flex: 1 0 100%; color: #fff; }
.vfig__tc { color: var(--color-ash); font-variant-numeric: tabular-nums; }
/* negative margin cancels the padding visually — grows the tap target without shifting the row */
.vfig__sound { color: #fff; opacity: 0.7; padding: 10px 6px; margin: -10px -6px; transition: opacity 0.25s var(--ease), color 0.25s var(--ease); }
.vfig__sound:hover, .vfig__sound[aria-pressed="true"] { opacity: 1; color: var(--color-red); }

.vfig__seek {
  -webkit-appearance: none; appearance: none;
  flex: 1 1 120px; min-width: 0; height: 24px; background: transparent; cursor: pointer;
}
.vfig__seek::-webkit-slider-runnable-track { height: 2px; background: rgba(255,255,255,0.28); border-radius: 2px; }
.vfig__seek::-moz-range-track            { height: 2px; background: rgba(255,255,255,0.28); border-radius: 2px; }
.vfig__seek::-webkit-slider-thumb {
  -webkit-appearance: none; width: 15px; height: 15px; margin-top: -6.5px;
  border-radius: 50%; background: var(--color-red);
}
.vfig__seek::-moz-range-thumb { width: 15px; height: 15px; border: 0; border-radius: 50%; background: var(--color-red); }

.detail-body { display: grid; grid-template-columns: minmax(0,4.5rem) 1fr; gap: clamp(1rem,3vw,2.5rem); }
.detail-body__label { font-family: var(--font-mono); font-size: var(--text-micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-red); padding-top: 0.5rem; }
.detail-body__text { font-family: var(--font-display); font-weight: var(--w-light); font-size: var(--text-heading-sm); line-height: 1.3; letter-spacing: -0.01em; max-width: 24ch; }
.detail-body__text p + p { margin-top: 1.2rem; }
/* opt-in per project (data.js wideBody:true) — same 24ch column reads too tall/vertical when the
   body copy runs long, so this lets it use the shell's full width instead. */
.detail-body__text--wide { max-width: none; }

/* opt-in per project (data.js crewInline:true, currently just Laphont) — puts Štáb beside O
   realizaci instead of in its own stacked section further down the page. Plain block by default
   (--split added by JS only when there's an inline crew to show) so every other project's body
   copy still gets the full shell width instead of losing half of it to an empty grid track. */
.detail-body-row--split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem,4vw,3rem); align-items: start; }
@media (max-width: 900px) {
  .detail-body-row--split { grid-template-columns: 1fr; }
}
/* person-page bio (osoba.html's #p-bio, unique id — projekt.html's body copy uses #p-body) —
   full prose paragraphs read too tall in the 24ch/heading-size treatment above, so this runs
   smaller body copy across the full shell width instead. */
#p-bio .detail-body__text {
  max-width: none;
  font-family: var(--font-body);
  font-weight: var(--w-reg);
  font-size: var(--text-body-lg);
  line-height: 1.7;
}

/* 8 not 6 columns: g-wide/g-tall/g-half keep their old span counts, so against a wider grid
   each tile reads ~25% smaller and packs tighter — reads as "more photos" without adding any.
   8 (not 9) matters: with the real wide(4)+tall(2)+tall(2) / tall×4 sequences used across the
   project galleries, 8 divides those combos with no leftover column; 9 left a visible gap at
   the end of almost every row. g-full stays a true full-bleed row (span = total), untouched. */
.gallery { display: grid; grid-template-columns: repeat(8, 1fr); gap: clamp(0.6rem,1.2vw,1rem); }
.gallery figure { margin: 0; overflow: hidden; background: var(--color-carbon-2); border-radius: 12px; position: relative; }
.gallery figure img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.7s var(--ease); }
.gallery button {
  display: block; width: 100%; height: 100%; padding: 0; cursor: zoom-in;
  border-radius: inherit; overflow: hidden;
}
.gallery figure:hover img { transform: scale(1.05); }
.gallery figure::after {
  content: "⤢"; position: absolute; z-index: 2; right: 12px; bottom: 12px;
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  font-size: 14px; color: #fff; background: rgba(0,0,0,0.55);
  border: 1px solid var(--color-hairline); pointer-events: none;
  opacity: 0; transform: translateY(6px); transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.gallery figure:hover::after { opacity: 1; transform: none; }
.gallery .g-wide { grid-column: span 4; aspect-ratio: 16/9; }
.gallery .g-tall { grid-column: span 2; aspect-ratio: 3/4; }
/* span 2, not 3: 4 half-tiles now tile a row with zero remainder (2/8 x4=8) instead of 2 tiles
   leaving a quarter-row of dead space (3/8 x2=6/8) — denser packing was the whole point. */
.gallery .g-half { grid-column: span 2; aspect-ratio: 4/3; }
.gallery .g-full { grid-column: span 8; aspect-ratio: 21/9; }

/* Category heading for a multi-category gallery (Foto's hudba/automotive/lifestyle/politika
   split). Lives INSIDE the same .gallery grid as a full-width row rather than starting a new
   grid per category — that keeps the lightbox's single `.gallery` query and its index math
   (projekt.js numbers `data-lb-open` by gallery-item position, headings don't get one) correct
   for free. Projects with no `category` on their gallery items never render one of these. */
.gallery-group__label {
  grid-column: 1 / -1; margin: 0; padding-top: clamp(1.4rem, 2.4vw, 2.2rem);
  font-family: var(--font-mono); font-size: var(--text-micro);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-red);
}
.gallery-group__label:first-child { padding-top: 0; }

/* A video tile's poster looks identical to a photo at rest — the "⤢" zoom cue only earns its
   keep on hover because a photo needs no other explanation. A video does: it gets a permanent
   play badge instead (same red-circle language as .vfig__play), visible before you ever hover,
   because "this one plays" has to read at a glance across a grid of otherwise-static stills. */
.gallery figure.gallery__item--video::after { display: none; }
.gallery__play {
  position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; pointer-events: none;
}
.gallery__play::before {
  content: "▶"; width: clamp(46px, 5vw, 64px); aspect-ratio: 1; border-radius: 50%;
  display: grid; place-items: center; padding-left: 3px;
  background: var(--color-red); color: #fff; font-size: 1rem;
  box-shadow: 0 8px 30px rgba(0,0,0,0.5);
  transition: background 0.3s var(--ease), transform 0.3s var(--ease);
}
.gallery figure.gallery__item--video:hover .gallery__play::before { background: var(--color-red-bright); transform: scale(1.08); }

/* =========================================================================
   LIGHTBOX
   ========================================================================= */
.lb {
  position: fixed; inset: 0; z-index: 500; display: none;
  place-items: center; padding: clamp(1rem, 4vw, 3rem);
  background: rgba(0,0,0,0.9);
  backdrop-filter: blur(18px) saturate(1.2); -webkit-backdrop-filter: blur(18px) saturate(1.2);
  opacity: 0; transition: opacity 0.3s var(--ease);
}
.lb.is-open { display: grid; }
.lb.is-shown { opacity: 1; }
body.lb-open { overflow: hidden; }
.lb__img, .lb__video {
  max-width: min(100%, 1280px); max-height: 82svh; width: auto; height: auto;
  object-fit: contain; border-radius: 8px;
  transform: scale(0.97); transition: transform 0.35s var(--ease);
}
.lb.is-shown .lb__img, .lb.is-shown .lb__video { transform: none; }
.lb.is-dragging .lb__img, .lb.is-dragging .lb__video { transition: none; }
.lb__bar {
  position: absolute; left: 0; right: 0; bottom: clamp(1rem, 3vw, 2rem);
  display: flex; align-items: center; justify-content: center; gap: 1.2rem;
  font-family: var(--font-mono); font-size: var(--text-micro); letter-spacing: 0.16em; color: var(--color-ash);
}
.lb__btn {
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center; font-size: 1.1rem; color: #fff;
  border: 1px solid var(--color-hairline-strong); background: rgba(0,0,0,0.4);
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.lb__btn:hover { background: var(--color-red); border-color: var(--color-red); transform: scale(1.08); }
.lb__close { position: absolute; top: clamp(1rem,3vw,2rem); right: clamp(1rem,3vw,2rem); }
.lb__count { min-width: 5ch; text-align: center; }

.detail-next { border-top: 1px solid var(--color-hairline); display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
.detail-next__link { text-align: right; }
.detail-next__label { font-family: var(--font-mono); font-size: var(--text-micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-ash); }
.detail-next__title { font-family: var(--font-display); font-weight: var(--w-light); font-size: var(--text-heading); text-transform: uppercase; letter-spacing: -0.015em; margin-top: 0.4rem; transition: color 0.3s var(--ease); }
.detail-next a:hover .detail-next__title { color: var(--color-red); }

/* reveal-on-scroll */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity 0.8s var(--ease), transform 0.8s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }

@keyframes recpulse {
  0%   { box-shadow: 0 0 0 0 rgba(225,6,0,0.55); opacity: 1; }
  70%  { box-shadow: 0 0 0 10px rgba(225,6,0,0); opacity: 0.5; }
  100% { box-shadow: 0 0 0 0 rgba(225,6,0,0); opacity: 1; }
}

/* =========================================================================
   RESPONSIVE
   ========================================================================= */
@media (max-width: 1080px) {
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .about { grid-template-columns: 1fr; }
  .detail-meta__grid { grid-template-columns: repeat(2, 1fr); }
  .gallery .g-wide { grid-column: span 8; }
  .gallery .g-tall { grid-column: span 4; }
  .section__note, .section__lead { text-align: left; }
}

/* No hover to reveal the bar, so it lives on screen — and one clip per row keeps the mono
   controls above the size where they collapse into each other. */
@media (hover: none) {
  .vfig__ui { opacity: 1; }
}
@media (max-width: 760px) {
  .vstage { grid-template-columns: 1fr; }
  .vstage--trio { grid-template-columns: 1fr; }
  .vstage > .vfig--lead, .vstage > .vfig:last-child:nth-child(even) { grid-column: span 1; }
  .vshorts { grid-column: span 1; grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 760px) {
  .burger { display: block; z-index: 120; }
  /* desktop's 5px pad reads fine at mouse precision; bumped only here where fingers do the tapping */
  .lang button { padding: 11px 12px; }
  .nav__brand { letter-spacing: 0.2em; gap: 0.4rem; }
  .nav__menu {
    position: fixed; inset: 0;
    flex-direction: column; align-items: center; justify-content: center;
    gap: 1.8rem;
    /* no backdrop-filter: at 97% opaque the blur underneath was doing almost nothing visually,
       but re-sampling it every frame of the transform transition (right on top of the WebGL
       canvas still rendering behind it) was real cost the rollout could ill afford. */
    background: rgba(6,6,6,0.97);
    transform: translateY(-100%); transition: transform 0.5s var(--ease), visibility 0.5s;
    z-index: 110;
    /* closed menu must not stay in the tab order while parked off-screen */
    visibility: hidden;
  }
  body.menu-open .nav__menu { transform: none; visibility: visible; }
  .nav__menu a { font-size: 1.4rem; opacity: 1; }
  body.menu-open { overflow: hidden; }
  .contact__grid { grid-template-columns: 1fr; align-items: start; }
  .detail-body { grid-template-columns: 1fr; }
  .detail-body__label { padding-top: 0; }
  .gallery { grid-template-columns: 1fr; }
  .gallery .g-wide, .gallery .g-tall, .gallery .g-half, .gallery .g-full { grid-column: 1 / -1; aspect-ratio: 4/3; }
  .lb__bar { gap: 0.8rem; }
}

@media (max-width: 460px) {
  /* stays 2-up even at phone width — same call as .logos, shorter page beats one-per-row */
  .grid--people { grid-template-columns: 1fr; }
  .card__media { aspect-ratio: 4/3; }
  .hero__cta { gap: 0.6rem; }
  .hero__cta .pill { padding: 12px 22px; }
}
