/* Hero variants on the real home page (build.py --hero): the parts all six share. Everything is under
   .hx (the hero section) or body.hx-on, so the site's own styles.css stays as it is. Colours and word
   widths come from build.py as custom properties on the section (--design, --film, --code, --ai,
   --w-almighty, --w-guys, --w-ag, --cap). */

.hx {
  --vh: 1svh;
  --ls: -0.01em;                       /* the wordmark tracking; heroes/__init__.py measures with it */
  --sa-b: var(--ui-b, env(safe-area-inset-bottom, 0px));  /* styles.css: safe area plus a floating bar */
  position: relative;
  scroll-snap-align: start;            /* phones: the hero is the first snap stop, free scroll inside */
  color: var(--ink);
}
@supports not (height: 1svh) { .hx { --vh: 1vh; } }

.hx-word {
  margin: 0; font-family: var(--f-display); font-weight: 900; text-transform: uppercase;
  letter-spacing: var(--ls); line-height: .8; white-space: nowrap; font-kerning: normal;
}
.hx-label { font: 600 13px/1.2 var(--f-label); text-transform: uppercase; letter-spacing: .04em; }

/* The scroll cue, lower right. */
.hx-cue {
  position: absolute; right: var(--pad); bottom: calc(var(--pad) + var(--sa-b)); z-index: 5;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  font: 600 12px/1 var(--f-label); letter-spacing: .08em; text-transform: uppercase; pointer-events: none;
}
.hx-cue__line { position: relative; width: 1px; height: 40px; overflow: hidden; background: color-mix(in srgb, currentColor 30%, transparent); }
.hx-cue__line i { position: absolute; left: 0; top: 0; width: 1px; height: 40%; background: currentColor;
  transform: translateY(-100%); animation: hx-cue 1.8s cubic-bezier(.6, 0, .3, 1) infinite; }
@keyframes hx-cue { to { transform: translateY(250%); } }
.hx-narrow .hx-cue { display: none; }

/* The header bar shows from the start with a hero; while the hero is on screen its wordmark text
   steps back to the halo alone (the hero carries the name). */
.hx-top .bar__logo span { display: none; }
.hx-top .bar__logo .halo--logo { margin-bottom: 0; }

/* --- the «Featured work» column that starts the opening instead of the wordmark column ---------- */
.intro--hx { justify-content: flex-end; min-height: 0; padding-top: 110px; }
.intro__count { opacity: .7; }
.intro__title {
  font: 900 12vw/.8 var(--f-display); text-transform: uppercase; text-wrap: balance;
  font-size: min(calc((100vw - 2 * var(--pad)) / var(--fit, 1)), 24vh);
}
.h .intro--hx { justify-content: flex-end; padding-top: 110px; }
.h .intro--hx .intro__title { font-size: min(calc((var(--intro) - 2 * var(--pad)) / var(--fit, 1)), 30vh); }
.h .intro--hx .intro__count { margin-top: auto; }
/* Phones and touch screens: the hero hands straight over to the first project section. */
@media not all and (min-width: 1024px) and (hover: hover) and (pointer: fine) {
  .intro--hx { display: none; }
}

/* Reduced motion: nothing loops, nothing drifts. */
.hx-rm .hx-cue__line i { animation: none; transform: translateY(80%); }

/* F: the mission. Four strands in the discipline colours, each with a short cut of its work at the tip,
   close into the one halo over the wordmark as you scroll; then the mission headline and statement
   land (the home's separate mission section is left out with this hero). */
.hx-f { height: calc(100 * var(--vh) + 200vh); }
/* The paper is painted on the stage itself: the crew loop multiplies onto it (the sticky stage is its own
   stacking context, so the body behind it is not part of the blend). */
.hx-f__stage { position: sticky; top: 0; height: 100vh; height: 100lvh; overflow: hidden; background: var(--paper); }
.hx-f__frame { position: absolute; inset: 0 0 auto; height: calc(100 * var(--vh)); }
.hx-f__weave { position: absolute; z-index: 2; inset: 0; width: 100%; height: 100%; max-width: none; overflow: visible; }
.hx-f__s { display: none; }  /* colours only: f.js draws the strands on the canvas */
.hx-f__cv { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; max-width: none; pointer-events: none; }
/* Scroll variants (build.py --scroll): «timed» plays the hero on one screen, «native» keeps a shorter
   scroll-driven hero without assistance, «glide» is the long hero with the assisted glide. */
.hx-f--scroll-timed { height: calc(100 * var(--vh)); }
.hx-f--scroll-native { height: calc(100 * var(--vh) + 120vh); }
.hx-f__halo { stroke: var(--ink); opacity: 0; }
.hx-f__thumbs { position: absolute; z-index: 3; inset: 0; pointer-events: none; }
/* Bigger on desktop (Jean, 01.10: «очень маленькие картинки в Hero Section. Давай сделаем их побольше»), and each is
   a link to its discipline's work: the label gets an arrow and the frame thickens under the pointer. */
.hx-f__thumb { position: absolute; left: 0; top: 0; width: clamp(150px, 18vw, 320px); width: round(clamp(150px, 18vw, 320px), 2px);
  aspect-ratio: 16 / 10; pointer-events: auto; cursor: pointer; text-decoration: none;
  border: 3px solid var(--c); background: var(--c); transition: box-shadow .2s; }
