/* ==========================================================================
   Textura Media — Vesper design system (scrolling inner pages)
   Base #000000 · indigo #1A152F surfaces · pink #CE2E4F accents
   The landing page (index.html) carries its own inline copy of these tokens
   because it is specified as a single self-contained file.
   ========================================================================== */

html, body { background: #000000 !important; color: #ffffff; }

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

:root {
  --bg: #000000;
  --text: #ffffff;
  --muted: #9a9a9a;
  --stat: #d8d8d8;
  --border: rgba(255, 255, 255, 0.16);
  --border-soft: rgba(255, 255, 255, 0.12);

  /* "textura" — tactile grain. Two tiling noise fields: a fine filmic one for
     the global overlay, a coarser weave that gives flat surfaces a material feel. */
  --noise-fine: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  --noise-weave: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.6' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23w)' opacity='0.55'/%3E%3C/svg%3E");
  --edge: max(var(--gutter), calc((100% - var(--container)) / 2 + var(--gutter)));

  /* brand palette — see contrast notes in index.html */
  --indigo: #1A152F;          /* still drives the shader palette */
  --indigo-lift: #2A2246;
  /* Panels are translucent near-black so the moving field reads straight
     through them. Opaque indigo slabs fought the shader for the same hue. */
  --surface: rgba(9, 7, 16, 0.66);
  --surface-lift: rgba(30, 24, 52, 0.74);
  --pink: #CE2E4F;          /* fills, buttons, borders, glows */
  --pink-hover: #B82744;    /* white button text holds 6.16:1 */
  --pink-text: #F26A85;     /* accent text: 7.18:1 black / 6.02:1 indigo / 5.07:1 card-hover */

  --logo-h: 34px;
  --nav: 14px;
  --nav-h: 40px;
  --btn: 13.5px;
  --btn-h: 40px;
  --header-y: 18px;
  --header-x: 40px;

  --h1: 52px;
  --h2: 40px;
  --lede: 15.5px;
  --gutter: clamp(20px, 5vw, 40px);
  --header-h: 80px;           /* measured at runtime; this is the fallback */
  --container: 1240px;

  --ui: "Akt", "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --serif: "Crimson Pro", "Times New Roman", Times, serif;
  /* call-sheet tier: dates, day counts, durations, phase numbers. Keeping
     anything numeric in mono makes a schedule read as production paperwork
     rather than marketing. Never mixed with the serif — the contrast is the point. */
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

html { scroll-behavior: smooth; scroll-padding-top: 96px; }

html, body {
  background: #000000;
  background: var(--bg, #000000);
  color: #ffffff;
  color: var(--text, #ffffff);
}

body {
  font-family: var(--ui);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  position: relative;
}

img, svg, iframe, video { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button, input, textarea { font-family: inherit; color: inherit; }

:focus-visible { outline: 2px solid var(--pink-text); outline-offset: 3px; border-radius: 4px; }

.skip-link {
  position: absolute; left: var(--gutter); top: -100px; z-index: 200;
  padding: 12px 20px; background: var(--pink); color: #ffffff;
  font-weight: 600; border-radius: 6px; transition: top 180ms ease;
}
.skip-link:focus { top: 12px; }

.grain {
  position: fixed; inset: -60px; z-index: 100; pointer-events: none;
  opacity: 0.075;
  background-image: var(--noise-fine);
  /* stepped so it reads as real film grain rather than a smooth drift */
  animation: gate 900ms steps(1, end) infinite;
  will-change: transform;
}
@keyframes gate {
  0%   { transform: translate3d(0, 0, 0); }
  20%  { transform: translate3d(-14px, 8px, 0); }
  40%  { transform: translate3d(10px, -12px, 0); }
  60%  { transform: translate3d(-8px, -6px, 0); }
  80%  { transform: translate3d(12px, 10px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) { .grain { animation: none; inset: 0; } }

/* ---------- header ---------- */
.header {
  position: sticky; top: 0; z-index: 50;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  padding: var(--header-y) var(--header-x);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color 0.35s ease, border-color 0.35s ease;
}
/* the bar only earns a background once the page has actually moved */
.header.is-stuck {
  background: rgba(0, 0, 0, 0.62);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border-bottom-color: rgba(255, 255, 255, 0.07);
}
/* an open drawer always needs an opaque bar behind it */
body.menu-open .header { background: #000; }

.logo {
  display: inline-flex; align-items: center; justify-self: start;
  min-height: 44px;
}
/* the wordmark is a fixed 845:266 lockup, so it is sized by height only */
.logo img {
  height: var(--logo-h);
  width: auto;
  display: block;
}
.logo-footer img { height: calc(var(--logo-h) * 1.25); }

#site-nav { display: flex; align-items: center; gap: clamp(20px, 2.6vw, 40px); justify-self: center; }

.nav-link {
  position: relative;
  display: inline-flex; align-items: center;
  height: var(--nav-h); padding: 0 2px;
  border: 0; background: none;
  color: rgba(255, 255, 255, 0.68);
  font-size: 12.5px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  white-space: nowrap;
  transition: color 0.25s ease;
}
/* a hairline that draws in from the left on hover — the only ornament */
.nav-link::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 10px;
  height: 1px; background: var(--pink);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.nav-link:hover { color: #fff; }
.nav-link:hover::after { transform: scaleX(1); }
.nav-link[aria-current='page'] { color: var(--pink-text); }
.nav-link[aria-current='page']::after { transform: scaleX(1); }
/* the "Oferta" trigger reads as active on every one of its five child pages,
   not just on Oferta itself */
.nav-link--active { color: var(--pink-text); }
.nav-link--active::after { transform: scaleX(1); }

/* ---------- Oferta dropdown (desktop: hover/focus panel) ---------- */
.nav-item.has-dropdown { position: relative; display: flex; align-items: center; }
/* mega menu: seven services no longer fit a single narrow column without
   looking like a wall of text, so this is a two-column icon+description
   grid instead of a plain link list. */
.nav-dropdown {
  /* left-anchored to the trigger's own left edge, not centered on it — a
     mega menu this wide would clip past the left viewport edge on narrower
     desktop widths if centered on a trigger that sits near the left of the
     header (right after the logo) */
  position: absolute; top: 100%; left: 0;
  transform: translateY(4px);
  z-index: 55; margin-top: 10px;
  width: max-content; max-width: min(640px, calc(100vw - 24px));
  padding: 14px; border-radius: 14px;
  background: rgba(9, 7, 16, 0.92);
  border: 1px solid var(--border-soft);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.45);
  display: grid; grid-template-columns: repeat(2, minmax(230px, 1fr)); gap: 2px 6px;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s linear 0.2s;
}
/* the 10px margin-top above is a real gap with nothing hoverable in it —
   moving the cursor straight down from the trigger into the panel crosses
   it, drops :hover for a frame, and pointer-events:none kills the panel
   right then (no grace period). This invisible strip is still a DOM
   descendant of .nav-item, so hovering it keeps the whole dropdown alive
   across the gap. Inherits visibility from .nav-dropdown, so it is only
   hit-testable while the panel is already open. */
.nav-dropdown::before { content: ''; position: absolute; left: 0; right: 0; top: -10px; height: 10px; }
.nav-item.has-dropdown:hover .nav-dropdown,
.nav-item.has-dropdown:focus-within .nav-dropdown {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateY(0);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s linear 0s;
}
.nav-dropdown-link {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 10px; border-radius: 8px;
  white-space: normal;
  transition: background-color 0.2s ease;
}
.nav-dropdown-link:hover, .nav-dropdown-link:focus-visible { background: rgba(255, 255, 255, 0.07); }
.nav-dd-icon {
  flex: none; display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 8px; margin-top: 1px;
  background: rgba(206, 46, 79, 0.14); color: var(--pink-text);
}
.nav-dd-icon svg { width: 17px; height: 17px; }
.nav-dd-title {
  display: block; font-size: 13px; font-weight: 600; letter-spacing: 0.01em;
  text-transform: none; color: rgba(255, 255, 255, 0.92);
}
.nav-dropdown-link[aria-current='page'] .nav-dd-title { color: var(--pink-text); }
.nav-dd-desc {
  display: block; margin-top: 2px; font-size: 11.5px; line-height: 1.4;
  color: var(--muted); text-transform: none; letter-spacing: 0;
}

/* the <details> accordion only exists for the mobile full-screen menu */
.nav-group { display: none; }

.header-cta { justify-self: end; }

/* ---------- buttons (flat — no gradients) ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: var(--btn-h); padding: 0 16px; border-radius: 6px;
  font-size: var(--btn); font-weight: 500; letter-spacing: -0.02em; line-height: 1;
  white-space: nowrap; cursor: pointer; border: 1px solid transparent;
  transition: background-color 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease, color 0.35s ease;
}
.btn svg { width: 16px; height: 16px; flex: none; }
.btn-lg { height: 48px; padding: 0 22px; font-size: 15px; }
.btn-block { width: 100%; }

.btn-solid { background: var(--pink); color: #ffffff; border-color: var(--pink-text); }
.btn-solid:hover {
  background: var(--pink-hover); border-color: var(--pink-hover);
  box-shadow: 0 0 22px rgba(206, 46, 79, 0.5), 0 8px 18px rgba(206, 46, 79, 0.25);
}

.btn-ghost { background: rgba(9, 7, 16, 0.55); color: #fff; border-color: rgba(198, 198, 198, 0.45); }
.btn-ghost:hover {
  background: rgba(206, 46, 79, 0.28); border-color: rgba(242, 106, 133, 0.7);
  box-shadow: 0 0 20px rgba(206, 46, 79, 0.3);
}

/* ---------- burger ---------- */
.burger {
  display: none; place-items: center; gap: 5px;
  width: 44px; height: 44px; border-radius: 6px;   /* 44px minimum touch target */
  border: 1px solid var(--border); background: rgba(8, 8, 8, 0.55);
  cursor: pointer; z-index: 60;
  transition: background 0.25s ease, border-color 0.25s ease;
}
.burger:hover { border-color: rgba(255,255,255,0.32); background: rgba(255,255,255,0.05); }
.burger span { display: block; width: 16px; height: 1.5px; border-radius: 1px; background: #fff;
  transition: transform 0.25s ease, opacity 0.2s ease; }
body.menu-open .burger span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
body.menu-open .burger span:nth-child(2) { opacity: 0; }
body.menu-open .burger span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.menu-backdrop { display: none; }

/* ---------- layout ---------- */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.container-narrow { max-width: 860px; }

.section { position: relative; z-index: 2; padding-block: clamp(72px, 11vw, 148px); }
.section-tight { padding-block: clamp(40px, 6vw, 68px); }

.page-hero {
  position: relative; z-index: 2; overflow: hidden;
  min-height: clamp(440px, 58vh, 640px);
  display: flex; align-items: center;
  padding: clamp(88px, 13vw, 140px) 0 clamp(40px, 6vw, 64px);
}
/* a real BTS photo as a full-bleed backdrop, on subpages that used to be
   text-only — the copy sits left, so the scrim is strongest there and eases
   off to the right, letting the photo actually read instead of just peeking
   out from behind a boxed-in slot. Bottom fade blends into the pure-black
   page background below, same technique as the homepage's video hero. */
.page-hero-media { position: absolute; inset: 0; z-index: 0; background: #000; }
.page-hero-media img { width: 100%; height: 100%; object-fit: cover; }
.page-hero-media::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(90deg, #000 0%, rgba(0,0,0,0.9) 32%, rgba(0,0,0,0.58) 55%, rgba(0,0,0,0.2) 78%, rgba(0,0,0,0) 100%),
    linear-gradient(180deg, rgba(0,0,0,0.25) 0%, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.55) 78%, #000 100%);
}
.page-hero .container { position: relative; z-index: 1; }
@media (max-width: 700px) {
  /* not enough width left of a portrait crop for the gradient to spare — a
     flatter, uniformly dark scrim keeps the text readable instead */
  .page-hero-media::after { background: rgba(0,0,0,0.72); }
}

/* ---------- type ---------- */
h1, h2, h3 {
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 0.94;
  text-wrap: balance;
}
h1 { font-size: var(--h1); }
h2 { font-size: var(--h2); }
h3 { font-size: 19px; line-height: 1.15; letter-spacing: -0.015em; }
/* the italic serif accent stays lowercase — the whole point of the contrast */
h1 em, h2 em, h3 em, .serif-em { text-transform: none; font-weight: 400; }

em, .serif-em {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: 1.08em; letter-spacing: -0.03em; color: var(--pink-text);
}

.lede { max-width: 62ch; color: var(--muted); font-size: var(--lede); line-height: 1.55; letter-spacing: -0.015em; }
.prose { max-width: 68ch; color: var(--stat); }
.prose strong { color: #fff; font-weight: 600; }
.muted { color: var(--muted); }
.accent { color: var(--pink-text); }

.badge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 15px; border-radius: 5px;
  background: var(--surface);
  border: 1px solid rgba(242, 106, 133, 0.45);
  color: #f2f2f2; font-size: 12.5px; font-weight: 400; letter-spacing: -0.01em;
}
.badge svg { flex: none; filter: drop-shadow(0 0 4px rgba(242, 106, 133, 0.9)); }

.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--pink-text);
}
.eyebrow::before { content: ''; width: 28px; height: 1px; background: var(--pink); }
.eyebrow-plain::before { display: none; }

.section-head { max-width: 60ch; margin-bottom: clamp(32px, 5vw, 56px); }
.section-head h2 { margin-top: 16px; }
.section-head .lede { margin-top: 18px; }

.link {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px;
  font-weight: 600; color: var(--pink-text);
  border-bottom: 1px solid rgba(242, 106, 133, 0.5);
  transition: color 0.3s ease, border-color 0.3s ease;
}
.link:hover { color: var(--pink-text); border-color: var(--pink-text); }
.link svg { width: 16px; height: 16px; transition: transform 0.3s ease; }
.link:hover svg { transform: translateX(3px); }

/* ---------- grids ---------- */
.grid { display: grid; gap: clamp(16px, 2.5vw, 28px); }
.grid-2 { grid-template-columns: 1fr; }
@media (min-width: 900px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr)); }
.split { display: grid; gap: clamp(28px, 5vw, 64px); align-items: start; }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .split-sticky > :first-child { position: sticky; top: 104px; } }

/* ---------- cards (indigo needs a border: 1.19:1 vs black on fill alone) ---------- */
.card {
  position: relative; display: flex; flex-direction: column;
  padding: clamp(22px, 3vw, 32px);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  transition: background-color 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
.card:hover { background: var(--surface-lift); border-color: rgba(242, 106, 133, 0.5); }
.card h3 { margin-bottom: 10px; }
.card p { color: var(--stat); font-size: 15px; }
.card-foot { margin-top: auto; padding-top: 22px; }
.card-feature { border-color: rgba(242, 106, 133, 0.65); }

.tag {
  position: absolute; top: -11px; left: clamp(22px, 3vw, 32px);
  z-index: 2;                       /* above the card's media slot */
  padding: 4px 11px; border-radius: 999px;
  background: var(--pink); color: #fff;          /* 5.09:1 */
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
}

.price { display: flex; align-items: baseline; gap: 8px; margin: 14px 0 4px;
  font-size: clamp(28px, 3vw, 38px); font-weight: 500; letter-spacing: -0.045em; line-height: 1; color: var(--pink-text); }
.price small { font-size: 13px; font-weight: 500; letter-spacing: 0.04em; color: var(--muted); }
.price-from { font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--pink-text); }

.ticks { list-style: none; display: grid; gap: 12px; margin-top: 20px; }

/* ---------- big-number stat block (press/results figures) ---------- */
.figures { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px clamp(20px, 3vw, 36px); }
.figure-num { font-size: clamp(26px, 3vw, 34px); font-weight: 500; letter-spacing: -0.03em; line-height: 1; color: var(--pink-text); }
.figure-label { display: block; margin-top: 6px; font-size: 13px; color: var(--stat); }

/* ---------- results screenshots (masonry) ----------
   The source screenshots range from a 90px stat callout to a full 1100px
   LinkedIn post — a regular grid would force them to a common row height and
   either crop or letterbox half of them. CSS columns lets each keep its own
   natural height while still packing tightly. */
.results-grid { columns: 3 240px; column-gap: clamp(16px, 2vw, 24px); }
.result-shot {
  display: block; width: 100%; margin-bottom: clamp(16px, 2vw, 24px);
  border-radius: 10px; break-inside: avoid; overflow: hidden;
  box-shadow: 0 20px 44px rgba(0, 0, 0, 0.4);
  position: relative;
}
.result-shot img { display: block; width: 100%; height: auto; }

/* A circular loupe that follows the cursor (positioned by vesper.js), showing
   a magnified crop of whatever part of the screenshot it's over — the stats
   are dense small print, so this beats a flat hover-zoom of the whole image. */
.result-lens {
  position: absolute;
  width: clamp(32px, 3.5vw, 44px);
  aspect-ratio: 1;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease;
  background-repeat: no-repeat;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.85), 0 12px 32px rgba(0, 0, 0, 0.55);
  z-index: 3;
}
.result-lens.is-active { opacity: 1; }
/* the lens hides the real cursor so it reads as the pointer itself, but only
   once JS has confirmed a mouse (not touch) is driving — see vesper.js */
.result-shot.has-lens { cursor: none; }
@media (hover: none), (pointer: coarse) {
  .result-lens { display: none !important; }
}
/* a very wide/short source (a YouTube result card, not a tall LinkedIn post)
   reads as a tiny sliver squeezed into one ~240px column — give it the full
   row instead, at whatever height that width naturally implies */
.result-shot--wide { column-span: all; max-width: 640px; }
@media (max-width: 560px) { .results-grid { columns: 1; } }
.ticks li { display: grid; grid-template-columns: 20px 1fr; gap: 12px; align-items: start;
  color: var(--stat); font-size: 15px; line-height: 1.5; }
.ticks svg { width: 20px; height: 20px; margin-top: 3px; color: var(--pink-text); }

/* ---------- steps ---------- */
.steps { counter-reset: step; display: grid; gap: 1px; background: var(--border-soft);
  border: 1px solid var(--border-soft); border-radius: 10px; overflow: hidden; }
@media (min-width: 860px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.step { counter-increment: step; padding: clamp(24px, 3vw, 34px); background: var(--surface);
  transition: background-color 0.35s ease; }
.step:hover { background: var(--surface-lift); }
.step::before { content: '0' counter(step); display: block; margin-bottom: 16px;
  font-family: var(--serif); font-style: italic; font-size: 40px; line-height: 1; color: var(--pink-text); }
.step h3 { margin-bottom: 8px; }
.step p { color: var(--stat); font-size: 15px; }

/* ---------- portfolio ---------- */
/* masonry, not an even grid: a mix of 16:9 and 9:16 cards in equal-height
   grid rows either stretches the landscape ones into tall empty cards or
   squashes the vertical ones — columns let each card keep its own height. */
.work-grid { columns: 3 330px; column-gap: clamp(16px, 2vw, 24px); }
.work-grid-featured > :first-child { column-span: all; }

.work { position: relative; display: block; width: 100%; padding: 0; text-align: left;
  background: var(--surface); border: 1px solid var(--border-soft); border-radius: 10px;
  overflow: hidden; cursor: pointer; break-inside: avoid;
  margin-bottom: clamp(16px, 2vw, 24px);
  transition: border-color 0.35s ease, box-shadow 0.35s ease; }
.work:hover, .work:focus-visible { border-color: var(--pink-text); box-shadow: 0 0 28px rgba(206, 46, 79, 0.3); }

.work-frame { display: block; position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: #000; }
/* a 9:16 source padded into a 16:9 box shows as a thumbnail with dark bars
   either side — shaping the frame itself to match avoids that padding
   entirely, same fix as .case-media-vertical */
.work-frame--vertical { aspect-ratio: 9 / 16; }
.work-frame img { width: 100%; height: 100%; object-fit: cover; opacity: 0.85;
  transition: transform 500ms ease, opacity 0.35s ease; }
.work:hover .work-frame img, .work:focus-visible .work-frame img { transform: scale(1.04); opacity: 1; }
.work-frame::after { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.8) 100%); }

.work-play { position: absolute; z-index: 2; left: 18px; bottom: 18px;
  display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%;
  background: rgba(9, 7, 16, 0.72); border: 1px solid var(--border);
  backdrop-filter: blur(6px);
  transition: background-color 0.35s ease, border-color 0.35s ease; }
.work-play svg { width: 18px; height: 18px; margin-left: 2px; color: #fff; }
.work:hover .work-play, .work:focus-visible .work-play { background: var(--pink); border-color: var(--pink-text); }
.work:hover .work-play svg, .work:focus-visible .work-play svg { color: #ffffff; }

.work-time { position: absolute; z-index: 2; right: 18px; bottom: 18px;
  padding: 3px 9px; border-radius: 3px; background: rgba(0,0,0,0.72); border: 1px solid var(--border-soft);
  font-size: 11.5px; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: 0.06em; color: var(--stat); }

.work-body { display: block; padding: 20px 22px 22px; }
.work-cat { display: block; font-size: 10.5px; font-weight: 600; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--pink-text); }
.work-title { display: block; margin-top: 8px; font-size: 19px; font-weight: 500; letter-spacing: -0.03em; }

/* ---------- lightbox ---------- */
.lightbox {
  position: fixed; inset: 0; z-index: 150; display: grid; place-items: center;
  padding: clamp(16px, 4vw, 48px); background: rgba(0, 0, 0, 0.92);
  backdrop-filter: blur(10px);
  opacity: 0; visibility: hidden;
  transition: opacity 0.28s ease, visibility 0s linear 0.28s;
}
.lightbox.is-open { opacity: 1; visibility: visible; transition: opacity 0.28s ease, visibility 0s linear 0s; }
.lightbox-panel { width: min(100%, 1150px); }
.lightbox-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.lightbox-title { font-size: clamp(17px, 2vw, 22px); font-weight: 500; letter-spacing: -0.03em; }
.lightbox-frame { position: relative; aspect-ratio: 16 / 9; border: 1px solid var(--border-soft);
  border-radius: 10px; background: #000; overflow: hidden; }
.lightbox-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
body.is-locked { overflow: hidden; }
/* same overlay shell as the video lightbox, reused for one-off signup forms
   (e.g. Warsztat Otwarty) — just narrower, and scrollable on short screens
   since a form's height isn't fixed like a 16:9 video frame. */
.lightbox-panel--form { width: min(100%, 480px); max-height: calc(100vh - 32px); overflow-y: auto; }

/* ---------- FAQ ---------- */
.faq { border-top: 1px solid var(--border-soft); }
.faq details { border-bottom: 1px solid var(--border-soft); }
.faq summary { display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 20px 0; font-size: clamp(17px, 1.8vw, 21px); font-weight: 500; letter-spacing: -0.03em;
  line-height: 1.3; cursor: pointer; list-style: none; transition: color 0.3s ease; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--pink-text); }
.faq summary .chev { flex: none; width: 22px; height: 22px; color: var(--pink-text); transition: transform 0.3s ease; }
.faq details[open] summary .chev { transform: rotate(45deg); }
.faq details p { padding-bottom: 22px; color: var(--stat); max-width: 70ch; }

/* ---------- chips ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip { padding: 9px 16px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--stat); font-size: 14px;
  transition: color 0.3s ease, border-color 0.3s ease, background-color 0.3s ease; }
.chip:hover { color: #fff; border-color: var(--pink-text); background: var(--surface-lift); }

/* ---------- people / beliefs ---------- */
/* photo first, then the hairline and name — mirrors the process steps */
.person { padding-top: 0; border-top: 0; }
.person-photo {
  margin-bottom: 20px;
  /* uncapped these ran ~700px tall and pushed the names off-screen */
  max-width: 400px;
}
.person-photo .slot { aspect-ratio: 4 / 5; }
.person-name {
  padding-top: 16px; border-top: 1px solid var(--border-soft);
  font-size: 28px; font-weight: 500; letter-spacing: -0.045em; line-height: 1.1;
}
.person-role { margin-top: 6px; font-size: 11.5px; font-weight: 600; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--pink-text); }
.person p { margin-top: 14px; color: var(--stat); }

.belief { padding: clamp(20px, 3vw, 28px) 0; border-top: 1px solid var(--border-soft); }
.belief h3 { font-size: clamp(19px, 2.4vw, 24px); }
.belief p { margin-top: 10px; color: var(--stat); max-width: 62ch; }

/* ---------- CTA band ---------- */
.cta-band { position: relative; z-index: 2; overflow: hidden;
  background: var(--surface); }
.cta-band-inner { text-align: center; padding-block: clamp(56px, 9vw, 96px); }
.cta-band h2 { margin: 16px auto 0; max-width: 18ch; }
.cta-band .lede { margin: 18px auto 0; }
.cta-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 28px; }

/* ---------- form ---------- */
.form { display: grid; gap: 18px; }
.field { display: grid; gap: 7px; }
.field label { font-size: 13px; font-weight: 600; letter-spacing: 0.03em; color: var(--stat); }
.field label .req { color: var(--pink-text); }
.field input, .field textarea {
  width: 100%; min-height: 48px; padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px; color: #fff;
  transition: border-color 0.3s ease, background-color 0.3s ease;
}
.field textarea { min-height: 150px; resize: vertical; line-height: 1.6; }
.field input::placeholder, .field textarea::placeholder { color: #8F89A5; }  /* 5.2:1 on indigo */
.field input:hover, .field textarea:hover { border-color: rgba(255,255,255,0.34); }
.field input:focus, .field textarea:focus { border-color: var(--pink-text); background: var(--surface-lift); }
.field .hint { font-size: 12.5px; color: var(--muted); }
.form-note { font-size: 13px; color: var(--muted); }

.contact-list { list-style: none; display: grid; gap: 1px; background: var(--border-soft);
  border: 1px solid var(--border-soft); border-radius: 10px; overflow: hidden; }
.contact-list a { display: flex; align-items: center; gap: 14px; min-height: 64px; padding: 14px 18px;
  background: var(--surface); transition: background-color 0.3s ease; }
.contact-list a:hover { background: var(--surface-lift); }
.contact-list svg { width: 20px; height: 20px; flex: none; color: var(--pink-text); }
.contact-list .k { display: block; font-size: 10.5px; font-weight: 600; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted); }
.contact-list .v { display: block; margin-top: 2px; font-weight: 500; color: #fff; }

/* ---------- footer ---------- */
.footer { position: relative; z-index: 2;
  background: #000; padding-block: clamp(44px, 6vw, 68px) 24px; }
.footer-grid { display: grid; gap: 36px; }
@media (min-width: 760px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
.footer h4 { font-size: 10.5px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 10px; }
.footer ul { list-style: none; display: grid; gap: 2px; }
.footer ul a { display: inline-flex; align-items: center; min-height: 44px; }
.footer a { color: var(--stat); transition: color 0.3s ease; }
.footer a:hover { color: var(--pink-text); }
.footer-bottom { display: flex; flex-wrap: wrap; gap: 10px 24px; justify-content: space-between;
  margin-top: 40px; padding-top: 20px; border-top: 1px solid var(--border-soft);
  font-size: 13px; color: var(--muted); }

/* ---------- scroll reveal ---------- */
.reveal { opacity: 0; transform: translateY(18px);
  transition: opacity 700ms cubic-bezier(0.16, 1, 0.3, 1), transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: var(--d, 0ms); }
.reveal.is-visible { opacity: 1; transform: none; }

/* ================= responsive ================= */
@media (min-width: 1600px) {
  :root { --logo-h: 40px; --nav: 15px; --nav-h: 44px; --btn: 15px; --btn-h: 44px;
          --h1: 68px; --h2: 50px; --lede: 18px; --header-x: 64px; }
  .nav-link { padding: 0 20px; }
}
@media (min-width: 1920px) {
  :root { --logo-h: 46px; --nav: 16px; --nav-h: 48px; --btn: 16px; --btn-h: 48px;
          --h1: 80px; --h2: 58px; --lede: 20px; --header-x: 80px; }
  #site-nav { gap: 10px; }
  .nav-link { padding: 0 22px; }
}
@media (min-width: 901px) and (max-width: 1279px) {
  :root { --logo-h: 30px; --nav: 13px; --nav-h: 36px; --btn: 13px; --btn-h: 38px;
          --h1: 44px; --h2: 34px; --lede: 15px; --header-x: 28px; }
  .nav-link { padding: 0 14px; }
}

@media (max-width: 900px) {
  :root { --logo-h: 30px; --btn: 15px; --btn-h: 46px; --h1: 38px; --h2: 30px; --lede: 16.5px;
          --header-y: 14px; --header-x: 18px; }

  .header {
    grid-template-columns: 1fr auto auto; gap: 8px;
    padding-top: max(var(--header-y), env(safe-area-inset-top));
    padding-left: max(var(--header-x), env(safe-area-inset-left));
    padding-right: max(var(--header-x), env(safe-area-inset-right));
  }
  .logo, .header-cta, .burger { z-index: 80; }
  .burger { display: grid; }

  /* backdrop-filter makes an element a containing block for fixed-position
     descendants, which trapped the full-screen nav inside the header box.
     Drop it on phones and paint the stuck bar solid instead. */
  .header.is-stuck, body.menu-open .header {
    background: #000000;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .menu-backdrop {
    display: block; position: fixed; inset: 0; z-index: 40; background: rgba(8, 8, 8, 0.42);
    opacity: 0; visibility: hidden;
    transition: opacity 0.28s ease, visibility 0s linear 0.28s, backdrop-filter 0.28s ease;
  }
  body.menu-open .menu-backdrop {
    opacity: 1; visibility: visible;
    backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
    transition: opacity 0.28s ease, visibility 0s linear 0s, backdrop-filter 0.28s ease;
  }

  #site-nav {
    position: fixed; inset: 0; z-index: 45;
    justify-self: stretch; align-items: stretch;
    flex-direction: column; justify-content: center; gap: 12px;
    padding: 96px 22px 32px; padding-top: max(96px, calc(env(safe-area-inset-top) + 88px));
    background: transparent; opacity: 0; visibility: hidden;
    transition: opacity 0.28s ease, visibility 0s linear 0.28s;
  }
  body.menu-open #site-nav { opacity: 1; visibility: visible; transition: opacity 0.28s ease, visibility 0s linear 0s; }
  .nav-link { width: 100%; height: 56px; justify-content: center; font-size: 20px; letter-spacing: 0.1em; }
  .nav-link::after { left: 50%; right: 50%; bottom: 12px; transition: left 0.3s ease, right 0.3s ease, transform 0.3s ease; }
  .nav-link:hover::after, .nav-link[aria-current='page']::after { left: 22%; right: 22%; transform: scaleX(1); }

  /* the hover panel needs real hover, which touch screens don't have — swap
     to the native <details> accordion for the same five links */
  .nav-item.has-dropdown { display: none; }
  .nav-group { display: block; width: 100%; text-align: center; }
  .nav-group summary {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    width: 100%; height: 56px; cursor: pointer; list-style: none;
  }
  .nav-group summary::-webkit-details-marker { display: none; }
  .nav-group summary::after {
    content: ''; width: 9px; height: 9px; flex: none;
    border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg) translateY(-2px); transition: transform 0.25s ease;
  }
  .nav-group[open] summary::after { transform: rotate(-135deg) translateY(2px); }
  .nav-sublist { display: flex; flex-direction: column; align-items: center; gap: 2px; padding-bottom: 14px; }
  .nav-dropdown-link {
    width: 100%; max-width: 320px;
    flex-direction: column; align-items: center; text-align: center;
    padding: 12px;
  }
  .nav-dd-icon { margin-top: 0; }
  .nav-dd-title { font-size: 15px; letter-spacing: 0.02em; margin-top: 8px; }
  .nav-dd-desc { font-size: 12.5px; }

  body.menu-open { overflow: hidden; }
}

@media (max-width: 560px) {
  :root { --h1: 34px; --header-x: 16px; }
  .cta-actions { flex-direction: column; }
  .cta-actions .btn { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .reveal { opacity: 1; transform: none; }
}

/* section heading, centred variant */
.section-head-center { margin-inline: auto; text-align: center; }
.section-head-center .lede, .section-head-center .eyebrow { margin-inline: auto; }
.section-head-center .eyebrow::before { display: none; }

/* action rows inside page heroes and sections */
.cta-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.page-hero .cta-actions { justify-content: flex-start; }


/* ==========================================================================
   Home hero (video) + entrance motion — shared so index.html uses this sheet
   ========================================================================== */
.home-hero {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: flex-start;
  min-height: 82svh;                    /* a sliver of the next section shows, inviting scroll */
  /* pulled up under the transparent bar so the footage runs to the very top
     of the viewport; the padding puts the copy back clear of it */
  margin-top: calc(-1 * var(--header-h));
  padding: calc(var(--header-h) + 40px) var(--edge) clamp(48px, 7vw, 88px);
  overflow: hidden;
}
.hero-photo { position: absolute; inset: 0; z-index: 0; background: #000; overflow: hidden; }
.hero-photo video { width: 100%; height: 100%; object-fit: cover; opacity: 1; }
/* the set is lit from the right; the copy sits in the dark left half, so the
   scrim only has to deepen that side and leave the television untouched */
.hero-photo::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(0,0,0,0.72) 0%, rgba(0,0,0,0.50) 32%, rgba(0,0,0,0.12) 55%, rgba(0,0,0,0) 72%);
}
.hero-copy {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: flex-start; text-align: left;
  /* never run under the television: JS publishes its left edge as --tv-left */
  max-width: min(620px, calc(var(--tv-left, 60vw) - var(--edge) - 32px)); width: 100%;
}
.hero-copy .badge { margin-bottom: 22px; }
.home-hero h1 { display: flex; flex-direction: column; align-items: flex-start; }
.headline-line { display: block; overflow: hidden; padding: 0.06em 0.15em 0.14em; margin-left: -0.15em; }
.home-hero .lede { max-width: 500px; margin-top: 18px; }
.hero-actions { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 12px; margin-top: 28px; }

/* clickable television: positioned by JS over the set in the footage */
.hero-tv {
  position: absolute; z-index: 3; display: none;
  padding: 0; border: 0; background: transparent; cursor: pointer;
  border-radius: 14px; outline-offset: 6px;
}
.hero-tv.is-placed { display: block; }
/* play button sits on the picture tube (48% / 42% of the set's box) and only
   shows itself on hover or keyboard focus */
.hero-tv-play {
  position: absolute; left: 48%; top: 42%;
  width: 72px; height: 72px; margin: -36px 0 0 -36px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--pink); color: #fff;
  box-shadow: 0 10px 30px rgba(0,0,0,0.45), 0 0 0 1px rgba(255,255,255,0.12) inset;
  opacity: 0; transform: scale(0.82);
  transition: opacity 0.25s ease, transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}
.hero-tv-play svg { width: 26px; height: 26px; margin-left: 3px; }
.hero-tv:hover .hero-tv-play, .hero-tv:focus-visible .hero-tv-play { opacity: 1; transform: scale(1); }
/* quiet prompt above the set */
.hero-tv-hint {
  position: absolute; left: 48%; bottom: calc(100% + 18px); transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); white-space: nowrap; opacity: 0.85;
  transition: color 0.25s ease, opacity 0.25s ease;
}
.hero-tv-hint i {
  display: block; width: 1px; height: 22px;
  background: linear-gradient(180deg, rgba(154,154,154,0) 0%, rgba(154,154,154,0.9) 100%);
  animation: hint-drop 2.4s ease-in-out infinite;
}
@keyframes hint-drop {
  0%, 100% { transform: translateY(0); opacity: 0.6; }
  50%      { transform: translateY(6px); opacity: 1; }
}
.hero-tv:hover .hero-tv-hint, .hero-tv:focus-visible .hero-tv-hint { color: var(--pink-text); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .hero-tv-hint i { animation: none; } }

/* click transition: the camera pushes into the picture tube, the room falls
   away, the frame cuts to black and the showreel takes over. JS sets the
   transform origin to the centre of the screen and adds .is-zooming. */
.hero-photo video {
  transform-origin: var(--tv-cx, 75%) var(--tv-cy, 50%);
  transition: transform 1.1s cubic-bezier(0.65, 0, 0.25, 1), filter 1.1s ease;
}
.home-hero.is-zooming .hero-photo video { transform: scale(3.2); filter: saturate(1.15) contrast(1.05); }
.home-hero.is-zooming .hero-copy { opacity: 0; transform: translateX(-28px); transition: opacity 0.45s ease, transform 0.6s ease; }
.home-hero.is-zooming .hero-tv { opacity: 0; transition: opacity 0.3s ease; pointer-events: none; }
.home-hero.is-zooming .hero-photo::after, .home-hero.is-zooming .hero-photo::before { opacity: 0; transition: opacity 0.7s ease; }
.hero-photo::after, .hero-photo::before { transition: opacity 0.4s ease; }
/* the fade lives above the lightbox (z 150): it goes fully black while the
   camera is still pushing in, the reel opens underneath it, then it lifts */
.hero-flash {
  position: fixed; inset: 0; z-index: 160; pointer-events: none;
  background: #000; opacity: 0; transition: opacity 0.5s ease;
}
body.is-tv-zoom .hero-flash { opacity: 1; transition: opacity 0.65s ease 0.4s; }
body.is-tv-zoom.is-tv-reveal .hero-flash { opacity: 0; transition: opacity 0.8s ease 0.1s; }
/* coming back from the showreel: quick, no drama */
.home-hero.is-unzooming .hero-photo video { transition-duration: 0.6s; }
@media (prefers-reduced-motion: reduce) {
  .hero-photo video, .home-hero.is-zooming .hero-photo video { transition: none; transform: none; }
}
/* the pill on the television replaces the text button on wide screens */
.home-hero.has-tv .hero-showreel-btn { display: none; }

/* Proof band flush under the hero: bounded top and bottom, three equal
   columns split by hairlines. Previously three items adrift in open space. */
/* the hero fades to solid black at its foot, so a hard rule here would put
   the seam back — the band is delimited by its lower hairline alone */
/* pure black, continuing the hero's dissolve — anything translucent here
   would let the field through and put the seam straight back */
.stats {
  position: relative; z-index: 2;
  border-bottom: 1px solid var(--border-soft);
  background: #000;
}
.stats-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  max-width: var(--container); margin-inline: auto;
  padding-inline: var(--gutter);
}
.stat {
  display: flex; align-items: center; gap: 14px;
  padding: clamp(22px, 2.6vw, 30px) clamp(18px, 2vw, 30px);
  font-size: 13.5px; letter-spacing: -0.015em; color: var(--stat);
}
.stat:first-child { padding-left: 0; }
.stat:last-child { padding-right: 0; }
.stat + .stat { border-left: 1px solid var(--border-soft); }
.stat-icon { width: 20px; height: 20px; flex: none; }
.stat-icon-wide { width: 38px; height: 21px; flex: none; }

