Поправка 2026-08-30 (Жан). Везде ниже, где сказано «наш сигнальный красный
#FB3B1E» или «наш акцент — красный», — ошибка: у Colossus постоянного цветного акцента НЕТ (брендбук: монохром «от белого до графита», сезонные цвета только по согласованию). Технические выводы о референсах остаются в силе; сравнения «их красный = наш» — нет.Статус: файл писался по ходу разбора, блок за блоком (защита от потери контекста). Разведчик w2. Дата: 2026-08-29. Инструменты:
curl(разметка, бандлы, шейдеры, размеры ассетов, HTTP-статусы) и машинный зондprobe-browser.jsonl(headless Chromium, перехватgetContext, окно 8 секунд). Браузерная автоматизация по условию задачи не использовалась. Все вердикты ниже опираются на прочитанный исходный код, а не на впечатление от страницы.
Зонд честен, но у него три системные слепые зоны, и все три меняют чтение результатов. Эти поправки касаются не только моего участка — их стоит учесть всем, кто читает тот же JSONL.
ogl в script_libs — почти всегда ложное срабатывание. Проверка ищет подстроку ogl
в URL скрипта, а её содержат googletagmanager.com и слово googleweblight внутри
ботовой регулярки Next.js. Строка script_libs=['ogl'] при webgl_ctx=[] означает
«стоит Google Tag Manager», а не «подключена библиотека OGL». Проверено на Draaimolen:
пять совпадений ogl в первых чанках — все из регулярки Next.
То же относится к three: у Holzmarkt совпадение даёт файл threedee.js, внутри
которого Adobe Animate, а не three.js.webgl_ctx непустой при canvases=0 и без глобали THREE — это, как правило, не графика,
а снятие отпечатка видеокарты антибот-скриптами (reCAPTCHA v3, маячок Cloudflare).
Три сайта участка попали в отчёт как трёхмерные именно так. Разобрано в отбраковке.--use-gl=swiftshader. Сцена, которая стартует после
клика, после менеджера согласия или по IntersectionObserver глубоко на странице, в зонд не
попадает; медленный сайт под шестью параллельными контекстами отдаёт fail: TimeoutError.
Поэтому is3d=False означает «не доказано за 8 секунд», а не «3D нет», а TimeoutError —
не «сайт мёртв». Наш второй по значимости результат, Bootshaus, лежит именно в строке
с таймаутом.Надёжный признак настоящего 3D в этом отчёте — непустой webgl_ctx вместе с глобалью
THREE / BABYLON или ненулевым числом холстов; всё остальное требует чтения исходника.
Из 88 адресов настоящее авторское 3D нашлось у пяти, и это ровно тот результат, который задача предсказывала: клубы 3D почти не делают. Но найденное отвечает на главный вопрос утвердительно — клубный сайт может быть трёхмерным и не выглядеть демо-роликом агентства, и три из пяти доказательств лежат в нашей палитре без всякой подгонки.
Порядок: 1) Teletech — 3D как несущая конструкция страницы, палитра совпадает до значения токена; 2) Bootshaus — металлический логотип в подвале и лучший на участке ответ на запрет перекрашивать знак: красное подаётся светом; 3) Depot Mayfield — полноэкранные кадры плоскостями в WebGL, волновой зум и шторка-вскрытие, и единственное доказанное цифрой попадание в наш бюджет (three-чанк 113 кБ gzip); 4) Institut für Zukunft — гиперболический вихрь на курсоре без единого ассета плюс переход, переживающий навигацию; 5) Wilde Möhre — кроссфейд портретов по карте смещения, техника без мира.
Три вещи, которые участок доказал попутно и которые дороже отдельных приёмов:
--darkest-hour:#0a0a0a и --dusk:#141414
совпадают с нашим фоном и панелью буквально, у Depot Mayfield акцент #ff3814 против нашего
#FB3B1E, у Bootshaus контровой свет #F74300, у IFZ панель #141414 и серый #8c8c8c.
Четыре независимых тёмных клубных сайта пришли к одному и тому же набору.Движок (доказательство). Зонд: is3d=True, webgl_ctx=['webgl2'], глобали THREE,
__THREE__, gsap, Lenis, два холста на странице. Исходник подтверждает и уточняет: сайт собран
на Webflow, но всю графику держит на собственном CDN assets.teletech.events —
three.min.js (616 кБ), GLTFLoader.js (108 кБ), meshopt_decoder.js, OrbitControls.js,
gsap.min.js + CustomEase + ScrollTrigger, lenis.min.js, splittype.min.js,
grained.min.js (зерно, 2.3 кБ). Модель — tt-3d-rp-opt.glb (1.51 МБ, сжата meshopt),
окружение — winter_evening_1k.hdr (1.49 МБ). Весь авторский код лежит открытым текстом в двух
инлайн-скриптах страницы (9.6 кБ и 18.8 кБ) — читается целиком, копируется построчно.
Палитра — почти наша, до токена. В CSS-переменных сайта: --darkest-hour:#0a0a0a
(в точности наш фон), --dusk:#141414 (в точности наша секционная панель), --midnight:#0d0d0d,
--haze-grey:#1e1e1e (наш диапазон волосяных линий), --power-white:#f0f0f0 (против нашего
#F3F3F3), и ровно один красный акцент --digital-blood:#c13243. Даже имена переменных
индустриальные. Это не «похожий вайб» — это доказательство, что наша палитра уже отработана
на живом клубном сайте с 3D.
Что там происходит. Открывается механическая диафрагма: пятичастная маска (верхняя кромка,
средний ряд из четырёх полос, нижняя кромка) сначала расходится по горизонтали, потом кромки
уезжают вверх-вниз, а под ней канвас-контейнер съезжает с масштаба 1.2 в 1 на авторской кривой
CustomEase("M0,0 C0.14,0.86 0.37,0.96 1,1") — резкий старт, длинный мягкий хвост. По углам
прелоудера прочерчиваются уголки-кроншпили: SVG-линии, рисующие себя через stroke-dashoffset.
Дальше в hero стоит GLTF-объект с металлическим материалом (metalness 0.5, roughness 0.2,
envMapIntensity 1.5), освещённый HDR-окружением через PMREMGenerator и двумя контровыми
источниками контрастных цветов. По скроллу морф-таргет Break разламывает объект на куски
(прогресс скролла с квадратичным замедлением, первый экран — мёртвая зона), одновременно поворачивая
его на 89°. Поверх непрерывно дёргаются пять случайных морф-таргетов Glitch_1…5 со случайной
амплитудой и длительностью 50–200 мс. Отдельно на обычные <img> навешан второй WebGL-слой:
плоскость с шейдером, который смещает UV по полю скоростей курсора, хранящемуся в DataTexture
34×34 с релаксацией 0.9 — изображение течёт под мышью и медленно затягивается обратно.
ЧТО БЕРЁМ для Колоссуса.
- Прелоудер (пик 13) — готовая механика, не идея. Наша задача — «маска перехода в hero, а не
заставка перед пустотой»; здесь она разобрана на элементы: раскрывающаяся диафрагма + масштаб
hero 1.2 → 1 + именно эта кривая ease. Уголки-кроншпили, рисующие себя stroke-dashoffset, —
прямое попадание в бренд-девайс №6 (рамки/блоки) и в «полигон». Наши предохранители,
которых у них нет, ставим сверху: лимит ~1.5 с (у них 3.6 с), скип кликом, sessionStorage
на повторный визит, prefers-reduced-motion — мимо.
- Рецепт «жидкого металла» (пик 17) — целиком. metalness около 0.5 при roughness около
0.2 плюс scene.environment из env-карты плюс два контровых направленных света контрастных
цветов. Мы подставляем свои: сигнальный красный #FB3B1E в один контровой и холодный белый
#F3F3F3 во второй — знак остаётся белым, металл ловит красный рефлекс, красное не становится
поверхностью. Это же ложится на ховер-материал карточек цифр и CTA-плит.
- Разлом по скроллу — драматургия для монолита. Морф-таргет на прогрессе скролла с мёртвой
зоной в первый экран — механика, которая превращает статичный объект в раскадровку: монолит
Колоссуса может расслаиваться на бетонные плиты по мере ухода со второго экрана. Мёртвая зона
важна: hero не дёргается от первого же движения колеса.
- Тёкущая под курсором картинка (DataTexture + релаксация) — вторая жизнь HÖR-списка.
Дешёвый шейдер, не требующий модели: плоскость, текстура, сетка 34×34. Это альтернатива красной
заливке строки для той части элементов, где по пику 17 нужен металл: наведение гонит волну по
кадру артиста позади списка.
- Самозапуск эффекта. Через 1.6 с после загрузки главной они программно рассылают
mousemove по контейнерам, чтобы поверхность ожила сама и показала, что она интерактивна.
Приём стоит копейки и снимает главную проблему ховер-эффектов: без него половина посетителей
никогда не узнает, что кадр реагирует.
- Детект слабого режима через video.play(). Промис от play() ловится, и на отказ
(iOS Low Power Mode) видео-слой просто гасится. Это честный, работающий capability-гейт
для нашего видео-hero — в дополнение к saveData и reduced-motion.
- CSS-мелочь с большим эффектом: класс .flicker — 20-шаговый кейфрейм дрожания
непрозрачности с шагом 0.03 с, отключаемый на мобильном. Мерцание лампы даром, без канваса.
ЧТО НЕ БЕРЁМ.
- Их бюджет. three.min.js полной сборкой 616 кБ, модель 1.5 МБ, HDR 1.5 МБ — больше трёх
мегабайт только на 3D. Наш потолок: three-чанк ≤160 кБ асинхронно, медиа ≤1.5 МБ на первый экран.
Значит: древотряска импорта three, вместо HDR — процедурная env-карта из кадра монолита
(она у нас уже есть), модель через meshopt/Draco и жёсткий бюджет полигонов.
- Цветовую схему сцены. Их контровые — розовый #ff1493 и голубой #1e90ff, а амбиент синий.
Это киберпанк-подсветка, у нас один акцент; берём схему освещения, не цвета.
- Прелоудер на каждый визит и его длину. 3.6 секунды без скипа и без памяти о визите —
ровно то, что наши предохранители запрещают.
- Стеклянно-глючную типографику. Их текст на ховере пересыпается случайными символами
(applyGlitchEffect) — это чужой тон голоса; у нас вход текста Zentry-масками и смешанный курсив.
- Мини-игру и OrbitControls (у них он подключён и полностью выключен — мёртвый вес).
ВАУ / ТРУД. ВАУ — очень высокий: единственный на всём участке клубный сайт, где 3D не
демонстрация, а несущая конструкция страницы, и при этом он в нашей палитре и в нашей интонации.
ТРУД — высокий, но делимый: шейдер искажения кадра (DataTexture + релаксация) — день работы и
десятки строк, прелоудер-диафрагма — день на GSAP-таймлайн без всякого WebGL, а вот
разлом модели морф-таргетом требует авторской модели монолита с шейп-ключами в Blender — это
отдельная производственная задача, не фронтенд. Порядок внедрения ровно обратный сложности:
диафрагма → искажение кадра → металл на карточках → разлом монолита последним.
Движок (доказательство). Зонд упал по таймауту (страница медленная, поверх висит баннер
согласия CookieFirst) — это ровно тот случай, когда is3d=False означает «не доказано за 8 секунд».
Исходник закрывает вопрос: в разметке лежит <canvas id="footer-emblem-canvas"> внутри
.footer-partners-container, страница объявляет importmap
("three": "…three@0.170.0/build/three.module.js", three/addons/) и подключает модуль
/js/emblem-3d.js — 5.3 кБ авторского кода, читаемого целиком. Внутри: THREE.WebGLRenderer
с powerPreference:'low-power', GLTFLoader, модель /img/logo.gltf (154 кБ) и полный
PBR-набор карт (color / normal / roughness / metalness).
Что там происходит. Логотип клуба живёт в подвале как физическая металлическая отливка:
холст 200×200 (150 на мобильном), ортографическая камера, MeshStandardMaterial с
metalness 0.8, roughness 0.6 и картой нормалей со normalScale 0.1 — то есть у знака есть
литая шершавая поверхность, а не блеск. Свет — три источника: белый ключевой, синеватый заполняющий
0x8888ff и контровой 0xF74300 (rgb 247,67,0). Знак не перекрашен: он остаётся своим,
но ловит фирменный оранжево-красный рефлекс по кромке. Появляется он по скроллу: как только верх
секции пересекает низ экрана, на дистанции ровно 200 пикселей прогресс с кубическим замедлением
гонит одновременно blur(15px → 0), scale(6 → 0.2), opacity и поворот pivot.rotation.y
на половину оборота — эмблема будто выплывает из расфокуса и встаёт на место. На 0.8 прогресса
она отпускает бегущую строку партнёрских логотипов (marquee-ready), на 0.95 — ставит класс
emblem-done. Ниже эмблемы в этой же секции едет marquee: Absolut, Bacardi и остальные.
ЧТО БЕРЁМ для Колоссуса.
- Главный приём — красное как СВЕТ, а не как краска. Брендбук прямо запрещает перекрашивать
логотип, и здесь показано, как обойти запрет без нарушения: белый знак, контровой источник
сигнального красного. #F74300 у них против нашего #FB3B1E — практически одно значение.
Логотип остаётся белым по букве правила, а красное присутствует физически. Это лучший ответ
на «красное ≤ фразы» из всей выборки.
- Масштаб дозы. 200×200 пикселей 3D в подвале — доказательство, что «настоящее 3D у клуба»
не обязано быть полноэкранной сценой. Для нас это готовый третий носитель жидкого металла
рядом с карточками цифр и CTA-плитами, причём самый дешёвый по риску.
- RAF по требованию — эталонная реализация нашего закона эффектов. Флаг ticking, ранний
выход при дельте меньше 0.002, самоостановка цикла при устаканивании, passive на скролл-слушателе,
лерп displayEased к цели с коэффициентом 0.1 (критическое демпфирование вместо жёсткой привязки
к скроллу). Наш v3.1 требует «один RAF-менеджер» — вот как он выглядит в 60 строках.
- Явный тир для мобильного внутри одного эффекта. На десктопе размытие считается каждый кадр
и пишется в style.filter; на мобильном оно заменено переключением CSS-класса на пороге 0.15.
Не «отключить на мобильном», а «сделать дешевле» — это ровно то, чего требуют три наших
capability-тира.
- 3D как дирижёр секции. Прогресс эмблемы запускает бегущую строку партнёров. У нас в подвале
стоит та же полоса партнёрских логотипов (Red Bull, Jägermeister, Holsten, Pernod Ricard,
sxodim, zvuk…) — структура совпадает один в один, и приём «знак приземлился → полоса поехала»
переносится буквально.
- Материал знака. Карта нормалей со normalScale 0.1 при roughness 0.6 даёт не хром, а
литой металл. Для ДНК «металл и бетон» это точнее, чем зеркальный хром: у Колоссуса
жидкий металл — специя, а несущая фактура — тяжёлая, матовая.
ЧТО НЕ БЕРЁМ.
- Их вес — категорически. Четыре PBR-карты в JPEG весят 2.23 + 2.00 + 2.03 + 0.30 МБ, то есть
6.5 МБ текстур на холст 200×200, плюс three.module.js с jsdelivr на 1.31 МБ несжатым.
Утверждение «весь код 5 кБ» верно только про авторский файл и полностью неверно про полезную
нагрузку. У нас на этом месте: карты 512×512 в WebP (на 200 пикселях разницы не видно),
древотрясённый three в общем асинхронном чанке, никаких CDN-модулей на рантайме — статический
экспорт всё складывает локально.
- Отсутствие гейтов. Ни prefers-reduced-motion, ни saveData, ни фолбэка при отказе WebGL —
без канваса подвал остаётся пустым. У нас на этом месте обязателен статичный белый PNG знака.
- Синеватый заполняющий свет — лишний цвет в системе, у нас его роль возьмёт холодный белый.
ВАУ / ТРУД. ВАУ — средний по эффекту, но очень высокий по применимости: это не то, от чего падает челюсть, это то, что можно поставить на сайт целиком за один день и что делает подвал фирменным. ТРУД — низкий, самый низкий среди всего трёхмерного в участке: модель — экструзия существующего лого-PNG в Blender, кода около шестидесяти строк, риск по производительности почти нулевой из-за размера холста. Это правильная первая точка входа в 3D для проекта: если жидкий металл на карточках цифр окажется дорогим, металлический знак в подвале всё равно останется.
Движок (доказательство). Зонд: is3d=True, webgl_ctx=['webgl'], глобаль __THREE__,
в скриптах three, но canvases=0 — то есть три работает, а холста в DOM на момент проверки нет.
Исходник объясняет и это, и всё остальное. Тема WordPress собрана Vite с расщеплением на чанки:
main-47da3149.js (124 кБ) импортирует ./three-bdcc11be.js и ./vendor-1ec4eef9.js.
Внутри main лежат две авторские GLSL-программы (вершинная и фрагментная) открытым текстом,
класс масштабируемой текстуры, свой планировщик кадров и capability-проба
te = !!document.createElement("canvas").getContext("webgl2") — вот она и попала в зонд
как «контекст есть, холста нет». Сцена монтируется на элемент data-frontpage-hero;
переходы страниц — Barba.
Ключевая цифра для нас: three-чанк весит 113 кБ на проводе (gzip). Это ниже нашего потолка в 160 кБ на асинхронный three-чанк. То есть перед нами живое доказательство, что полноэкранное фото плоскостью в WebGL с авторским шейдером помещается в бюджет v3.1 — если собирать three с древотряской, а не тянуть UMD-сборку целиком, как Teletech.
Палитра — снова наша. В теме: #000 (69 использований), #fff, и ровно один акцент
#ff3814 (10 использований) плюс его тёмный вариант #e64f21. #ff3814 = rgb(255,56,20)
против нашего #FB3B1E = rgb(251,59,30). Разницу глазом не поймать.
Что там происходит. Полноэкранные кадры бетонного депо живут не картинками, а плоскостями
в WebGL, и с ними делают три вещи, которых в CSS не бывает.
Первое — uv_bg_cover: покрытие кадром вьюпорта посчитано прямо в шейдере, то есть
background-size: cover реализован в GLSL и работает на любом соотношении сторон.
Второе — uv_spec_zoom: приближение не равномерное, а волновое. От точки-якоря считается
расстояние, и коэффициент зума модулируется синусом этого расстояния
(1. + sin(dist * azoom * 0.8 * 3.14) * 0.2); та же функция применяется и к вершинам,
так что плоскость физически выгибается на ±0.05, пока текстура плывёт на ±0.2. Кадр не
приближается — он идёт волной от точки, куда смотрит пользователь.
Третье — вскрытие: uRevealProgress рубит картинку жёсткой вертикальной границей
(if (vUv.x > uRevealProgress) gl_FragColor = чёрный) и одновременно снимает добавочный зум
1 + (1 - progress) * 0.5. Кадр открывается слева направо чёрной шторкой и на ходу
отъезжает из приближения — как ворота депо, разъезжающиеся на пустой зал.
Мелочь мастера: финальные UV поджаты на процент (* 0.98 + vec2(0.01)), чтобы по краям
не лезли артефакты растяжения крайнего пикселя.
ЧТО БЕРЁМ для Колоссуса.
- Волновой зум как язык наших полноэкранных медиа-секций. Пик 3 и закон четырёх требуют
«большой контент» — полноэкранные кадры площадки. Обычный CSS-зум по ховеру выглядит как
сток. Волна от якоря — это ровно тот «охуенный эффект», который отличает наш кадр от чужого,
и он стоит одну шейдерную программу на все секции сразу.
- uv_bg_cover — забрать в наш шейдерный хелпер целиком. Это переиспользуемая утилита,
снимающая главную боль полноэкранного WebGL-медиа: корректный cover на любом вьюпорте
без пересчёта геометрии. Функция короткая, читается за минуту, экономит день отладки.
- Чёрная шторка uRevealProgress — механика вскрытия для секции «О пространстве» и /hire.
Пустой зал, открывающийся жёсткой границей, — это буквальная метафора «ворота открылись»,
и она дешевле любой видео-заставки. Сочетание «шторка + снятие зума» даёт ощущение веса,
которого нет у обычного fade.
- Планировщик кадров scheduleRender. Флаг af, отмена через cancelAnimationFrame,
опциональный потолок FPS через сравнение performance.now() — готовый скелет того самого
«одного RAF-менеджера на страницу» из v3.1, причём с ограничением частоты, которое нам
понадобится на мид-Android.
- Класс масштабируемой текстуры. Исходное изображение перерисовывается в промежуточный
2D-канвас нужного размера («cover»/«contain») и только потом уходит в GPU. Для нас это
прямой ответ на риск «30 кадров площадки в полном разрешении убивают видеопамять телефона».
- IntersectionObserver с порогом 0.15, ставящий видео на паузу вне экрана — гигиена,
которую наш видео-hero и лупы артистов обязаны иметь.
- Опции рендерера как дефолт: antialias:true, alpha только когда нет фона, stencil:false,
preserveDrawingBuffer:false. Мелочь, но stencil:false и отключённый
preserveDrawingBuffer — бесплатная экономия памяти на мобильном.
- Видео-текстуры в той же машинерии. Ветка isVideoTexture показывает, что тот же
плоскостной шейдер несёт и видео. Значит волновой зум и шторка применимы к нашему
hero-лупу, а не только к фотографиям.
ЧТО НЕ БЕРЁМ.
- powerPreference:"high-performance" без разбора. У Bootshaus в аналогичном месте стоит
low-power, и для нашего третьего capability-тира правильнее именно он: просить
дискретную видеокарту ради фонового кадра — это разряжать ноутбук посетителя.
- Отсутствие prefers-reduced-motion. Ноль совпадений во всём бандле. У нас это
обязательный гейт, не опция.
- Барба и WordPress-обвязку. У нас статический экспорт Next; переходы страниц решаются
своими средствами, тащить Barba в проект незачем.
- Шторку как единственный вход в кадр. Приём сильный и потому одноразовый: если каждая
секция открывается шторкой, к третьей это перестаёт читаться. Одна-две на весь сайт.
ВАУ / ТРУД. ВАУ — высокий и при этом «тихий»: эффект не кричит, он делает бетон кинематографичным, что и есть наша задача (бетонное депо продаёт себя тем же аргументом, что и Колоссус). ТРУД — средний: моделирования нет вообще, нужна одна шейдерная программа на плоскость и аккуратный менеджер текстур; половина работы уже написана и читается в их бандле. Это самый выгодный по соотношению «эффект к риску» пункт участка после подвального знака Bootshaus, и единственный, чья реализуемость в наших бюджетах доказана цифрой.
Движок (доказательство). Зонд: is3d=True, webgl_ctx=['webgl'], один холст. В списке первой
волны сайт стоял как «жёсткий ч/б текстовый интерфейс, смотреть структуру» — то есть за 3D его
никто не держал. Исходник переворачивает картину: тема WordPress собрана одним бандлом
main.d12a055f33fd49a449fc.js на 755 кБ, внутри которого лежит three.js (359 упоминаний THREE,
44 — WebGLRenderer) и полный текст авторского фрагментного шейдера с комментариями самого
разработчика — сборка не срезала их. Читается целиком, включая закомментированные строки
«comment this line in to wind up image in center».
Что там происходит. На весь экран лежит одна плоскость PlaneBufferGeometry(2,2) с камерой
на z=1 — классический полноэкранный квад без всякой перспективы, самый дешёвый способ иметь
шейдер на фоне сайта. В него подаётся текущая фоновая картинка (артист, событие) и пять униформ:
u_texture, u_time, u_warp, u_resolution, u_mouse. Шейдер строит гиперболический вихрь
с центром в курсоре: система координат переносится в точку мыши, координата смещается на
HYP / radius - HYP, где HYP = 0.4 * (1 / u_warp), а поверх накладывается вращение, у которого
угол растёт и со временем (полный оборот примерно за две минуты), и с близостью к центру по
кривой четвёртой степени. Картинка медленно закручивается воронкой вокруг курсора. Гашение
краёв сделано умно: alpha = min(SQRT_2 - radius, (radius - HYP + 0.2) * 8.0) умножается прямо
в RGB, а альфа принудительно ставится в единицу — то есть кадр уходит не в прозрачность, а
в чёрный, что на чёрном фоне и есть правильное растворение.
Самое интересное — u_warp не константа. Есть две функции, suckIn и spitOut, которые
тви́нят её между 1 и 0 за полсекунды на Quadratic.Out. При u_warp → 0 гиперболический
коэффициент уходит в бесконечность, и весь фон всасывается в точку курсора. Вызываются они
из клиентского роутера: сайт живёт на page.js с маршрутами /, /events/:date/:title,
/series, /series/:name, /artists, /artists/:name, /archive, /booking,
/safer-clubbing, /about, /contact, и каждый переход между страницами утягивает фон в
воронку и выплёвывает обратно уже с новой картинкой. Это и есть настоящий переход, переживающий
навигацию, — на этом участке он найден здесь, а не у Teletech (у Teletech load_grid оказался
просто CSS-классом сетки, не переходом; версию прошлого захода снимаем).
Их карта разделов почти дословно наша: события с датой и слагом, серии (у нас — бренды
JILT / JAR / ZVUK / Massive), артисты списком и по одному, архив, букинг (у нас — /hire),
safer-clubbing (у нас — «билеты и правила», этика zero tolerance), about, контакты.
Полезно не только как техника, но и как подтверждение структуры v3 живым клубом.
Палитра. В CSS: #fff (39 использований), серый #8c8c8c (27 — против нашего #888888),
#141414 (15 — наш секционный панельный тон в точности), #000, #1e1e1e, и ровно один
акцент — чистый жёлтый #ff0 (21). То есть система тождественна нашей — тёмная база, холодный
белый, один серый, ОДИН акцент, — расходится только оттенок акцента.
ЧТО БЕРЁМ для Колоссуса.
- Вихрь как ховер-фактура для HÖR-списка. По пику 5 позади списка артистов идёт
полноэкранное размытое медиа наведённого артиста. Наш v3.1 запретил живой blur и потребовал
пре-размытых WebP. Вихрь решает ту же задачу иначе и лучше: кадр позади списка не размывается,
а медленно закручивается вокруг курсора. Стоит это одну текстуру и один шейдер, никаких
деривативов, никакого blur на каждый кадр.
- Шейдер целиком — самый дешёвый носитель эффекта во всём участке. Ни модели, ни env-карты,
ни GLTF-лоадера: полноэкранный квад плюс сорок строк GLSL. Из всего трёхмерного, что здесь
найдено, это единственное, что укладывается в бюджет без единого дополнительного байта
ассетов.
- Гашение умножением в RGB при alpha = 1. Приём ровно под наш фон #0a0a0a: кадр гаснет
в чёрный, а не в дырку, и не требует ни прозрачного канваса, ни правильного порядка смешивания.
- suckIn / spitOut как язык переходов между страницами. У нас статический экспорт Next
с клиентской навигацией — значит фоновая сцена может пережить переход /artists →
/artists/<slug>: воронка утягивает кадр, роут меняется, воронка выплёвывает уже портрет
артиста. Это тот самый «охуенный эффект» на стыке разделов, а не внутри одного экрана.
- Ответ на «ховера нет на таче» — не заглушка, а другой ввод. У них:
Modernizr.touchevents && "ondeviceorientation" in window → u_mouse считается из beta
и gamma наклона устройства. То есть на телефоне вихрь ведётся не за пальцем, а за наклоном
корпуса. Для нашего мобильного тира это гораздо интереснее статичного градиента, и это
бесплатно.
- Промежуточный 2D-канвас перед загрузкой текстуры — тот же приём, что у Depot Mayfield:
картинка сначала рисуется в канвас нужного размера, потом уходит в THREE.Texture. Два
независимых сайта пришли к одному решению — значит это и есть правильный способ кормить
WebGL нашими тридцатью кадрами площадки.
- RAF со start()/stop() по флагу видимости — третья независимая реализация нашего
«одного RAF-менеджера». Закономерность подтверждена трижды: никто из них не крутит цикл вхолостую.
ЧТО НЕ БЕРЁМ.
- Жёлтый #ff0. Единственное расхождение с нашей ДНК, и принципиальное: кислотный жёлтый —
чужой голос. Механика акцента забирается, оттенок остаётся у них.
- Дистанционно устаревший стек. three версии примерно r80, Modernizr, page.js, Leaflet
с unpkg, всё одним бандлом на 755 кБ без расщепления. Технику берём, инженерию — нет.
- Скорость вращения. Полный оборот за 128 секунд — на их «медленном» сайте это уместно,
у нас фон под списком не должен уползать сам по себе; вращение стоит привязать только
к близости курсора, оставив временну́ю составляющую около нуля.
- Постоянно живой фон на всех страницах: у нас закон одного активного WebGL-контекста, значит
вихрь и монолит не могут гореть одновременно.
ВАУ / ТРУД. ВАУ — высокий, причём именно в нашем регистре: эффект не «трёхмерный», он
физический, тёмный и тихий, ровно как бетон с металлом. ТРУД — низкий: шейдер восстановлен
полностью и переносится почти без изменений, обвязка — полноэкранный квад и две функции тви́на.
Единственная нетривиальная часть — увязать suckIn/spitOut с навигацией Next, но это
фронтенд-работа без графики. По соотношению эффекта к затратам это лучший пункт участка.
Движок (доказательство). Зонд: is3d=True, webgl_ctx=['webgl'], глобали THREE,
__THREE__, gsap, один холст. Исходник: тема WordPress подключает свои
three.min.js, gsap.min.js, ScrollTrigger, Flip, ScrollToPlugin, а вся графика живёт
в overlay.js (44 кБ), где лежат две авторские фрагментные программы открытым текстом.
Что там происходит. WebGL здесь работает не на герое, а в оверлее артиста — во всплывающей
карточке. Обе программы делают одно: переход между двумя фотографиями через карту смещения.
Первая берёт яркость самих кадров как карту ((d.r + d.g + d.b) * 0.33) и разводит их по
горизонтали навстречу друг другу пропорционально прогрессу. Вторая честнее: подаётся отдельная
текстура displacement, из неё берётся вектор (disp.r, disp.g), и два кадра смещаются по нему
в противоположных направлениях — под углами PI * 0.25 и -PI * 0.75, повёрнутыми матрицей
getRotM. Итог смешивается через mix(t1, t2, progress). Кадры не растворяются друг в друге,
а как будто вытекают один из другого по общей текстуре шума.
ЧТО БЕРЁМ для Колоссуса. - Переход между портретами артистов. У нас на странице артиста и в HÖR-списке кадры меняются постоянно: строка списка ведёт свой фон, галерея артиста листает сеты. Кроссфейд по карте смещения — это фирменный способ менять кадр, и он не требует ничего, кроме второй текстуры. - Встречное смещение под двумя углами — важная деталь: именно противоположные направления дают ощущение, что один кадр вытесняет другой, а не что они просто смешались. Углы и матрица поворота переносятся константами. - Карта смещения как бренд-носитель. Вместо шумовой текстуры можно подать нашу собственную: фактуру бетона или искривлённую сетку из бренд-девайса №5. Тогда переход между кадрами физически идёт по нашей же графике — приём становится фирменным, а не стоковым.
ЧТО НЕ БЕРЁМ. Весь визуальный мир: иллюстративный лесной фестиваль, светлый фон
(setClearColor(0xeeeeee)), тёплая палитра — противоположный нашему полюс. Гейтов по
reduced-motion нет. Пиксель-рейшо ставится без потолка (window.devicePixelRatio без
Math.min(…, 2)) — на ретине это учетверённая нагрузка; у нас потолок обязателен.
ВАУ / ТРУД. ВАУ — средний: приём известный и растиражированный, узнаваемость даст только своя карта смещения. ТРУД — низкий, шейдер короткий и переносится как есть. Берётся как инструмент в набор, не как направление.
Для нас этот раздел часто выгоднее предыдущего: приёмы отсюда не тратят WebGL-контекст, не попадают под закон одного активного контекста и работают на тач-устройствах без отдельного тира.
Доказательство. Зонд: webgl_ctx=[], глобали gsap и Lenis. Исходник: Webflow плюс
GSAP 3.15 с ScrollTrigger, Lenis 1.0.36, Splide, Howler.js (аудио) и hls.js
(адаптивное видео). И главное — около шестисот строк авторского кода курсора,
оставленного в странице вместе с проектными комментариями разработчика, где он объясняет,
почему версия v10 лучше v8. Это редчайший случай: чужие проектные решения задокументированы
их же автором.
Что там происходит. За курсором тянется «червь» из пиксельных иконок. Ранняя версия держала
хвост целиком видимым, пока курсор не остановится, и только потом запускала волну затухания —
из-за чего иконки тупо стояли секунду. В нынешней версии у каждой иконки собственный возраст:
на каждую точку истории пишется временна́я метка, иконка живёт holdMs = 90 мс в полной
непрозрачности и гаснет за fadeMs = 420 мс. Побочный эффект автор считает главной находкой:
хвост стал зависеть от скорости — быстрый курсор даёт длинный червь (всё молодое), медленный
короткий, остановка растворяет его с хвоста, потому что хвост старше всех.
Скругление углов сделано отдельно и хитро: путь головы усредняется по длине дуги, а не по
времени, поэтому радиус задаётся в пикселях (cornerRadiusPx = 70) и не плывёт от скорости
курсора. Тонкость, которую автор специально оговаривает: усредняются только координаты, а
временна́я метка берётся строго из центрального отсчёта — иначе возраст размазался бы по
повороту и порядок затухания сломался бы.
ЧТО БЕРЁМ.
- Весь набор параметров как стартовые значения, если Колоссус получит свой курсор:
длина 40, шаг между элементами 0.35 от размера, followLerp 0.3, радиус скругления 70 px,
9 отсчётов ядра, holdMs 90, fadeMs 420, дополнительный конус хвоста 0.35. Это сэкономит
день подбора на глаз.
- Скругление по длине дуги — приём переносится на любую траекторию, а не только на курсор:
на протяжку, на путь бегущей строки, на любой след.
- Гашение следа на интерактивных элементах. Селектор .btn, a, .nav-bar-link,
[data-trail-hide], уход за 380 мс, возврат за 300 мс, полоса затухания — четверть длины
червя, и убирается он от головы к хвосту, потому что закрывает подпись именно та иконка,
что под курсором. Уровень внимания, которого у большинства кастомных курсоров нет.
- prefers-reduced-motion первой строкой. Проверка стоит до всей инициализации и просто
выходит из функции. Единственный сайт участка, где гейт сделан правильно, — эталон для нас.
- Тач не отключает эффект, а меняет его природу. Отдельная мобильная конфигурация
превращает след в самодвижущийся «конвой» со случайными углом (до 35°), кривизной и паузой
между запусками (0.8–2.6 с). То же решение, что у IFZ с наклоном устройства: на таче эффект
становится фоновой анимацией, а не исчезает. Для наших ховер-приёмов это готовая стратегия.
- Обработка режима энергосбережения — лучше, чем у Teletech. Видео пробуют запустить на
DOMContentLoaded, промис ловят молча, и тут же вешают повтор на первый click и
touchstart (с passive: true). В итоге на iPhone в Low Power видео стартует с первого
касания вместо того, чтобы остаться мёртвым. Это надо взять в наш видео-hero целиком.
- Ограничение шага симуляции dt = Math.min(50, now - lastFrameAt) — защита от скачка
после возврата на вкладку. Одна строка, снимает класс багов.
- Howler.js для аудио. У нас JILT.CAST с тремя аудио-эпизодами SoundCloud; Howler — рабочая
альтернатива, если понадобится свой плеер вместо чужого фасада.
ЧТО НЕ БЕРЁМ. Галерейный воздух и светлую подачу — это арт-институция, у нас плотная
индустриальная площадка. Загрузку иконок фетчем скрытой CMS-страницы с разбором её через
DOMParser — у нас статический экспорт, тот же результат даётся build-time JSON'ом. Зависимость
от Webflow и от CDN unpkg на рантайме.
ВАУ / ТРУД. ВАУ — высокий, если курсор вообще войдёт в проект (пока в v3 его нет; это кандидат на добавление). ТРУД — средний: логика непростая, но она полностью прочитана и параметризована.
Доказательство. Ни GSAP, ни Lenis, ни канваса: только jQuery. Вся моторика — рукописный CSS в теле страницы.
Что там происходит. Всё, на что можно нажать — ссылка на билеты, имя артиста, кнопка,
элемент круговых часов расписания, — на ховере получает filter: blur(4px). Один селектор,
одно правило, никакой библиотеки. Ощущение фирменное и мгновенно узнаваемое: интерфейс
расфокусируется под пальцем. Рядом — раскрытие описаний артистов через
max-height: 0 → transition 0.2s ease-out, полноэкранное фоновое видео на z-index: -1,
Impact для заголовков и Space Mono для служебного текста, свечение через
text-shadow: 0 0 10px и drop-shadow.
ЧТО БЕРЁМ. Мысль, а не пиксели: один моторный жест на весь сайт сильнее пяти разных.
У нас такой жест уже назначен — красная заливка строки на ховере (пик 5); Atonal подтверждает,
что этого достаточно, если применять последовательно везде. Аккордеон на max-height
переносится прямо в раскрытие треклистов /cast (пик 4 требует «раскрываются, не печатаются
простынёй»). Расфокус можно держать в запасе для второстепенных элементов, где красная заливка
была бы перебором по красной дисциплине.
ЧТО НЕ БЕРЁМ. filter: blur как основной ховер — на больших областях это дорого на
мобильном и конфликтует с нашим главным жестом. Палитру #f2ffec (белый с зелёным подтоном) —
у нас холодный белый.
ВАУ / ТРУД. ВАУ — низкий по отдельности, высокий по дисциплине. ТРУД — почти нулевой.
Доказательство. Зонд: webgl_ctx=[], глобаль только Lenis. Исходник объясняет расхождение
с описанием «WebGL-фон» из первой волны: сайт собран на WordPress с темой Lay, и у этой темы
есть встроенная функция WebGL-слайдшоу — но на всех рядах главной стоит класс-выключатель
no-webglslideshow. То есть движок есть, а сцена выключена. Строку «WebGL-фон» в
w2-clubs-north.md надо считать неверной для текущей версии сайта. Что осталось честного:
плавный скролл Lenis, бегущие строки, много видео, кастомный курсор темы, свои шрифты.
ЧТО БЕРЁМ. Ничего технически уникального; ценность — предостережение. Тема с богатыми эффектами не равна сайту с эффектами, и «клуб, но смело» здесь достигается типографикой и плотностью, а не графикой.
Доказательство. Свой сборочный бандл (dist/assets/app.1a2773d1.js), утилитарные классы,
и 512 упоминаний marquee в разметке главной.
Что там происходит. Бегущая строка у них не украшение, а полноценный компонент с
модификаторами: c-marquee c-marquee--white c-marquee--link на всю ширину, с рамками сверху
и снизу, и целиком является ссылкой на билеты. Тридцатилетний архив клуба подан той же
механикой.
ЧТО БЕРЁМ. Приём «широкая полоса-ссылка бегущей строкой» под наши CTA и под слэш-локи:
colossus®/jilt · colossus®/jar · colossus®/zvuk бесконечной лентой — это буквально
бренд-девайс №2, поставленный в движение. Важна именно компонентная дисциплина: один
компонент с модификаторами, а не пять разных бегущих строк.
ЧТО НЕ БЕРЁМ. Плотность применения: пятьсот вхождений — это перебор, у нас закон четырёх.
Доказательство. Настоящий Barba (67 упоминаний в main.js, разметка размечена
data-barba="wrapper" / "container" / "namespace"), GSAP, Locomotive Scroll
(data-scroll-container), прелоудер оформлен как веб-компонент <base-preloader> со стопкой
слов MUSIC / CULTURE / SPACE, и фоновый <audio> с треком прямо на главной. Важная деталь
родословной: тема лежит по пути app/themes/broadwick-live/_/js/dist/ — ровно та же структура,
что у Depot Mayfield (app/themes/depot-mayfield/_/dist/). Это один и тот же разработчик,
и Depot Mayfield — его же более поздняя, уже шейдерная работа. Наши пункты 3 и этот — две
ступени одной эволюции.
Что берём. Один приём, которого нет больше нигде на участке: тир по реальной скорости
сети. В сайте живёт служба-сердцебиение, которая замеряет соединение и пишет флаг
isLowNetwork в sessionStorage; переход между страницами читает этот флаг и выбирает,
играть богатую анимацию или дешёвую. Наш v3.1 описывает три capability-тира по устройству,
saveData и reduced-motion — сетевой тир их дополняет. Оговорка: собственное сердцебиение
стоит трафика и таймеров; современный бесплатный эквивалент —
navigator.connection.effectiveType плюс saveData, и брать надо идею, а не их реализацию.
Второе — прелоудер как веб-компонент со стопкой слов: у нас на этом месте слэш-локи
(colossus®/jilt), и оформление прелоудера отдельным компонентом упрощает наши предохранители
(лимит, скип, память о визите) — они живут в одном месте, а не размазаны по странице.
Что не берём. Автозапуск музыки на главной. Locomotive Scroll — у нас Lenis. Отсутствие
prefers-reduced-motion (ноль совпадений во всём бандле на 551 кБ).
colourfactory.com) — в списке значатся «Barba-переходы». Это ошибка
сопоставления: сайт сделан на Squarespace, никакого Barba нет, а слово нашлось в
списке стран («Barbados»). mix-blend-mode — стандартный твик Squarespace. Настоящая
ценность сайта — типографика (Alternate Gothic через Typekit) и масштаб подачи, не моушн.fielddayfestivals.com) — та же ошибка с Barba по той же причине. Реально
там есть штатный эффект зерна Squarespace (image-effect-film-grain.js) и шрифт
TWK Lausanne; типографическая система сильная, инженерия — коробочная.holzmarkt.com) — «canvas-анимация» верна, «three» в машинном отчёте —
ложное срабатывание: подключён файл threedee.js, но внутри него Adobe Animate / CreateJS,
то есть 2D-канвас, а не three.js. Полезное там другое: анимация включается только от 992 px
ширины и имеет аварийный выключатель прямо в адресе (?no3d=1), добавляющий классу html
метку disable-3d. Идею «URL-выключатель тяжёлой графики» стоит забрать для отладки и
для демонстраций клиенту.Задача предписывала искать в первой волне только трёхмерный слой и не пересказывать
REFERENCES.md. Результат проверки исходников — отрицательный и однозначный, и это само по
себе полезное знание. Ни у одного клуба и ни у одной площадки первой волны нет ни WebGL, ни
канваса, ни шейдера: Berghain, Tresor, HÖR, KHIDI, Bassiani, fabric London, FOLD,
Awakenings, Dekmantel, Time Warp, Magazine London, Broadwick, Drumsheds, Village Underground,
Shelter Amsterdam, Tresor.West — ноль совпадений по three, webgl, gl_FragColor,
ShaderMaterial, <canvas>, spline, pixi, curtains в разметке и подключённых скриптах.
Из первой волны трёхмерными остаются только три агентские работы, уже разобранные в
REFERENCES.md (igloo.inc — подтверждён зондом как webgl2 с глобалью THREE, lusion.co,
resn.co.nz) и недоступный отсюда ARMA17.
Практический смысл для проекта: тёмная клубная эстетика, которая нам нравится у Berghain, Tresor и HÖR, сделана вообще без графики — типографикой, плотностью, фотографией и цветом. Значит 3D у нас обязано быть добавкой к уже работающему плоскому языку, а не его заменой. Ровно поэтому порядок внедрения из пункта 1 (сначала прелоудер и шторки, потом металл, разлом модели последним) — не осторожность, а повторение чужого успешного пути.
Три сайта участка отмечены зондом как is3d=True, и все три — не про графику. Признак у них
общий и его стоит запомнить: непустой webgl_ctx при canvases=0 и без глобали THREE.
Это значит, что контекст создали на канвасе, которого нет в документе, — так снимают отпечаток
видеокарты антибот-скрипты.
exhibitionwhitecity.com) — WordPress на jQuery плюс маячок
Cloudflare Insights. Никакой графики.phonox.co.uk) — jQuery 1.8, плагин tubular (видео с YouTube фоном) и
reCAPTCHA v3. Контекст создаёт reCAPTCHA.tobaccodocklondon.com/spaces) — reCAPTCHA v3, Klaviyo, Flickity,
vanilla-lazyload. Тот же случай.Ценность Tobacco Dock для нас не в этом: он остаётся структурным донором B2B-ветки (пик 12), и его прилипшая форма заявки — приём вёрстки, а не графики. Никакого 3D там не было и нет.
Зонд: webgl и два холста — то есть WebGL настоящий. Источник: WordPress + Elementor +
Slider Revolution 6 (rs6.min.js), у которого свои WebGL-переходы между слайдами.
Отбраковка по двум причинам сразу: эффект коробочный, плагинный и узнаваемый как плагинный —
ровно то «выглядит как демо-ролик агентства», от чего нас предостерегает задача; и фестивальная
палитра противоположна индустриальной. Брать нечего, кроме напоминания, что WebGL в разметке
ещё не означает авторскую работу.
Зонд поймал в скриптах babylon при пустом webgl_ctx. Разгадка в разметке: на странице стоит
<iframe id="rooom-spaceviewer" title="SMS Metaverse"> с разрешениями vr; xr; accelerometer;
gyroscope; camera и загрузчик static.rooom.com/viewer-api/space-viewer-latest.min.js. То есть
фестиваль встроил чужую платформу виртуальных пространств (rooom, на Babylon.js) с аватарами и
VR, а собственно 3D живёт внутри iframe и стартует только после менеджера согласия Klaro —
поэтому контекст в наше восьмисекундное окно и не попал.
Отбраковка, но с полезным выводом. Идея «трёхмерный тур по площадке» для B2B-ветки /hire выглядит соблазнительно: покажи заказчику залы в объёме. Здесь видно, во что она превращается на практике — внешняя платформа, iframe, аватары, разрешения на камеру и микрофон, ноль контроля над видом и полная несовместимость со статическим экспортом. Если тур по залам когда-нибудь понадобится, делать его надо своими средствами (последовательность полноэкранных кадров с шейдерным переходом по образцу Depot Mayfield), а не встраиванием метавселенной.
Зонд: webgl2, глобаль __THREE__, один холст — три работает наверняка. Но сайт собран на
Next.js с Turbopack, и в одиннадцати чанках, объявленных в начальной разметке, нет ни одного
следа three: он приезжает ленивым чанком, имя которого без браузера не узнать, а браузерные
инструменты в этой задаче запрещены. Единственное, что удалось установить точно: упоминание
ogl в машинном отчёте здесь тоже ложное — оно из регулярки Next.js для ботов, где есть слово
googleweblight.
Оставляю честно: 3D есть, техника не прочитана. Если участок будет доразбираться, Draaimolen — первый кандидат на браузерный проход.
Файл называется threedee.js (отсюда three в машинном отчёте), а внутри — Adobe Animate
и CreateJS, то есть 2D-канвас с иллюстративной анимацией квартала. Аутентично для арт-квартала,
чужое для нас. Разобрано подробнее в разделе поправок выше.
Отдельно стоит сказать, что «мёртвых» на участке почти нет: строки fail: TimeoutError в
машинном отчёте в подавляющем большинстве оказались медленным ответом под нагрузкой зонда
(шесть параллельных контекстов и программный рендер swiftshader), а не отсутствием сайта.
Перепроверено поштучно обычным запросом:
| Сайт | Зонд | Реальность (проверка curl) |
|---|---|---|
bootshaus.tv |
timeout | HTTP 200, 51.9 кБ, 0.65 с — сайт жив, и это наш пункт 2 |
dekmantel.com |
timeout | HTTP 200, 103 кБ, 1.17 с — 3D нет |
magazinelondon.co.uk |
timeout | HTTP 200, 11.9 кБ (страница-заглушка) — 3D нет |
tresorwest.com |
timeout | HTTP 200, 21.8 кБ — 3D нет |
villageunderground.co.uk |
timeout | HTTP 200, 100 кБ — 3D нет |
shelteramsterdam.nl |
timeout | HTTP 200, 125 кБ, 2.6 с — 3D нет |
verknipt.org |
HTTPError | HTTP 403 ботам — как и предупреждал исходный список; открывать руками |
arma17.club |
timeout | соединение не устанавливается (проверено дважды, до 40 с, ноль байт). Имя при этом разрешается — 141.8.193.176, российский хостинг Timeweb. То есть адрес живой, но TCP отсюда не проходит; единственный по-настоящему недоступный адрес участка. Смотреть руками или с другого канала |
Вывод для протокола разведки: fail: TimeoutError в этом отчёте нельзя читать как «сайт
мёртв» и тем более как «3D нет» — Bootshaus, наш второй по значимости результат, лежит именно
в этой строке.