.hx-f__thumb:hover, .hx-f__thumb:focus-visible { box-shadow: 0 0 0 4px var(--c); outline: none; }
.hx-f__thumb:hover b::after, .hx-f__thumb:focus-visible b::after { content: " →"; }
/* A layer of their own only while the strands move (f.js sets is-moving), not for the whole visit. */
.hx-f__thumbs.is-moving .hx-f__thumb { will-change: transform; }
.hx-f__thumb video { display: block; width: 100%; height: 100%; max-width: none; object-fit: cover; }
/* The label under each tile says what the discipline covers (the discipline's `tag`). */
.hx-f__thumb b { position: absolute; left: -3px; top: 100%; display: block; padding: 5px 8px 4px; background: var(--c);
  color: var(--on); font: 600 13px/1 var(--f-label); letter-spacing: .04em; text-transform: uppercase; white-space: nowrap; }
/* The crew as inflatable toys round the halo (f.js places, layers and moves them each frame). The
   container makes no stacking context, so each toy's z-index sorts it against the halo: 1 behind the
   weave (2), 3 inside the ring under the front arc (.hx-f__front, 5), 6 and up in front. */
.hx-f__toys { position: absolute; inset: 0; pointer-events: none; }
.hx-f__toy { position: absolute; left: 0; top: 0; max-width: none; visibility: hidden; transform-origin: 50% 100%;
  pointer-events: auto; cursor: pointer; user-select: none; -webkit-user-select: none; -webkit-user-drag: none;
  -webkit-tap-highlight-color: transparent; touch-action: pan-y; }
.hx-f__front { position: absolute; inset: 0; z-index: 5; width: 100%; height: 100%; max-width: none; overflow: visible;
  pointer-events: none; }
.hx-f__front path { stroke: var(--ink); stroke-linecap: butt; opacity: 0; }
.hx-f__type { position: absolute; left: 0; right: 0; bottom: 10svh; z-index: 2; display: grid; justify-items: center;
  text-align: center; padding: 0 var(--pad); }
.hx-f__word { display: flex; gap: .2em; font-size: calc(72vw / var(--w-ag)); }
.hx-f__mission { display: grid; justify-items: center; gap: 12px; margin-top: clamp(18px, 3vh, 34px); }
.hx-f__head { margin: 0; font: 900 clamp(30px, 3.4vw, 56px)/.9 var(--f-display); text-transform: uppercase; letter-spacing: var(--ls); }
.hx-f__statement { margin: 0; max-width: 60ch; font-size: clamp(15px, 1.15vw, 18px); line-height: 1.45; }
@media (max-width: 760px) {
  /* Two lines that nearly touch (Jean, 28.09): each line box is trimmed to its capitals (--trim-t,
     --trim-b from the font's metrics), then GUYS sits 4 % of ALMIGHTY's cap height below it. */
  .hx-f__word { flex-direction: column; gap: 0; font-size: inherit; line-height: 1; }
  .hx-f__word .hx-l1, .hx-f__word .hx-l2 { display: block; margin: calc(-1em * var(--trim-t)) 0 calc(-1em * var(--trim-b)); }
  /* --wm: the wordmark's width, the screen less the margins, but on short phones (an iPhone SE) at most what
     leaves the toys room above it (29.09, fit audit). */
  .hx-f__word { --wm: min(88vw, 42svh); }
  .hx-f__word .hx-l1 { font-size: calc(var(--wm) / var(--w-almighty)); }
  .hx-f__word .hx-l2 { font-size: calc(var(--wm) / var(--w-guys));
    margin-top: calc(-1em * var(--trim-t) + 0.04 * var(--cap) * var(--wm) / var(--w-almighty)); }
  .hx-f__statement { font-size: 15px; }
}
.hx-narrow .hx-f__thumb { width: 44vw; width: round(44vw, 2px); overflow: visible; transform-origin: 50% 0; }
.hx-narrow .hx-f__thumb video { aspect-ratio: 16 / 10; height: auto; }
.hx-narrow .hx-f__type { bottom: calc(22px + var(--sa-b)); }
.hx-narrow .hx-f__head { font-size: 34px; }
.hx-narrow .hx-f__mission { gap: 10px; margin-top: 18px; }
/* f1: what we do, in two lines at the top beside the logo (Jean, 28.09: «чуть больше текста на самом
   стартовом экране сверху справа от лого»). It steps back as the strands start to move. On phones the
   bar fills the top row, so the line sits under it and the tiles start below it (f.js). */
.hx-f__lede { position: absolute; z-index: 3; top: calc(var(--pad) + 9px); left: calc(var(--pad) + 88px);
  max-width: 34ch; margin: 0; font: 400 clamp(16px, 1.25vw, 20px)/1.3 var(--f-body); text-wrap: pretty; }
/* The strands hang from the top edge on phones and cross the line: it gets the paper ground the bar's
   boxes have, so it reads over them. */
.hx-narrow .hx-f__lede { left: var(--pad); right: auto; max-width: calc(100% - 2 * var(--pad)); padding: 7px 10px 8px;
  background: var(--paper); font-size: 15px; line-height: 1.35; }
/* f2: the scroll cue on phones too, centred above the wordmark (f.js places it). */
.hx-narrow .hx-f--assist .hx-cue { display: flex; left: 0; right: 0; bottom: auto; top: 0; }
.hx-rm .hx-f { height: auto; }
.hx-rm .hx-f__stage { position: relative; height: calc(100 * var(--vh)); }