@media (max-width: 900px) {
  .stats-grid { grid-template-columns: 1fr; }
  .stat { padding-inline: 0; font-size: 15px; }
  .stat + .stat { border-left: 0; border-top: 1px solid var(--border-soft); }
  .home-hero { min-height: 72svh; padding: calc(var(--header-h) + 28px) 20px 48px; justify-content: center; align-items: flex-end; }
  /* no television hotspot on small screens (the crop hides the set) – copy
     goes back to centred over a plain scrim */
  .hero-copy { max-width: 100%; align-items: center; text-align: center; }
  .home-hero h1 { align-items: center; }
  .headline-line { margin-left: 0; }
  .hero-actions { justify-content: center; }
  .hero-photo::after { background: linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.35) 40%, rgba(0,0,0,0.85) 100%); }
  .hero-actions { flex-direction: column; width: 100%; }
  .hero-actions .btn { width: 100%; }
}

.appear {
  opacity: 1;
  animation-duration: 1.05s;
  animation-fill-mode: both;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
  animation-delay: var(--d, 0.08s);
}
.appear--scale { animation-name: in-scale; }
.appear--soft  { animation-name: in-soft; }
.appear--mask  { animation-name: in-mask; }
.appear--pop   { animation-name: in-pop; }
.appear--btn   { animation-name: in-btn; }
.appear--side  { animation-name: in-side; }
.appear--stat  { animation-name: in-stat; }
.appear.is-in, .hero-photo.is-in { animation: none; opacity: 1; transform: none; clip-path: none; filter: none; }

