/* pf-live.js — сюжет с курсорами для фона Portfolio. Подключается одной строкой в HEAD. */
(function(){if(document.getElementById('pfLiveCss'))return;var s=document.createElement('style');s.id='pfLiveCss';s.textContent="@media(min-width:981px){.pfX_overlay{--pfc:clamp(44px,3.89vw,100px)}.pfX_overlay::before{background-size:calc(var(--pfc) * 5) calc(var(--pfc) * 5),calc(var(--pfc) * 5) calc(var(--pfc) * 5),var(--pfc) var(--pfc),var(--pfc) var(--pfc)}}.pfCv{--k:1;position:absolute;left:-30%;right:-30%;top:-20%;bottom:-6%;z-index:0;pointer-events:none;transform-origin:50% 100%;opacity:0;transform:perspective(1600px) rotateX(58deg) translateY(6%) scale(1.12);transition:opacity .3s ease,transform .5s ease;font-family:var(--pf-font,Arial,sans-serif)}.pfX_overlayClip.isOpen .pfCv{opacity:1;transform:perspective(1600px) rotateX(12deg) scale(1);transition:opacity .9s ease .42s,transform 1.9s cubic-bezier(.22,1,.36,1) .42s}.pfA,.pfF,.pfCm,.pfRx{position:absolute;left:50%;top:100%}.pfA{width:0;height:0;z-index:3}.pfAIn{position:absolute;left:0;top:0;display:flex;align-items:flex-start;scale:var(--k);transform-origin:0 0;animation:pfWob 3.2s ease-in-out infinite alternate}.pfD .pfAIn{animation-duration:3.8s;animation-delay:-1.3s}.pfAIn svg{display:block;width:24px;height:30px;margin:-1px 0 0 -1px;overflow:visible;filter:drop-shadow(0 3px 4px rgba(20,6,80,.35))}.pfAIn path{fill:var(--c);stroke:#fff;stroke-width:1.3px;stroke-linejoin:round}.pfAIn span{margin:22px 0 0 -4px;padding:5px 10px 6px;border-radius:2px 11px 11px 11px;background:var(--c);color:var(--t);font-size:14px;line-height:1;white-space:nowrap;box-shadow:0 4px 12px rgba(20,6,80,.3)}.pfY{--c:#B8FF1A;--t:#1C1030}.pfD{--c:#FFFFFF;--t:#4A22D8}.pfE{--c:#FF6BB5;--t:#FFFFFF}.pfE .pfAIn{left:-27px;top:-17px;flex-direction:column;align-items:center;transform-origin:27px 17px;animation-duration:4.6s}.pfE svg{width:54px;height:34px;margin:0;transform-origin:50% 50%}.pfE .pfAIn path{fill:#fff;stroke:#FF6BB5;stroke-width:2px}.pfE .pfIr{fill:#FF6BB5}.pfE .pfDt{fill:#1C1030}.pfE .pfAIn span{margin:6px 0 0;border-radius:11px}.pfF{z-index:1;box-sizing:border-box;border:1.5px solid rgba(255,255,255,.85);background-color:rgba(255,255,255,.07);transition:background-color .6s,border-color .6s,border-radius .6s}.pfF::before{content:attr(data-n);position:absolute;left:-1px;bottom:100%;margin-bottom:calc(5px * var(--k));font-size:calc(11px * var(--k));line-height:1;color:rgba(255,255,255,.75);white-space:nowrap}.pfSz{position:absolute;left:50%;top:100%;margin-top:calc(7px * var(--k));transform:translateX(-50%);padding:.27em .55em;border-radius:3px;background:#B8FF1A;color:#1C1030;font-size:calc(11px * var(--k));line-height:1;white-space:nowrap}.pfIm{position:absolute;overflow:hidden;border-radius:4px;background:linear-gradient(135deg,#C4B3FF,#8A6AFF);transition:border-radius .6s}.pfIm::before{content:\"\";position:absolute;right:18%;top:18%;width:calc(14px * var(--k));height:calc(14px * var(--k));border-radius:50%;background:#B8FF1A}.pfIm::after{content:\"\";position:absolute;left:0;right:0;bottom:0;height:55%;background:rgba(40,14,140,.45);clip-path:polygon(0 100%,0 60%,28% 10%,52% 62%,70% 34%,100% 78%,100% 100%)}.pfPen{position:absolute;left:0;top:0;width:100%;height:100%;overflow:visible}.pfPen path{fill:none;stroke:#B8FF1A;stroke-width:calc(2.5px * var(--k));stroke-linecap:round;vector-effect:non-scaling-stroke}.pfPen circle{fill:#fff;stroke:#B8FF1A;stroke-width:1.5px;vector-effect:non-scaling-stroke}.pfBr{position:absolute;height:calc(6px * var(--k));border-radius:3px;background:rgba(255,255,255,.8);transform-origin:0 50%;transition:background .6s}.pfF.vDark{background-color:#1C1030;border-color:#fff}.pfF.vDark .pfBr{background:#B8FF1A}.pfF.vDark .pfIm{background:linear-gradient(135deg,#5B3BD6,#2A1680)}.pfF.vAccent{border-color:#B8FF1A}.pfF.vAccent .pfIm{background:linear-gradient(135deg,#EAFFB0,#B8FF1A)}.pfF.vAccent .pfIm::after{background:rgba(74,34,216,.55)}.pfF.vAccent .pfBr:first-of-type{background:#B8FF1A}.pfF.vSoft{border-radius:calc(14px * var(--k))}.pfF.vSoft .pfIm{border-radius:calc(12px * var(--k))}.pfF.vSoft .pfBr{border-radius:9px}.pfT,.pfN{position:absolute;z-index:1;box-sizing:border-box;border-radius:calc(6px * var(--k));box-shadow:0 4px 14px rgba(20,6,80,.28)}.pfT1{background:linear-gradient(135deg,#C4B3FF,#8A6AFF)}.pfT2{background:linear-gradient(135deg,#EAFFB0,#B8FF1A)}.pfT3{background:linear-gradient(135deg,#FFC2E0,#FF6BB5)}.pfN{padding:calc(9px * var(--k)) calc(10px * var(--k));border-radius:calc(3px * var(--k));background:#fff;border-top:calc(5px * var(--k)) solid #FF6BB5;color:#1C1030;font-size:calc(13px * var(--k));line-height:1.25}.pfCm{z-index:2}.pfCmIn{position:absolute;left:0;bottom:0;scale:var(--k);transform-origin:0 100%}.pfPin{position:absolute;left:0;bottom:0;width:28px;height:28px;border-radius:14px 14px 14px 3px;background:#fff;color:#4A22D8;font-size:12px;font-weight:700;line-height:28px;text-align:center;box-shadow:0 4px 12px rgba(20,6,80,.3);transform-origin:0 100%}.pfBub{position:absolute;left:36px;bottom:0;width:max-content;min-width:120px;max-width:180px;padding:8px 11px 9px;border-radius:12px 12px 12px 4px;background:#fff;color:#1C1030;font-size:13px;line-height:1.3;box-shadow:0 6px 18px rgba(20,6,80,.3);transform-origin:0 100%}.pfBub b{display:block;margin-bottom:2px;font-size:11px;color:#6B5AA8}.pfBub p{margin:0;min-height:1.3em}.pfBub p+b{margin-top:7px;padding-top:7px;border-top:1px solid #ECE8F8}.pfRe{display:inline-block;margin-top:7px;padding:2px 8px;border-radius:10px;background:#F1ECFF;font-size:12px;line-height:1.4}.pfCar{display:inline-block;width:1.5px;height:1em;margin-left:1px;vertical-align:-2px;background:currentColor;animation:pfBl 1s steps(1) infinite}.pfRx{z-index:4;width:0;height:0;font-size:28px;line-height:1}.pfRx span{position:absolute;left:22px;top:-30px;scale:var(--k)}@keyframes pfWob{0%{transform:translate(0,0) rotate(0)}35%{transform:translate(3px,-2px) rotate(-3deg)}70%{transform:translate(-2px,2px) rotate(2deg)}100%{transform:translate(1px,-3px) rotate(-1deg)}}@keyframes pfBl{50%{opacity:0}}@media(max-width:980px){.pfAIn svg{width:20px;height:25px}.pfAIn span{margin-top:18px;font-size:12px;padding:4px 8px 5px}.pfBub{max-width:150px;font-size:12px}}@media(prefers-reduced-motion:reduce){.pfCv{display:none}}";document.head.appendChild(s);})();
(function(){
/* LIVE CANVAS — сюжет на фоне Portfolio.
Отдельный скрипт: только читает класс isOpen у #pfX_overlayClip
и добавляет свой слой в #pfX_overlay. Существующий JS не трогает. */
var clip = document.getElementById('pfX_overlayClip');
var ov = document.getElementById('pfX_overlay');
var scene = document.getElementById('pfProjectScene');
if(!clip || !ov || !scene || window.pfLiveInit || !Element.prototype.animate){ return; }
window.pfLiveInit = true;
if(window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches){ return; }
var EASE = 'cubic-bezier(.45,0,.2,1)';
var ARROW = '';
/* арт-директор не правит ошибки, а подкидывает идеи;
yourich начинает делать вариант, пока тот ещё печатает */
var IDEAS = [
{ad:'огонь. а в тёмной теме?', y:'уже', v:'vDark', n:'dark'},
{ad:'круто. а мобильную?', y:'держи', v:'vMobile', n:'mobile'},
{ad:'нравится. а с акцентом?', y:'готово, смотри', v:'vAccent', n:'accent'},
{ad:'чисто. а если помягче?', y:'вот так', v:'vSoft', n:'soft'}
];
var AD_RE = ['🔥', '🙌', '💯', '😍'];
var AD_NOTE = ['референсы', 'палитра', 'мудборд', 'идеи'];
var E_REACT = ['😍', '👍', '🔥', '👀'];
var cv = document.createElement('div');
cv.className = 'pfCv';
cv.setAttribute('aria-hidden', 'true');
ov.insertBefore(cv, scene);
function mk(cls, html, parent){
var e = document.createElement('div');
e.className = cls;
if(html){ e.innerHTML = html; }
(parent || cv).appendChild(e);
return e;
}
function actor(cls, inner){
var a = mk('pfA ' + cls, '
' + inner + '
');
a.p = {x:0, y:0};
return a;
}
var Y = actor('pfY', ARROW + 'yourich');
var D = actor('pfD', ARROW + 'арт-директор');
var E = actor('pfE',
'заказчик');
var eyeSvg = E.querySelector('svg');
var pupil = E.querySelector('.pfPu');
/* ---------- утилиты ---------- */
var run = 0, anims = [], focus = null, isOn = false;
function isM(){ return window.innerWidth <= 980; }
/* клетка сетки: та же формула, что в CSS (--pfc) */
function baseCell(){ return isM() ? 36 : Math.min(100, Math.max(44, window.innerWidth * .0389)); }
/* на невысоких экранах (ноутбуки) уменьшаем клетку, чтобы верх сцены
и глаз-«заказчик» не залезали под хедер */
function headerBottom(){
var b = 0;
document.querySelectorAll('.pfX_leftGroup,.pfX_rightGroup,.pfX_centerGroup').forEach(function(e){
var r = e.getBoundingClientRect();
if(r.height){ b = Math.max(b, r.bottom); }
});
return b || 70;
}
/* экранная Y точки «пола» на высоте y (та же геометрия, что у сетки: rotateX 12°, perspective 1600) */
function planeScreenY(y){
var a = 12 * Math.PI / 180;
return window.innerHeight * 1.06 - y * Math.cos(a) * 1600 / (1600 + y * Math.sin(a));
}
var CELL = 0;
function fitCell(){
var C = baseCell();
if(isM()){ return C; }
var need = headerBottom() + 16;
while(C > 34 && planeScreenY(13.9 * C) - 24 * C / 56 < need){ C -= .5; }
return C;
}
function applyCell(){
CELL = fitCell();
if(!isM()){ ov.style.setProperty('--pfc', CELL + 'px'); }
cv.style.setProperty('--k', kk().toFixed(3));
}
function cell(){ return CELL || baseCell(); }
function kk(){ return isM() ? 1 : cell() / 56; }
function snapX(v){ var c = cell(); return Math.round((v + c / 2) / c) * c - c / 2; }
function T(p){ return 'translate(' + p.x.toFixed(1) + 'px,' + (-p.y).toFixed(1) + 'px)'; }
function place(el, x, y){ el.p = {x:x, y:y}; el.style.transform = T(el.p); }
function wait(ms){ return new Promise(function(r){ setTimeout(r, ms); }); }
function ck(g){ if(g !== run){ throw 0; } }
function rnd(a, b){ return a + Math.random() * (b - a); }
function an(el, kf, o){
var opt = {fill:'forwards', easing:EASE};
for(var k in o){ opt[k] = o[k]; }
var a = el.animate(kf, opt);
anims.push(a);
return a.finished.then(function(){
try{ a.commitStyles(); a.cancel(); }catch(e){}
anims.splice(anims.indexOf(a), 1);
}, function(){});
}
/* движение по мягкой дуге, как рука */
function move(a, x, y, ms){
var s = a.p, e = {x:x, y:y};
var dx = e.x - s.x, dy = e.y - s.y, d = Math.hypot(dx, dy) || 1;
var k = rnd(-.28, .28) * d;
var c = {x: s.x + dx / 2 - dy / d * k, y: s.y + dy / 2 + dx / d * k};
var kf = [];
for(var i = 0; i <= 10; i++){
var t = i / 10, u = 1 - t;
kf.push({transform: T({x: u*u*s.x + 2*u*t*c.x + t*t*e.x, y: u*u*s.y + 2*u*t*c.y + t*t*e.y})});
}
a.p = e;
if(a !== E){ focus = a; }
return an(a, kf, {duration: ms || Math.min(2300, 520 + d * 2.1)});
}
/* движение по списку точек (следом за пером) */
function follow(a, pts, ms){
a.p = pts[pts.length - 1];
focus = a;
return an(a, pts.map(function(p){ return {transform:T(p)}; }), {duration:ms, easing:'ease-in-out'});
}
function press(a){
return an(a.firstChild, [{transform:'scale(1)'}, {transform:'scale(.84)'}, {transform:'scale(1)'}], {duration:240, fill:'none'});
}
function pop(el, ms){
return an(el, [{transform:'scale(0)', opacity:0}, {transform:'scale(1.08)', opacity:1, offset:.7}, {transform:'scale(1)', opacity:1}], {duration:ms || 360, easing:'ease-out'});
}
function type(p, text, g){
var car = document.createElement('i');
car.className = 'pfCar';
var node = document.createTextNode('');
p.appendChild(node);
p.appendChild(car);
var i = 0;
return new Promise(function(res, rej){
(function tick(){
if(g !== run){ rej(0); return; }
if(i >= text.length){ setTimeout(function(){ car.remove(); res(); }, 450); return; }
node.data += text[i++];
setTimeout(tick, text[i - 1] === ' ' ? rnd(90, 160) : rnd(45, 115));
})();
});
}
/* ---------- глаз: следит и моргает ---------- */
var pu = {x:0, y:0};
function track(){
if(!isOn){ return; }
if(focus){
var r1 = focus.getBoundingClientRect(), r2 = eyeSvg.getBoundingClientRect();
var dx = r1.left - (r2.left + r2.width / 2), dy = r1.top - (r2.top + r2.height / 2);
var d = Math.hypot(dx, dy) || 1;
pu.x += (dx / d * 5 - pu.x) * .12;
pu.y += (dy / d * 3 - pu.y) * .12;
pupil.setAttribute('transform', 'translate(' + pu.x.toFixed(2) + ',' + pu.y.toFixed(2) + ')');
}
requestAnimationFrame(track);
}
function blink(g){
if(g !== run){ return; }
var twice = Math.random() < .3;
var kf = [{transform:'scaleY(1)'}, {transform:'scaleY(.08)', offset:.5}, {transform:'scaleY(1)'}];
an(eyeSvg, kf, {duration:170, easing:'ease-in-out', fill:'none'}).then(function(){
if(twice && g === run){ an(eyeSvg, kf, {duration:170, easing:'ease-in-out', fill:'none'}); }
});
setTimeout(function(){ blink(g); }, rnd(2200, 5200));
}
/* ---------- сюжет ---------- */
/* арт-директор тем временем собирает мудборд на другой стороне */
async function adBoard(g, n, side, C, K){
var vw = window.innerWidth;
var zc2 = -side * vw * .41;
var bx = snapX(zc2 - 1.5 * C), g4 = 4 * K;
var items = [];
function box(cls, x, yTop, w, h){
var e = mk(cls);
e.style.left = 'calc(50% + ' + (x + g4) + 'px)';
e.style.top = 'calc(100% - ' + (yTop - g4) + 'px)';
e.style.width = (w - 2 * g4) + 'px';
e.style.height = (h - 2 * g4) + 'px';
e.style.opacity = '0';
items.push(e);
return e;
}
var tiles = [[0, 7, 'pfT pfT1'], [1, 7, 'pfT pfT2'], [2, 7, 'pfT pfT3'], [0, 6, 'pfT pfT2'], [1, 6, 'pfT pfT3']];
await move(D, bx + .5 * C, 6.5 * C, 1600); ck(g);
for(var i = 0; i < tiles.length; i++){
var t = tiles[i], cx = bx + (t[0] + .5) * C, cy = (t[1] - .5) * C;
await move(D, cx, cy, rnd(420, 620)); ck(g);
press(D);
var el = box(t[2], bx + t[0] * C, t[1] * C, C, C);
await pop(el, 340); ck(g);
if(Math.random() < .35){ await wait(rnd(200, 500)); ck(g); }
}
var nx = bx + 2 * C, ny = 6 * C;
await move(D, nx + .2 * C, ny - .2 * C, 700); ck(g);
press(D);
var note = box('pfN', nx, ny, C * 1.9, C * 1.9);
note.style.transformOrigin = '0 0';
await pop(note, 380); ck(g);
await move(D, nx + 1.5 * C, ny - 1.4 * C, 600); ck(g);
await type(note, AD_NOTE[n % AD_NOTE.length], g); ck(g);
await wait(600); ck(g);
return items;
}
async function episode(g, n){
applyCell();
var C = cell(), K = kk(), m = isM(), idea = IDEAS[n % IDEAS.length];
cv.style.setProperty('--k', K.toFixed(3));
var side = m ? 0 : (n % 2 ? -1 : 1);
var vw = window.innerWidth;
var zc = m ? 0 : side * vw * .41;
var fw = 3 * C, fh = (m ? 3 : 3.5) * C, pad = Math.round(C * .18);
var fx = snapX(zc - fw / 2), fy = m ? C : 2 * C;
var top = fy + fh;
var fy2 = top + (m ? 3.6 : 3) * C, top2 = fy2 + fh;
function at(px, py, t){ return {x: fx + px, y: (t || top) - py}; }
/* глаз наблюдает сверху */
move(E, zc + (m ? 0 : side * .3 * C), top2 + (m ? 1.6 : 1.9) * C, 1800);
var boardP = m ? Promise.resolve([]) : adBoard(g, n, side, C, K);
boardP.catch(function(){});
/* 1. yourich собирает макет */
var F = mk('pfF');
F.setAttribute('data-n', 'Frame ' + (n + 1));
F.style.left = 'calc(50% + ' + fx + 'px)';
F.style.top = 'calc(100% - ' + top + 'px)';
F.style.width = '0px';
F.style.height = '0px';
F.style.opacity = '0';
await move(Y, fx, top); ck(g);
await press(Y); ck(g);
F.style.opacity = '1';
var sz = mk('pfSz', Math.round(fw / K) + ' × ' + Math.round(fh / K), F);
await Promise.all([
an(F, [{width:'0px', height:'0px'}, {width:fw + 'px', height:fh + 'px'}], {duration:900}),
move(Y, fx + fw, fy, 900)
]); ck(g);
await wait(400); ck(g);
an(sz, [{opacity:1}, {opacity:0}], {duration:300});
var iw = fw - 2 * pad, ih = Math.round(fh * .42);
var im = mk('pfIm', '', F);
im.style.left = pad + 'px';
im.style.top = pad + 'px';
im.style.width = '0px';
im.style.height = '0px';
var p0 = at(pad, pad), p1 = at(pad + iw, pad + ih);
await move(Y, p0.x, p0.y, 700); ck(g);
await press(Y); ck(g);
await Promise.all([
an(im, [{width:'0px', height:'0px'}, {width:iw + 'px', height:ih + 'px'}], {duration:750}),
move(Y, p1.x, p1.y, 750)
]); ck(g);
im.style.width = 'calc(100% - ' + 2 * pad + 'px)';
var py0 = ih + pad * 2.4, NS = 'http://www.w3.org/2000/svg';
var d = 'M' + pad + ' ' + (py0 + C * .3) + ' C' + (fw * .3) + ' ' + (py0 - C * .25) + ' ' + (fw * .62) + ' ' + (py0 + C * .8) + ' ' + (fw - pad) + ' ' + (py0 + C * .1);
var svg = document.createElementNS(NS, 'svg');
svg.setAttribute('class', 'pfPen');
svg.setAttribute('viewBox', '0 0 ' + fw + ' ' + fh);
svg.setAttribute('preserveAspectRatio', 'none');
var path = document.createElementNS(NS, 'path');
path.setAttribute('d', d);
svg.appendChild(path);
F.appendChild(svg);
var L = path.getTotalLength();
path.style.strokeDasharray = L;
path.style.strokeDashoffset = L;
var pts = [];
for(var i = 0; i <= 16; i++){
var q = path.getPointAtLength(L * i / 16);
pts.push(at(q.x, q.y));
}
await move(Y, pts[0].x, pts[0].y, 600); ck(g);
await press(Y); ck(g);
await Promise.all([
an(path, [{strokeDashoffset:L}, {strokeDashoffset:0}], {duration:1200, easing:'ease-in-out'}),
follow(Y, pts, 1200)
]); ck(g);
[0, 16].forEach(function(j){
var q = path.getPointAtLength(L * j / 16);
var c = document.createElementNS(NS, 'circle');
c.setAttribute('cx', q.x); c.setAttribute('cy', q.y); c.setAttribute('r', 3.5 * K);
svg.appendChild(c);
});
var bars = [[fh - pad * 1.9 - 7 * K, .72], [fh - pad - 5 * K, .46]];
for(var b = 0; b < bars.length; b++){
var br = mk('pfBr', '', F);
br.style.left = pad + 'px';
br.style.top = bars[b][0] + 'px';
br.style.width = 'calc((100% - ' + 2 * pad + 'px) * ' + bars[b][1] + ')';
br.style.transform = 'scaleX(0)';
var bp = at(pad + 2, bars[b][0] + 3 * K);
await move(Y, bp.x, bp.y, 480); ck(g);
press(Y);
await an(br, [{transform:'scaleX(0)'}, {transform:'scaleX(1)'}], {duration:400, easing:'cubic-bezier(.2,.8,.2,1)'}); ck(g);
}
F.classList.add('ok');
/* yourich отходит полюбоваться */
move(Y, fx + fw * .5 - side * C * .6, fy - C * .7, 900);
/* 2. арт-директор заканчивает мудборд, приходит и подкидывает идею */
var board = await boardP; ck(g);
await move(D, fx + fw * .7, top - C * .6, 2200); ck(g);
await wait(500); ck(g);
var cp = {x: fx, y: top + C * .45};
await move(D, cp.x + 8 * K, cp.y + 8 * K, 800); ck(g);
await press(D); ck(g);
var cm = mk('pfCm', '');
place(cm, cp.x, cp.y);
var pin = cm.querySelector('.pfPin'), bub = cm.querySelector('.pfBub'), pA = bub.querySelector('p');
bub.style.opacity = '0';
await pop(pin); ck(g);
move(D, cp.x + 90 * K, cp.y - 34 * K, 700);
await pop(bub, 320); ck(g);
var typing = type(pA, idea.ad, g);
/* 3. пока он печатает, yourich уже делает вариант */
await wait(700); ck(g);
var mid = at(fw / 2, fh * .75);
await move(Y, mid.x, mid.y, 700); ck(g);
await press(Y); ck(g);
var F2 = F.cloneNode(true);
F2.setAttribute('data-n', 'Frame ' + (n + 1) + ' / ' + idea.n);
F2.querySelectorAll('.pfSz').forEach(function(x){ x.remove(); });
cv.insertBefore(F2, F);
F2.style.top = 'calc(100% - ' + top + 'px)';
var dy = top2 - top;
await Promise.all([
an(F2, [{top:'calc(100% - ' + top + 'px)', opacity:.6}, {top:'calc(100% - ' + top2 + 'px)', opacity:1}], {duration:1300}),
move(Y, mid.x, mid.y + dy, 1300)
]); ck(g);
if(idea.v === 'vMobile'){
var re = at(fw, fh / 2, top2), nw = Math.round(1.75 * C);
await move(Y, re.x, re.y, 600); ck(g);
await press(Y); ck(g);
await Promise.all([
an(F2, [{width:fw + 'px'}, {width:nw + 'px'}], {duration:900}),
move(Y, fx + nw, re.y, 900)
]); ck(g);
} else {
await press(Y); ck(g);
F2.classList.add(idea.v);
await wait(300); ck(g);
}
/* 4. yourich отвечает в треде, арт-директор ставит реакцию */
await typing; ck(g);
await move(Y, cp.x + 120 * K, cp.y - 10 * K, 900); ck(g);
await press(Y); ck(g);
var bY = document.createElement('b'), pY = document.createElement('p');
bY.textContent = 'yourich';
bub.appendChild(bY);
bub.appendChild(pY);
await type(pY, idea.y, g); ck(g);
await move(D, cp.x + 60 * K, cp.y + 8 * K, 600); ck(g);
await press(D); ck(g);
var chip = document.createElement('div');
chip.className = 'pfRe';
chip.textContent = AD_RE[n % AD_RE.length] + ' 1';
bub.appendChild(chip);
await pop(chip, 300); ck(g);
/* 5. заказчик сравнивает оба макета и доволен */
focus = F2; await wait(900); ck(g);
focus = F; await wait(900); ck(g);
focus = F2; await wait(600); ck(g);
an(eyeSvg, [{transform:'scale(1)'}, {transform:'scale(1.18)', offset:.4}, {transform:'scale(1)'}], {duration:520, fill:'none'});
var rx = mk('pfRx', '' + E_REACT[n % E_REACT.length] + '');
place(rx, E.p.x, E.p.y);
an(rx, [{transform:T(E.p) + ' scale(.4)', opacity:0}, {transform:T({x:E.p.x, y:E.p.y + 18 * K}) + ' scale(1.1)', opacity:1, offset:.35}, {transform:T({x:E.p.x, y:E.p.y + 38 * K}) + ' scale(1)', opacity:0}], {duration:1800, easing:'ease-out'});
move(D, -side * vw * .45 + (m ? -140 : 0), top2 + rnd(0, 2) * C, 2400);
move(Y, zc - side * C * 1.4, fy - C * .4, 1600);
await wait(2200); ck(g);
/* 6. сцена гаснет, следующий эпизод — на другой стороне */
var gone = [F, F2, cm].concat(board);
await Promise.all(gone.map(function(el){ return an(el, [{opacity:getComputedStyle(el).opacity}, {opacity:0}], {duration:700}); })); ck(g);
gone.forEach(function(el){ el.remove(); }); rx.remove();
await wait(500); ck(g);
}
async function loop(g){
var n = 0;
try{
await wait(1500); ck(g);
while(true){ await episode(g, n++); }
}catch(e){}
}
function start(){
if(isOn){ return; }
isOn = true;
var g = ++run;
applyCell();
var vw = window.innerWidth, C = cell(), m = isM();
if(!Y.started){
Y.started = true;
place(Y, m ? -120 : vw * .2, 2 * C);
place(D, m ? 150 : -vw * .45, 8 * C);
place(E, m ? 0 : vw * .41, (m ? 7 : 11) * C);
cv.style.setProperty('--k', kk().toFixed(3));
}
loop(g);
setTimeout(function(){ blink(g); }, 1800);
requestAnimationFrame(track);
}
function stop(){
if(!isOn){ return; }
isOn = false;
run++;
anims.slice().forEach(function(a){ try{ a.commitStyles(); }catch(e){} a.cancel(); });
anims = [];
setTimeout(function(){
if(isOn){ return; }
cv.querySelectorAll('.pfF,.pfCm,.pfRx,.pfT,.pfN').forEach(function(el){ el.remove(); });
}, 800);
}
function sync(){
var open = clip.classList.contains('isOpen') && !clip.classList.contains('isClosing');
if(open){ start(); } else { stop(); }
}
new MutationObserver(sync).observe(clip, {attributes:true, attributeFilter:['class']});
sync();
})();