@keyframes in-scale { from { opacity: 0; transform: scale(0.84); } to { opacity: 1; transform: scale(1); } }
@keyframes in-soft  { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
@keyframes in-mask  { from { opacity: 0; transform: translateY(40%); } to { opacity: 1; transform: translateY(0); } }
@keyframes in-pop   { 0% { opacity: 0; transform: scale(0.9); } 70% { opacity: 1; transform: scale(1.03); } 100% { opacity: 1; transform: scale(1); } }
@keyframes in-btn   { from { opacity: 0; transform: translateY(18px) scale(0.94); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes in-side  { from { opacity: 0; transform: translateX(22px); } to { opacity: 1; transform: translateX(0); } }
@keyframes in-stat  { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
@keyframes in-star  { 0% { transform: scale(0.2) rotate(-50deg); } 65% { transform: scale(1.2) rotate(8deg); } 100% { transform: scale(1) rotate(0deg); } }
@keyframes in-em    { from { opacity: 0.35; filter: blur(4px); } to { opacity: 1; filter: blur(0); } }

.badge-star { animation: in-star 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.28s both; }
.home-hero h1 em { animation: in-em 1.2s cubic-bezier(0.16, 1, 0.3, 1) 0.72s both; }

@media (prefers-reduced-motion: reduce) {
  .appear, .hero-photo, .home-hero h1 em, .badge-star {
    opacity: 1; transform: none; clip-path: none; filter: none;
  }
}

/* ==========================================================================
   Architectural components — work-first homepage
   A. .reel     full-bleed horizontal rail, user-driven (no auto-motion:
                moving targets break click-to-play and trip motion sensitivity)
   B. .timeline process as a hairline grid, not boxes
   C. .roster   real client names as type, each row opening its film
   ========================================================================== */

/* ---------- A. showreel rail ---------- */
.reel {
  position: relative; z-index: 2;
  padding-block: clamp(48px, 7vw, 88px) 0;
}

.reel-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;
  max-width: var(--container); margin-inline: auto;
  padding-inline: var(--gutter); margin-bottom: clamp(20px, 3vw, 32px);
}
.reel-head h2 { margin-top: 14px; }



/* ---------- B. process timeline ---------- */
.timeline { display: grid; gap: clamp(28px, 4vw, 8px); counter-reset: tl; }
@media (min-width: 900px) { .timeline { grid-template-columns: repeat(3, 1fr); gap: 0; } }

.tl-step {
  counter-increment: tl;
  position: relative;
  padding: 30px clamp(16px, 3vw, 44px) 0 0;
  border-top: 1px solid var(--border-soft);
}
/* marker sitting on the rule */
.tl-step::before {
  content: '';
  position: absolute; top: -4px; left: 0;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--pink);
}
.tl-num {
  display: block;
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: clamp(40px, 5vw, 68px); line-height: 0.9;
  letter-spacing: -0.03em; color: var(--pink-text);
}
.tl-step h3 { margin: 18px 0 8px; }
.tl-step p { color: var(--stat); font-size: 15px; max-width: 38ch; }

/* ---------- C. client roster ---------- */
.roster { border-top: 1px solid var(--border-soft); }

.roster-item {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: clamp(16px, 3vw, 40px);
  width: 100%;
  padding: clamp(16px, 2.2vw, 24px) 0;
  border: 0; border-bottom: 1px solid var(--border-soft);
  background: none; text-align: left; cursor: pointer;
  transition: padding-inline-start 0.35s ease;
}
.roster-item:hover, .roster-item:focus-visible { padding-inline-start: 12px; }

.roster-line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px 16px; min-width: 0; }
.roster-name {
  font-size: clamp(21px, 3.1vw, 38px); font-weight: 500;
  letter-spacing: -0.04em; line-height: 1.1; color: #fff;
  transition: color 0.25s ease;
}
.roster-item:hover .roster-name, .roster-item:focus-visible .roster-name { color: var(--pink-text); }
.roster-meta { font-size: 12px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }

.roster-thumb {
  position: relative; flex: none;
  width: clamp(84px, 13vw, 148px); aspect-ratio: 16 / 9;
  border-radius: 6px; overflow: hidden; background: #000;
  border: 1px solid var(--border-soft);
}
.roster-thumb img { width: 100%; height: 100%; object-fit: cover; opacity: 0.7; transition: opacity 0.3s ease, transform 0.5s ease; }
.roster-item:hover .roster-thumb img, .roster-item:focus-visible .roster-thumb img { opacity: 1; transform: scale(1.06); }
.roster-thumb::after {
  content: ''; position: absolute; inset: 0;
  border-radius: 6px; box-shadow: inset 0 0 0 1px rgba(255,255,255,0.04);
}

/* a compact, honest one-liner replaces the old chip wall */
.roster-note { margin-top: clamp(24px, 3vw, 36px); color: var(--muted); font-size: 15px; max-width: 62ch; }


/* ---------- circular arrow badge (Takt-style action) ---------- */
.btn-circle { padding-right: 7px; gap: 12px; }
.btn-circle .circ {
  display: grid; place-items: center; flex: none;
  width: 28px; height: 28px; border-radius: 50%;
  background: rgba(0, 0, 0, 0.22);
  transition: transform 0.3s ease, background-color 0.3s ease;
}
.btn-circle .circ svg { width: 13px; height: 13px; }
.btn-circle:hover .circ { transform: rotate(45deg); }
.btn-ghost.btn-circle .circ { background: var(--pink); }

/* ---------- tiny caps label list (Takt "PHOTOGRAPHY / ANIMATION +") ---------- */
.caps-list { list-style: none; display: grid; gap: 10px; margin-top: 22px; }
.caps-list li {
  font-size: 12px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
}

/* ---------- media that breaks the column, Takt-style ---------- */
.bleed-right { margin-right: calc(-1 * var(--edge)); }
@media (max-width: 900px) { .bleed-right { margin-right: calc(-1 * var(--gutter)); } }

/* uppercase display sizes need more room than sentence case did */
.roster-name, .work-title, .person-name { text-transform: uppercase; letter-spacing: -0.02em; }
.tl-num { text-transform: none; }

.hero-copy { z-index: 2; }


/* ==========================================================================
   Tactile surfaces — the noise rides in the background layer (under text),
   blended into the colour so indigo reads as material rather than flat ink.
   ========================================================================== */
.card, .step, .section-invert, .cta-band, .badge, .chip,
.contact-list a, .field input, .field textarea, .work, .roster-thumb {
  background-image: var(--noise-weave);
  background-size: 200px 200px;
  background-blend-mode: soft-light;
}

/* Touch turns the weave that's already there into a faint flicker of static
   — the same fine grain the page-wide .grain layer uses, stepped through a
   few jittered offsets rather than crossfaded, so it reads as noise rather
   than a texture simply getting darker. Small amplitude on purpose: .card
   can't get overflow:hidden (.card-feature's ribbon tag deliberately sits
   -11px above the card edge and would get clipped), so the jitter has to
   stay too small for that edge to be visible either way. z-index:-1 needs
   its host to actually establish a stacking context (hence z-index:0 here
   too), or the pseudo paints on top of the card's own text and photo instead
   of behind them. .field input/textarea are skipped since generated content
   on replaced form elements doesn't render reliably. */
.card, .work, .chip, .badge { position: relative; z-index: 0; }
.card::after, .work::after, .chip::after, .badge::after {
  content: '';
  position: absolute; inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-image: var(--noise-fine);
  opacity: 0;
  transition: opacity 200ms ease;
  animation: static-jitter 400ms steps(1, end) infinite;
  animation-play-state: paused;
  pointer-events: none;
}
.card:hover::after, .card:focus-visible::after,
.work:hover::after, .work:focus-visible::after,
.chip:hover::after, .chip:focus-visible::after,
.badge:hover::after {
  opacity: 0.14;
  animation-play-state: running;
}

/* Video thumbnails (work/portfolio tiles, the case accordion's player,
   marquee logos, the roster's compact thumbs) get the same static, but on
   TOP of the image rather than behind it — there is no text to protect here,
   and static crossing the frame reads as an old broadcast signal catching,
   which suits a video reel far better than it would suit body copy. Kept
   below the play-icon/duration overlays (z-index:2) so those stay crisp. */
.tile, .case-media, .trust-item { position: relative; }
.tile::after, .case-media::after, .trust-item::after, .roster-thumb::before {
  content: '';
  position: absolute; inset: 0;
  z-index: 1;
  border-radius: inherit;
  background-image: var(--noise-fine);
  opacity: 0;
  transition: opacity 200ms ease;
  animation: static-jitter 400ms steps(1, end) infinite;
  animation-play-state: paused;
  pointer-events: none;
}
.tile:hover::after, .tile:focus-visible::after,
.case-media:hover::after, .case-media:focus-visible::after,
.trust-item:hover::after, .trust-item:focus-visible::after,
.roster-item:hover .roster-thumb::before, .roster-item:focus-visible .roster-thumb::before {
  opacity: 0.16;
  animation-play-state: running;
}
.tile-time { z-index: 2; }

@keyframes static-jitter {
  0%   { transform: translate3d(0, 0, 0); }
  20%  { transform: translate3d(-3px, 2px, 0); }
  40%  { transform: translate3d(2px, -3px, 0); }
  60%  { transform: translate3d(-2px, -2px, 0); }
  80%  { transform: translate3d(3px, 3px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .card::after, .work::after, .chip::after, .badge::after,
  .tile::after, .case-media::after, .trust-item::after, .roster-thumb::before {
    transition: none; animation: none;
  }
  .card:hover::after, .card:focus-visible::after,
  .work:hover::after, .work:focus-visible::after,
  .chip:hover::after, .chip:focus-visible::after,
  .badge:hover::after { opacity: 0.14; }
  .tile:hover::after, .tile:focus-visible::after,
  .case-media:hover::after, .case-media:focus-visible::after,
  .trust-item:hover::after, .trust-item:focus-visible::after,
  .roster-item:hover .roster-thumb::before, .roster-item:focus-visible .roster-thumb::before { opacity: 0.16; }
}

/* the work card's own photo must not get the weave */
.work-frame img, .roster-thumb img { background-image: none; }

/* lens vignette — the hero should feel shot, not rendered */
.home-hero::after,
.hero-vignette {
  pointer-events: none;
}
.hero-photo::before {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(120% 90% at 62% 48%, transparent 55%, rgba(0,0,0,0.38) 100%);
}
/* dissolve from the footage into the page, so the band below doesn't arrive
   as a hard cut – kept below the television so the set stays lit */
.home-hero::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: clamp(140px, 24%, 260px);
  z-index: 1; pointer-events: none;
  background: linear-gradient(180deg,
    rgba(0,0,0,0) 0%, rgba(0,0,0,0.25) 28%, rgba(0,0,0,0.62) 55%,
    rgba(0,0,0,0.88) 78%, #000 100%);
}

/* a hairline of grain on the big display type keeps it from looking vector-clean */
.home-hero h1 { text-shadow: 0 1px 0 rgba(0,0,0,0.5); }


/* ---------- living background field (WebGL, assets/js/shader.js) ----------
   Sits behind every transparent section so the page reads as a moving
   material rather than flat ink. The SVG film grain stays on top of it. */
.shader-bg {
  position: fixed; inset: 0; z-index: 0;
  display: block; width: 100%; height: 100%;
  pointer-events: none;
  /* capped at 0.42: above ~0.45 the field's brightest lobe pushes muted body
     copy (#9a9a9a) under 4.5:1. At 0.42 the worst case is 4.69:1. */
  opacity: 0.42;
}
@media (prefers-reduced-motion: reduce) { .shader-bg { opacity: 0.34; } }


/* ---------- trust strip (marquee) ---------- */
.trust {
  position: relative; z-index: 2;
  background: var(--surface);
  padding-block: clamp(16px, 2vw, 24px);
  --trust-gap: clamp(28px, 4vw, 64px);
}

.trust-marquee {
  display: flex; gap: var(--trust-gap);
  overflow: hidden;
  /* fade the ends so names enter and leave rather than getting chopped */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.trust-track {
  display: flex; align-items: center; flex: none;
  gap: var(--trust-gap);
  list-style: none; margin: 0; padding: 0;
  animation: trust-scroll 42s linear infinite;
  will-change: transform;
}
/* a moving target is hard to click, so stop on hover and on keyboard focus */
.trust:hover .trust-track,
.trust:focus-within .trust-track { animation-play-state: paused; }

@keyframes trust-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% - var(--trust-gap))); }
}

.trust-item {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0; border: 0; background: none;
  cursor: pointer; color: var(--muted);
  font-size: clamp(11px, 1.05vw, 13px); font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap;
  transition: color 0.25s ease;
}
.trust-item:hover, .trust-item:focus-visible { color: #fff; }
/* The files are already normalised to monochrome, so no filter is needed —
   grayscale+brightness on top of that would blow the lighter marks out.
   Capped on both axes: the wordmarks are up to 7:1 while the crest is square,
   so height alone would leave one enormous and the other invisible. */
.trust-item img {
  height: auto; width: auto;
  max-height: clamp(22px, 2.4vw, 30px);
  max-width: clamp(96px, 11vw, 150px);
  object-fit: contain;
  opacity: 0.72;
  transition: opacity 0.25s ease;
}
/* a square crest carries far less visual weight than a 7:1 wordmark at the
   same height, so it gets a little more room to balance optically */
.trust-item img[data-shape="mark"] { max-height: clamp(30px, 3.2vw, 42px); }
.trust-item:hover img, .trust-item:focus-visible img { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .trust-marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .trust-track { animation: none; }
  .trust-track[aria-hidden='true'] { display: none; }
  /* the repeated copies that keep a single track wide enough for giant
     screens are only needed to feed the animation, so a manual scroller
     doesn't need to show the client list 4 times over */
  .trust-track li[aria-hidden='true'] { display: none; }
}

}


/* CTA band keeps only its hairline — background comes from the page veil */
.cta-band { position: relative; overflow: hidden; }
.cta-band > * { position: relative; z-index: 1; }



/* ---------- page veil ----------
   The translucent layer the logo marquee used to carry on its own, now applied
   once across the whole page: it sits over the shader field and under all
   content, so every band and section shares one background instead of each
   painting its own. Bands are then delimited by hairlines alone. */
body::before {
  content: '';
  position: fixed; inset: 0; z-index: 0;
  pointer-events: none;
  background: var(--surface);
}
.trust, .cta-band { background: none; }
/* .stats keeps a solid black fill: it continues the hero's dissolve, so it
   must not let the field show through (see the hero-to-band run below). */
.stats { background: #000; }


/* ==========================================================================
   Media slots — a real <img> when artwork exists, an explicit empty state
   when it doesn't. Never a broken frame, never stand-in stock.
   ========================================================================== */
.slot {
  position: relative; display: block; overflow: hidden;
  border-radius: 8px; background: var(--surface);
  border: 1px solid var(--border-soft);
}
.slot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.slot-empty {
  display: grid; place-content: center; justify-items: center; gap: 10px;
  padding: 20px; text-align: center;
  border-style: dashed; border-color: rgba(255,255,255,0.16);
}
.slot-empty svg { width: 26px; height: 26px; color: var(--pink-text); opacity: 0.75; }
.slot-empty span {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted); max-width: 22ch; line-height: 1.5;
}

/* ---------- process: photo-led steps ---------- */
.process { display: grid; gap: clamp(32px, 4vw, 40px); }
@media (min-width: 900px) { .process { grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 2.4vw, 32px); } }

.pstep { display: flex; flex-direction: column; }
.pstep .slot { aspect-ratio: 4 / 5; margin-bottom: 22px; }
.pstep-rule {
  display: flex; align-items: center; gap: 12px;
  padding-top: 14px; border-top: 1px solid var(--border-soft);
}
.pstep-num {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: clamp(30px, 3.4vw, 44px); line-height: 0.9;
  letter-spacing: -0.03em; color: var(--pink-text); text-transform: none;
}
.pstep h3 { margin: 14px 0 8px; }
.pstep p { color: var(--stat); font-size: 15px; max-width: 40ch; }

/* ---------- offer cards with imagery ---------- */
.card-media { margin: calc(-1 * clamp(22px, 3vw, 32px)); margin-bottom: 20px; }
.card-media .slot {
  aspect-ratio: 1 / 1; border: 0; border-radius: 10px 10px 0 0;
  border-bottom: 1px solid var(--border-soft);
}
.card-media .slot-empty { border: 0; border-bottom: 1px dashed rgba(255,255,255,0.16); }

/* ---------- case-study accordion ---------- */
/* ---------- case filters ---------- */
/* Hidden until the script marks the group ready: with JS off every case shows
   and the chips would be inert controls. */
.case-filters { display: none; flex-wrap: wrap; gap: 10px; margin-bottom: 28px; }
.case-filters.is-ready { display: flex; }
.chip {
  font-family: var(--mono);
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  padding: 9px 16px;
  min-height: 38px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}
.chip:hover { color: #fff; border-color: rgba(255, 255, 255, 0.28); }
.chip.is-on {
  color: #fff;
  background: var(--pink);
  border-color: var(--pink);
}
.chip.is-on:hover { background: var(--pink-hover); border-color: var(--pink-hover); }
.case[hidden] { display: none; }
.work[hidden] { display: none; }
.cases-empty { margin-top: 28px; color: var(--muted); }

.cases { border-top: 1px solid var(--border-soft); }
.case { border-bottom: 1px solid var(--border-soft); }
.case > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: clamp(18px, 2.4vw, 26px) 0;
  cursor: pointer; list-style: none;
  transition: padding-inline-start 0.3s ease;
}
.case > summary::-webkit-details-marker { display: none; }
.case > summary:hover { padding-inline-start: 10px; }
.case-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px 16px; min-width: 0; }
.case-name {
  font-size: clamp(20px, 2.9vw, 34px); font-weight: 500;
  letter-spacing: -0.035em; line-height: 1.1; text-transform: uppercase;
  color: #fff; transition: color 0.25s ease;
}
.case > summary:hover .case-name, .case > summary:focus-visible .case-name { color: var(--pink-text); }
.case-meta {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted);
}
.case-chev { flex: none; width: 22px; height: 22px; color: var(--pink-text); transition: transform 0.3s ease; }
.case[open] .case-chev { transform: rotate(45deg); }

.case-body { display: grid; gap: clamp(20px, 3vw, 36px); padding-bottom: clamp(24px, 3vw, 36px); }
@media (min-width: 900px) { .case-body { grid-template-columns: 1.35fr 1fr; align-items: start; } }

.case-media {
  position: relative; display: block; width: 100%; padding: 0;
  border: 1px solid var(--border-soft); border-radius: 10px;
  background: #000; overflow: hidden; cursor: pointer;
  aspect-ratio: 16 / 9;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.case-media:hover, .case-media:focus-visible { border-color: var(--pink); box-shadow: 0 0 28px rgba(206,46,79,0.28); }
.case-media img { width: 100%; height: 100%; object-fit: cover; opacity: 0.9; transition: opacity 0.3s ease, transform 0.5s ease; }
.case-media:hover img { opacity: 1; transform: scale(1.03); }
.case-media .work-play { left: 18px; bottom: 18px; }

.case-copy p { color: var(--stat); font-size: 15px; line-height: 1.65; }
.case-facts { list-style: none; display: grid; gap: 10px; margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--border-soft); }
.case-facts div { display: grid; grid-template-columns: 8.5rem 1fr; gap: 12px; align-items: baseline; }
.case-facts dt { font-size: 10.5px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.case-facts dd { margin: 0; color: #fff; font-size: 14px; }


/* The hero and proof band sit on pure black; this returns the page to the
   living field gradually instead of switching back in one step. */
.reel { isolation: isolate; }
.reel::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0;
  height: clamp(180px, 28vh, 320px);
  z-index: 0; pointer-events: none;
  background: linear-gradient(180deg, #000 0%, rgba(0,0,0,0.72) 40%, rgba(0,0,0,0.3) 72%, transparent 100%);
}
.reel > * { position: relative; z-index: 1; }


/* ---------- 4. mono tier ---------- */
.mono, .work-time, .case-meta, .price-from, .tl-date, .tl-days, .sheet-meta, .sched-head {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}
.case-meta, .price-from, .sheet-meta { letter-spacing: 0.08em; }

/* ---------- 2. full-bleed contact sheet ---------- */
/* Mixed-orientation contact sheet as a mosaic: square cells, landscape tiles
   span two columns, portrait tiles span two rows. Both then sit ~12.5% off
   their true aspect — the symmetric compromise, absorbed by object-fit: cover.
   JS sets --cols and the row height (= column width) so cells stay square. */
.sheet {
  display: grid;
  grid-template-columns: repeat(var(--cols, 5), 1fr);
  grid-auto-flow: dense;
  gap: 0;
  background: #000;
}

.tile {
  position: relative; display: block; padding: 0;
  width: auto; height: auto;
  min-width: 0; overflow: hidden; cursor: pointer;
  border: 0; background: #000; text-align: left;
  box-shadow: inset -1px -1px 0 rgba(255, 255, 255, 0.07);
  transition: opacity 0.5s ease;
}
.tile--wide { grid-column: span 2; }
.tile--tall { grid-row: span 2; }
/* odd tile out: spans the full row width and two rows, so the grid ends flush */
.tile--feature { grid-column: 1 / -1; grid-row: span 2; }

.tile img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 0.6s ease, filter 0.6s ease;
}
.tile:hover img, .tile:focus-visible img { transform: scale(1.06); filter: brightness(0.65); }

/* no-JS fallback: square cells still work, rows just size to the image */
@supports not (grid-auto-flow: dense) { .sheet { display: flex; flex-wrap: wrap; } }

.tile-overlay {
  position: absolute; inset: 0; display: grid; place-content: center; justify-items: center;
  gap: 12px; padding: 16px; text-align: center;
  /* a real scrim, not just the brightness filter: a bright frame at 0.38
     brightness still leaves muted label text around 2.3:1 */
  background: rgba(0, 0, 0, 0.45);
  opacity: 0; transition: opacity 0.4s ease;
}
.tile:hover .tile-overlay, .tile:focus-visible .tile-overlay { opacity: 1; }
.tile-ring {
  display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.5); transition: background-color 0.3s ease, border-color 0.3s ease;
}
.tile:hover .tile-ring { background: var(--pink); border-color: var(--pink); }
.tile-ring svg { width: 17px; height: 17px; margin-left: 2px; color: #fff; }
.tile-name { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; color: #fff; }
.sheet-meta { display: block; margin-top: 4px; font-size: 11px; text-transform: uppercase; color: rgba(255,255,255,0.85); }
.tile-time {
  position: absolute; right: 10px; bottom: 10px;
  font-family: var(--mono); font-size: 11px; color: rgba(255,255,255,0.9);
  text-shadow: 0 1px 4px rgba(0,0,0,0.95), 0 0 12px rgba(0,0,0,0.8);
}

/* a small, fixed set of example videos reuses the homepage's mosaic tiles
   (edge-to-edge, hover-reveal title, no card body underneath) but in a
   static grid sized to the page's own hand-picked set — no JS square-cell
   sizing or tile--wide/tile--tall spans needed since each page's videos are
   given one uniform aspect-ratio (a stray 9:16 clip among mostly-landscape
   examples just gets center-cropped by object-fit:cover, same as any
   thumbnail grid) and a column count chosen to divide evenly, so nothing
   is ever left as a half-empty row. */
.example-sheet {
  display: grid; gap: 0;
  background: #000; border-radius: 10px; overflow: hidden;
}
.example-sheet .tile { grid-column: auto; grid-row: auto; }
.example-sheet--landscape .tile { aspect-ratio: 16 / 9; }
.example-sheet--portrait .tile { aspect-ratio: 9 / 16; }
.example-sheet--cols-2 { grid-template-columns: repeat(2, 1fr); }
.example-sheet--cols-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 640px) {
  .example-sheet--cols-2, .example-sheet--cols-3 { grid-template-columns: 1fr; }
}

/* ---------- 5. sibling-dimming spotlight ---------- */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .dim-group > * { transition: opacity 0.45s ease; }
  .dim-group:hover > * { opacity: 0.25; }
  .dim-group:hover > *:hover,
  .dim-group:focus-within > *:focus-within { opacity: 1; }
}

/* ---------- 1. date-aware schedule ---------- */
.sched-head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 18px;
  padding-bottom: 16px; margin-bottom: clamp(24px, 3vw, 36px);
  border-bottom: 1px solid var(--border-soft);
  font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
}
.sched-head b { color: #fff; font-weight: 600; }
.sched-note { font-size: 12px; color: var(--muted); margin-top: 14px; font-family: var(--ui); letter-spacing: 0; text-transform: none; }

.tl-dates { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; margin-top: 4px; }
.tl-date { font-size: 13px; color: var(--pink-text); }
.tl-days { font-size: 11px; color: var(--muted); }
.pstep-owed {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border-soft);
  font-size: 12.5px; color: var(--muted);
}
.pstep-owed b { color: #fff; font-weight: 600; }

/* ---------- 6. hairline mini-CTA band ---------- */
.band { position: relative; z-index: 2; padding-block: clamp(22px, 3vw, 34px); }
.band::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent 8%, rgba(206,46,79,0.45) 50%, transparent 92%);
}
.band-inner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px 28px;
  max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter);
}
.band p { color: var(--stat); font-size: 15px; margin: 0; }

/* inline callout inside a section — same voice as .band, but boxed */
.callout {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px 28px; margin-top: 32px; padding: 20px 24px;
  background: var(--surface); border: 1px solid var(--border-soft); border-left: 2px solid var(--pink);
  border-radius: 10px;
}
.callout p { color: var(--stat); font-size: 15px; margin: 0; }


/* 9:16 pieces get their real shape in the case view — pillarboxing them into
   a 16:9 frame would waste two thirds of the width on the one format the
   studio actually sells. */
.case-media-vertical { aspect-ratio: 9 / 16; max-width: 300px; }
@media (max-width: 900px) { .case-media-vertical { max-width: 240px; } }


/* ---------- portrait lightbox ----------
   9:16 pieces are staged at their real aspect: the panel shrinks to the frame
   so the title bar and close button stay aligned to the video's edges. */
.lightbox.is-vertical .lightbox-panel { width: auto; max-width: 100%; }
.lightbox.is-vertical .lightbox-frame {
  aspect-ratio: 9 / 16;
  height: min(74vh, 860px);
  width: auto;
  margin-inline: auto;
}
@media (max-width: 700px) {
  .lightbox.is-vertical .lightbox-frame { height: auto; width: min(100%, 78vw); }
}


/* behind-the-scenes shot on the About page */
.about-photo { margin-top: clamp(24px, 3vw, 34px); max-width: 380px; }
.about-photo .slot { aspect-ratio: 3 / 4; }


/* a client with no film behind it is not clickable */
.trust-item.is-static { cursor: default; }


/* ---------- header hold-back (homepage) ----------
   The bar stays out for a beat so the showreel opens on its own, then fades
   in just before the hero copy arrives. Resting state is fully visible, so if
   animations never run the header is simply there — it can't get stuck hidden.
   Opacity only, deliberately — animating transform here (even a translateY
   that ends at "none") leaves the property animated for as long as
   fill-mode holds the end state, which is forever with "both". A live
   transform on .header, even one that resolves to identity, makes it a
   containing block for position:fixed descendants — which traps #site-nav's
   full-screen mobile menu inside the header's own ~75px box instead of the
   viewport. Caught this building the Oferta dropdown: the mobile accordion
   rendered squashed into the header bar, only on the homepage. */
.header--intro {
  animation: header-in 0.6s cubic-bezier(0.16, 1, 0.3, 1) 1s both;
}
@keyframes header-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* tabbing in during the hold cancels it — never focus something invisible */
.header--intro:focus-within {
  animation: none;
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .header--intro { animation: none; opacity: 1; }
}


/* ---------- language switcher ---------- */
.header-actions { display: inline-flex; align-items: center; gap: clamp(10px, 1.4vw, 18px); justify-self: end; }
.lang-switch {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 6px;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.68);
  transition: color 0.25s ease;
}
.lang-switch:hover { color: var(--pink-text); }
@media (max-width: 900px) {
  .header-actions { gap: 6px; }
  .lang-switch { min-width: 40px; }
}

/* ==========================================================================
   CRT system – the television in the hero, carried through every screen.
   Three moves only: screens power on/off, switched-off screens wake on
   hover, and a missing picture is static rather than a blank. Everything is
   transform/opacity/clip so it stays cheap; reduced-motion gets plain fades.
   ========================================================================== */

/* --- the lightbox is the set ------------------------------------------- */
.lightbox-titles { display: flex; align-items: baseline; gap: 14px; min-width: 0; }
.lightbox-ch {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--pink-text); white-space: nowrap;
}
.lightbox-ch:empty { display: none; }
.lightbox-frame {
  border: 0; border-radius: 14px;
  box-shadow: 0 0 0 10px #0b0910, 0 0 0 11px rgba(255,255,255,0.09), 0 40px 90px rgba(0,0,0,0.65);
  transform-origin: 50% 50%;
}
/* picture-tube vignette, above the player but never in its way */
.lightbox-frame::before {
  content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none; border-radius: inherit;
  background: radial-gradient(120% 100% at 50% 50%, transparent 64%, rgba(0,0,0,0.42) 100%);
}
/* static while the player tunes in */
.lightbox-frame::after {
  content: attr(data-loading); position: absolute; inset: 0; z-index: 2;
  display: grid; place-items: center; pointer-events: none;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255,255,255,0.8); text-shadow: 0 1px 6px rgba(0,0,0,0.9);
  background: #000 var(--noise-fine); background-size: 160px 160px;
  opacity: 0; transition: opacity 0.3s ease 0.15s;
}
.lightbox-frame.is-loading::after { opacity: 0.9; transition-delay: 0s; animation: static-jitter 360ms steps(1, end) infinite; }
@keyframes crt-on {
  0%   { transform: scale(0.55, 0.004); filter: brightness(3); }
  38%  { transform: scale(1, 0.004); filter: brightness(3); }
  62%  { transform: scale(1, 1);     filter: brightness(1.7); }
  100% { transform: scale(1, 1);     filter: brightness(1); }
}
@keyframes crt-off {
  0%   { transform: scale(1, 1);     filter: brightness(1); }
  45%  { transform: scale(1, 0.004); filter: brightness(2.6); }
  100% { transform: scale(0, 0.004); filter: brightness(0.4); }
}
.lightbox.is-open .lightbox-frame { animation: crt-on 560ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }
/* keep the overlay up while the tube collapses, then let the usual fade run */
.lightbox.is-closing { opacity: 1; visibility: visible; transition: none; }
.lightbox.is-closing .lightbox-frame { animation: crt-off 400ms cubic-bezier(0.6, 0, 0.9, 0.5) forwards; }
.lightbox.is-closing .lightbox-bar { opacity: 0; transition: opacity 0.2s ease; }
@media (prefers-reduced-motion: reduce) {
  .lightbox.is-open .lightbox-frame, .lightbox.is-closing .lightbox-frame { animation: none; }
  .lightbox-frame.is-loading::after { animation: none; }
}

/* --- switched-off screens: video tiles ---------------------------------- */
.tile::before, .work-frame::before, .case-media::before {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; border-radius: inherit;
  background: radial-gradient(110% 92% at 50% 50%, transparent 56%, rgba(0,0,0,0.5) 100%);
  transition: opacity 0.4s ease;
}
.tile:hover::before, .tile:focus-visible::before,
.work:hover .work-frame::before, .work:focus-visible .work-frame::before,
.case-media:hover::before, .case-media:focus-visible::before { opacity: 0.5; }
/* the screen wakes: a flash of brightness as the tube warms, then settles */
@keyframes crt-wake     { 0% { filter: brightness(0.4) contrast(1.3); } 30% { filter: brightness(1.35) contrast(1.05); } 100% { filter: brightness(1); } }
@keyframes crt-wake-dim { 0% { filter: brightness(0.35) contrast(1.3); } 30% { filter: brightness(1.3); } 100% { filter: brightness(0.65); } }
.work:hover .work-frame img, .work:focus-visible .work-frame img,
.case-media:hover img, .case-media:focus-visible img { animation: crt-wake 0.5s ease-out both; }
.tile:hover img, .tile:focus-visible img { animation: crt-wake-dim 0.5s ease-out both; }
/* tuner readout on the duration badge */
.tile-time, .work-time { font-family: var(--mono); font-weight: 500; letter-spacing: 0.08em; font-variant-numeric: tabular-nums; }
.tile-time b, .work-time b { font-weight: 600; color: var(--pink-text); margin-right: 8px; }
.tile-time b:empty, .work-time b:empty { display: none; }
@media (prefers-reduced-motion: reduce) {
  .work:hover .work-frame img, .case-media:hover img, .tile:hover img { animation: none; }
}

/* --- no signal ----------------------------------------------------------- */
.nosignal { background: #000; overflow: hidden; }
.nosignal::before {
  content: ''; position: absolute; inset: -8px; pointer-events: none;
  background-image: var(--noise-fine); background-size: 160px 160px;
  opacity: 0.55; animation: static-jitter 360ms steps(1, end) infinite;
}
.nosignal .nosignal-label {
  position: absolute; right: 9%; top: 50%; z-index: 1; transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  font-family: var(--mono); font-size: 13px; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(255,255,255,0.88); text-shadow: 0 1px 8px rgba(0,0,0,0.9);
}
.nosignal .nosignal-label i { font-style: normal; font-size: 11px; color: var(--pink-text); }
@media (max-width: 700px) { .nosignal .nosignal-label { display: none; } }
/* small version for empty filter results */
.nosignal-mini {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  margin-top: 28px; padding: 52px 24px; border-radius: 12px; overflow: hidden; text-align: center;
  background: #000; border: 1px solid var(--border-soft); color: var(--muted);
}
.nosignal-mini[hidden] { display: none; }
.nosignal-mini::before {
  content: ''; position: absolute; inset: -8px; pointer-events: none;
  background-image: var(--noise-fine); background-size: 160px 160px;
  opacity: 0.16; animation: static-jitter 360ms steps(1, end) infinite;
}
.nosignal-mini .nosignal-label {
  position: relative; font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--pink-text);
}
.nosignal-mini p { position: relative; margin: 0; }
@media (prefers-reduced-motion: reduce) { .nosignal::before, .nosignal-mini::before { animation: none; } }

/* --- photos as screens ---------------------------------------------------
   Stills get the tube too: a curved-glass vignette, a whisper of scanlines,
   and a one-off power-on flicker when they scroll into view. Colour is left
   alone – the treatment is the glass, not a filter on the picture. */
.slot:not(.slot-empty) { border-radius: 12px; }
.card-media .slot:not(.slot-empty) { border-radius: 10px 10px 0 0; }
.slot:not(.slot-empty)::before {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; border-radius: inherit;
  background: repeating-linear-gradient(180deg, rgba(0,0,0,0) 0 2px, rgba(0,0,0,0.22) 2px 3px);
  opacity: 0.45; mix-blend-mode: multiply;
}
.slot:not(.slot-empty)::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; border-radius: inherit;
  background:
    radial-gradient(115% 95% at 50% 50%, transparent 60%, rgba(0,0,0,0.5) 100%),
    linear-gradient(180deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0) 22%);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.06);
}
/* JS arms each photo (collapsed to a bright line, like a set that is off) and
   powers it on with the lightbox's own crt-on once it is nearly all on
   screen – one after another when several arrive together. No JS, or
   reduced motion: nothing is armed and the photos simply sit there. */
.slot:not(.slot-empty) img { transform-origin: 50% 50%; }
.slot.is-armed img { transform: scale(0.55, 0.004); filter: brightness(3); }
.slot.is-armed.is-on img { animation: crt-on 560ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }
/* full-bleed hero backdrops: scanlines only – the scrims already do the glass */
.page-hero-media::before {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(0,0,0,0) 0 3px, rgba(0,0,0,0.16) 3px 4px);
  opacity: 0.5;
}
.page-hero-media.nosignal::before { background-image: var(--noise-fine); background-size: 160px 160px; opacity: 0.55; }
@media (prefers-reduced-motion: reduce) { .slot.is-armed img { transform: none; filter: none; animation: none; } }

/* --- channel change between pages ---------------------------------------
   html.is-tuning paints full-screen static with the page's data-tune label;
   .is-tuned fades it away once the new page has its picture. */
html.is-tuning::before {
  content: attr(data-tune); position: fixed; inset: 0; z-index: 300;
  display: grid; place-items: center; pointer-events: none;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 12px; letter-spacing: 0.22em; text-transform: uppercase;
  color: rgba(255,255,255,0.85); text-shadow: 0 1px 6px rgba(0,0,0,0.9);
  background: #000 var(--noise-fine); background-size: 160px 160px;
  animation: static-jitter 360ms steps(1, end) infinite;
  opacity: 1;
}
html.is-tuning.is-tuned::before { opacity: 0; animation: none; transition: opacity 0.5s ease; }

/* ==========================================================================
   Textura pixel icons – subjects (services, process, sectors). Lucide keeps
   the UI glyphs. `.picon-dark` carries its own offset colours; `.picon-mono`
   inherits currentColor. Sizes stay multiples of the 20 px grid.
   ========================================================================== */
.picon { display: inline-block; flex: none; vertical-align: middle; }
.card-icon { display: flex; margin-bottom: 20px; }
.card-icon .picon { width: 60px; height: 60px; }
.card-icon--sm { margin-bottom: 14px; }
.card-icon--sm .picon { width: 40px; height: 40px; }
.h3-icon { display: flex; align-items: center; gap: 12px; }
.h3-icon .picon { width: 28px; height: 28px; }
.nav-dd-icon .picon { width: 20px; height: 20px; }
.chip { display: inline-flex; align-items: center; gap: 8px; }
.chip .picon { width: 16px; height: 16px; opacity: 0.75; }
.chip.is-on .picon, .chip:hover .picon { opacity: 1; }
.pstep-icon { margin-left: auto; display: flex; }
.pstep-icon .picon { width: 40px; height: 40px; }
.stat .picon { width: 36px; height: 36px; }
@media (max-width: 900px) {
  .card-icon .picon { width: 48px; height: 48px; }
  .pstep-icon .picon { width: 32px; height: 32px; }
}
