﻿/*  cenas.jsx — recriação do edit "how it started vs how its going" do @illdari (16, DcgUeIEMfX3)
    -------------------------------------------------------------------------------------------
    Monta do zero, num projeto novo, a comp RECRIACAO (1080×1080, 30 qps, 28,17 s). Formato "antes × agora":

      0,00–5,47  ANTES      motion "de iniciante" de propósito: tudo linear, sem desfoque, canto reto. O avião sai
                            do ícone e dá uma volta inteira; selo vermelho; barra branca estica; o ícone atravessa
                            e troca a frase; a barra achata. Meio segundo de tela vazia antes do drop.
      5,50       DROP       corte seco: ícone do After Effects gigante e borrado pousa; grade de ícones Adobe;
                            painel de arquivos; aviso de travamento; "Obter info"; clique; notificação de RAM.
      9,75–13,55 MÚSICA     trecho estilo Spotify (nosso, simplificado): logo, título, artistas, página, item.
      13,55–14,3 ZOOM       barras azuis viram um cartão que gira e cresce até o miolo virar a cena nova.
      14,3–17,3  3D         galeria escura; iPhone dourado entra girando; câmera corre; MacBook em perspectiva.
      16,8–19,3  FITA       fita azul atravessa, aplaina com o texto correndo, vira pílula → círculo → check.
      19,33–28,2 NAVEGADOR  íris de 3 q abre o desktop; barra lateral rosa: favoritos, pastas, cliques, arrastar.

    COMO USAR
      - Troque os textos no bloco TEXTOS. File > Scripts > Run Script File… e escolha este arquivo: cria o projeto,
        salva em ae/trust-process.aep e grava os eventos de som em audio/eventos.json.
      - Mockups 3D (iPhone e MacBook) são camadas 3D do AE: tela (precomp) + moldura + 8 cópias para a espessura.
        Para um mockup mais fiel, troque por um render .glb (ver README do projeto).
*/
(function () {

// ================================================================ TEXTOS (trocáveis)
var TEXTOS = {
    tituloAntes: 'como começou vs :', tituloDepois: 'como está indo',
    frase1: 'Me chama quando quiser', frase2: 'Pode deixar :)',
    rotuloAe: 'After Effects',
    arquivos: [['projeto-final', '15MB'], ['abertura', '12MB'], ['marca', '2MB'], ['saas', '15MB']],
    tituloArquivos: 'Arquivos do projeto',
    alerta1: 'After Effects travou', alerta2: 'Precisa de mais memória.',
    info: 'Obter info',
    ram1: 'Mais memória', ram2: '16 GB', ram3: 'agora o After Effects respira',
    musica: 'Puro Movimento',
    somGlobal: 'Som Global', artistas: [['Você', 'Criador'], ['Marina', 'Cantora'], ['Léo', 'Produtor']],
    imersao: 'Imersão Global', paragrafo: 'Mergulhe numa paisagem sonora sem limites,\ronde cada camada do seu som favorito\rganha vida e lugar.',
    botao: 'Ir além', faixa: 'Luzes Piscando', faixaSub: 'Single',
    app: 'Clube', iphone1: 'Puxe sua', iphone2: 'inspiração', abrir: 'Abrir o Clube', fechar: 'Fechar',
    mac1: 'Dentro do seu', mac2: 'fluxo',
    fita: 'Salvando sua ideia', feito: 'Feito',
    espaco: 'Clube', pastas: ['Trabalho', 'Entretenimento', 'Redes sociais'], filhos: ['Pinterest', 'Figma', 'Gmail'],
    novaAba: 'Nova aba', insta: 'Instagram', lateral: ['Favoritos', 'Pastas', 'Espaços']
};

// ================================================================ pastas
var BASE = (typeof RECR_BASE !== 'undefined') ? new Folder(RECR_BASE) : File($.fileName).parent.parent;
var ASSETS = BASE.fsName + '/assets/';
var ICON = ASSETS + 'icones/';
var W = 1080, H = 1080, FPS = 30, DUR = 845 / 30;
function F(f) { return f / FPS; }

// ================================================================ ajudantes
function rgb(h) { h = h.replace('#', ''); return [parseInt(h.substr(0, 2), 16) / 255, parseInt(h.substr(2, 2), 16) / 255, parseInt(h.substr(4, 2), 16) / 255]; }
function nEase(p) {
    var t = p.propertyValueType;
    if (t == PropertyValueType.TwoD) return 2;
    if (t == PropertyValueType.ThreeD) return 3;
    return 1;
}
// K(prop, [[t, valor, influênciaEntrada, influênciaSaída], …]); influência -1 = linear; padrão 33
function K(p, arr) {
    var i, k, e, n = nEase(p);
    for (i = 0; i < arr.length; i++) arr[i][0] = Math.round(arr[i][0] * FPS) / FPS;   // chaves na grade de quadros
    for (i = 0; i < arr.length; i++) p.setValueAtTime(arr[i][0], arr[i][1]);
    for (i = 0; i < arr.length; i++) {
        k = p.nearestKeyIndex(arr[i][0]);
        var ei = arr[i].length > 2 ? arr[i][2] : 33, eo = arr[i].length > 3 ? arr[i][3] : ei;
        if (ei === 'a') {                                   // 'a' = curva automática contínua (velocidade sem degrau)
            p.setTemporalContinuousAtKey(k, true); p.setTemporalAutoBezierAtKey(k, true);
            if (p.isSpatial && p.matchName == 'ADBE Position') { p.setSpatialAutoBezierAtKey(k, false); p.setSpatialContinuousAtKey(k, false); }
            continue;
        }
        var ie = [], oe = [];
        for (e = 0; e < n; e++) { ie.push(new KeyframeEase(0, Math.max(0.1, ei))); oe.push(new KeyframeEase(0, Math.max(0.1, eo))); }
        p.setTemporalEaseAtKey(k, ie, oe);
        if (ei < 0 || eo < 0) p.setInterpolationTypeAtKey(k, ei < 0 ? KeyframeInterpolationType.LINEAR : KeyframeInterpolationType.BEZIER, eo < 0 ? KeyframeInterpolationType.LINEAR : KeyframeInterpolationType.BEZIER);
        if (p.isSpatial && p.matchName == 'ADBE Position') {
            p.setSpatialAutoBezierAtKey(k, false); p.setSpatialContinuousAtKey(k, false);
            var z = (p.value.length == 3) ? [0, 0, 0] : [0, 0];
            p.setSpatialTangentsAtKey(k, z, z);
        }
    }
}
function T(L) { return L.property('ADBE Transform Group'); }
function P(L) { return T(L).property('ADBE Position'); }
function S(L) { return T(L).property('ADBE Scale'); }
function R(L) { return T(L).property('ADBE Rotate Z'); }
function O(L) { return T(L).property('ADBE Opacity'); }
function A(L) { return T(L).property('ADBE Anchor Point'); }
function fx(L, mn) { return L.property('ADBE Effect Parade').addProperty(mn); }
function blur(L) { var e = fx(L, 'ADBE Gaussian Blur 2'); e.property('ADBE Gaussian Blur 2-0003').setValue(0); /* sem repetir borda: o desfoque some suave (com 1, PNG vira caixa) */ return L.property('ADBE Effect Parade').property(e.name).property('ADBE Gaussian Blur 2-0001'); }
function NUL(comp, nome, pos) { var L = comp.layers.addNull(); L.name = nome; A(L).setValue([0, 0]); P(L).setValue(pos); L.enabled = true; return L; }
function solid(comp, nome, cor, w, h) { var L = comp.layers.addSolid(rgb(cor), nome, w || comp.width, h || comp.height, 1); return L; }
function img(comp, arq) {
    var it = app.project.importFile(new ImportOptions(new File(arq)));
    it.parentFolder = PASTA;
    return comp.layers.add(it);
}
function shape(comp, nome) { var L = comp.layers.addShape(); L.name = nome; return L; }
function grupo(L, nome) { var g = L.property('ADBE Root Vectors Group').addProperty('ADBE Vector Group'); g.name = nome; return g; }
function cont(L, nome) { return L.property('ADBE Root Vectors Group').property(nome).property('ADBE Vectors Group'); }
function addRect(L, gn, w, h, r) { var g = grupo(L, gn); var rc = cont(L, gn).addProperty('ADBE Vector Shape - Rect'); rc.property('ADBE Vector Rect Size').setValue([w, h]); rc.property('ADBE Vector Rect Roundness').setValue(r); return gn; }
function addEllipse(L, gn, w, h, pos) { grupo(L, gn); var el = cont(L, gn).addProperty('ADBE Vector Shape - Ellipse'); el.property('ADBE Vector Ellipse Size').setValue([w, h]); if (pos) el.property('ADBE Vector Ellipse Position').setValue(pos); return gn; }
function addFill(L, gn, cor) { var f = cont(L, gn).addProperty('ADBE Vector Graphic - Fill'); f.property('ADBE Vector Fill Color').setValue(rgb(cor)); return f; }
function addStroke(L, gn, cor, w) { var s = cont(L, gn).addProperty('ADBE Vector Graphic - Stroke'); s.property('ADBE Vector Stroke Color').setValue(rgb(cor)); s.property('ADBE Vector Stroke Width').setValue(w); return s; }
function rectProp(L, gn, mn) { return cont(L, gn).property('ADBE Vector Shape - Rect').property(mn); }
function TX(comp, s, fonte, tam, cor, pos, just, track) {
    var L = comp.layers.addText(s);
    var tp = L.property('ADBE Text Properties').property('ADBE Text Document');
    var d = tp.value;
    d.resetCharStyle(); d.font = fonte; d.fontSize = tam; d.applyFill = true; d.fillColor = rgb(cor); d.applyStroke = false;
    d.tracking = track || 0;
    tp.setValue(d);
    d = tp.value; d.justification = just || ParagraphJustification.LEFT_JUSTIFY; tp.setValue(d);
    P(L).setValue(pos);
    return L;
}
function setLeading(L, lead) { var tp = L.property('ADBE Text Properties').property('ADBE Text Document'); var d = tp.value; d.autoLeading = false; d.leading = lead; tp.setValue(d); }
function caixa(L, t) { return L.sourceRectAtTime(t || 0, false); }   // {left, top, width, height} em coordenadas da camada
// animador de texto: esconde o que não foi "digitado" (opacidade 0 e 10 px abaixo). base: 1 caracteres, 3 palavras
function digita(L, base, chaves, desloc, indice) {
    var an = L.property('ADBE Text Properties').property('ADBE Text Animators').addProperty('ADBE Text Animator');
    an.name = 'digita';
    an.property('ADBE Text Animator Properties').addProperty('ADBE Text Opacity').setValue(0);
    if (desloc) L.property('ADBE Text Properties').property('ADBE Text Animators').property('digita').property('ADBE Text Animator Properties').addProperty('ADBE Text Position 3D').setValue([0, desloc, 0]);
    var sel = L.property('ADBE Text Properties').property('ADBE Text Animators').property('digita').property('ADBE Text Selectors').addProperty('ADBE Text Selector');
    var adv = sel.property('ADBE Text Range Advanced');
    adv.property('ADBE Text Range Type2').setValue(base);
    if (base == 3 || indice) {
        adv.property('ADBE Text Range Units').setValue(2);                 // índice (palavra/letra 1, 2, 3…)
        sel.property('ADBE Text Index End').setValue(999);
        K(sel.property('ADBE Text Index Start'), chaves);
    } else {
        K(sel.property('ADBE Text Percent Start'), chaves);
    }
}
function mb(L) { L.motionBlur = true; }

function R3(L, eixo) { return T(L).property(eixo == 'x' ? 'ADBE Rotate X' : 'ADBE Rotate Y'); }
function circ(comp, nome, d, cor, pos) { var L = shape(comp, nome); addEllipse(L, 'o', d, d); addFill(L, 'o', cor); if (pos) P(L).setValue(pos); return L; }
function rr(comp, nome, w, h, r, cor, pos) { var L = shape(comp, nome); addRect(L, 'r', w, h, r); addFill(L, 'r', cor); if (pos) P(L).setValue(pos); return L; }
function contorno(L, gn, cor, w) { return addStroke(L, gn, cor, w); }
function sombra(L, op, dist, suave) {
    var e = fx(L, 'ADBE Drop Shadow'); var n = e.name;
    L.property('ADBE Effect Parade').property(n).property('ADBE Drop Shadow-0002').setValue(op);
    L.property('ADBE Effect Parade').property(n).property('ADBE Drop Shadow-0003').setValue(180);
    L.property('ADBE Effect Parade').property(n).property('ADBE Drop Shadow-0004').setValue(dist);
    L.property('ADBE Effect Parade').property(n).property('ADBE Drop Shadow-0005').setValue(suave);
}
function filho(L, pai, pos) { L.setParentWithJump(pai); if (pos) P(L).setValue(pos); return L; }   // sem compensar: valores ficam locais ao pai
function caminho(L, gn, pts, fechado) {       // path de pontos retos
    grupo(L, gn);
    var pp = cont(L, gn).addProperty('ADBE Vector Shape - Group');
    var sh = new Shape(); sh.vertices = pts; sh.closed = !!fechado;
    cont(L, gn).property('ADBE Vector Shape - Group').property('ADBE Vector Shape').setValue(sh);
    return gn;
}
function entra(L, t, dur, dy, bl) {          // entrada padrão "depois": sobe, sai do desfoque, ease-out
    var p0 = P(L).value;
    K(P(L), [[t, [p0[0], p0[1] + (dy || 0)], 33, 10], [t + F(dur), p0, 85, 33]]);
    K(O(L), [[t, 0], [t + F(Math.max(3, Math.round(dur * 0.6))), 100]]);
    if (bl) K(blur(L), [[t, bl, 33, 10], [t + F(dur), 0, 85, 33]]);
    L.inPoint = Math.max(0, t - F(1));
}

// ================================================================ projeto
app.newProject();
var proj = app.project;
var PASTA = proj.items.addFolder('assets');
var COMPS = proj.items.addFolder('cenas');
function novaComp(nome, w, h, mbOn) { var c = proj.items.addComp(nome, w || W, h || H, 1, DUR, FPS); c.parentFolder = COMPS; c.motionBlur = (mbOn !== false); c.shutterAngle = 270; c.shutterPhase = -135; c.motionBlurSamplesPerFrame = 16; return c; }
var EVENTOS = [];
function ev(t, kind, pan, v) { EVENTOS.push({ t: Math.round(t * 1000) / 1000, kind: kind, pan: pan || 0, v: v || 0.7 }); }

// ================================================================ 1. ANTES (0–5,5): linear de propósito, sem desfoque
var P1 = novaComp('ANTES', W, H, true);
(function () {
    var c = P1;
    solid(c, 'fundo', '#161616');
    var G = NUL(c, 'GRUPO', [540, 540]);
    // barra branca de canto reto: a borda esquerda fica fixa em x 9, a direita estica (3,35–4,0)
    var barra = shape(c, 'barra'); addRect(barra, 'r', 230, 234, 0); addFill(barra, 'r', '#FFFFFF'); filho(barra, G, [0, 0]);
    var ws = [[3.35, 230], [3.50, 688], [3.60, 846], [3.70, 945], [3.80, 994], [3.90, 1017], [4.00, 1026]];
    var ks = [], kp = [], i;
    for (i = 0; i < ws.length; i++) { ks.push([ws[i][0], [ws[i][1], 234], -1, -1]); kp.push([ws[i][0], [-531 + ws[i][1] / 2, 0], -1, -1]); }
    K(rectProp(barra, 'r', 'ADBE Vector Rect Size'), ks);
    K(rectProp(barra, 'r', 'ADBE Vector Rect Position'), kp);
    barra.inPoint = 3.33; mb(barra);
    // frases (itálico): a nova aparece à esquerda do ícone, a velha some à direita dele (mattes filhos do ícone)
    var f1 = TX(c, TEXTOS.frase1, 'RobotoCondensed-Italic', 60, '#111111', [0, 0], ParagraphJustification.LEFT_JUSTIFY, 60); filho(f1, G, [-275, 20]);
    K(O(f1), [[3.68, 0, -1, -1], [3.80, 100, -1, -1]]);
    f1.inPoint = 3.66;
    var f2 = TX(c, TEXTOS.frase2, 'RobotoCondensed-Italic', 60, '#111111', [0, 0], ParagraphJustification.LEFT_JUSTIFY, 60); filho(f2, G, [-279, 20]);
    f2.inPoint = 3.95;
    // ícone do Telegram "antigo": quadrado branco arredondado, círculo azul-claro, avião branco
    var IC = NUL(c, 'ICONE', [0, 0]); IC.parent = G; P(IC).setValue([0, 0]);
    var q = rr(c, 'quadrado', 234, 234, 50, '#FFFFFF', [0, 0]); filho(q, IC, [0, 0]);
    var bola = circ(c, 'circulo azul', 206, '#A3CDE1', [0, 0]); filho(bola, IC, [0, 0]);
    var selo = circ(c, 'selo vermelho', 36, '#E0303E', [0, 0]); filho(selo, IC, [104, -104]);
    K(S(selo), [[2.10, [0, 0], -1, -1], [2.20, [100, 100], -1, -1]]);
    selo.inPoint = 2.08;
    // mattes da troca de frase
    var mD = rr(c, 'matte direita', 1400, 300, 0, '#FFFFFF', [0, 0]); filho(mD, IC, [700, 0]);
    var mE = rr(c, 'matte esquerda', 1400, 300, 0, '#FFFFFF', [0, 0]); filho(mE, IC, [-700, 0]);
    f1.moveAfter(mD); f1.setTrackMatte(mD, TrackMatteType.ALPHA);
    f2.moveAfter(mE); f2.setTrackMatte(mE, TrackMatteType.ALPHA);
    // movimento do ícone: balanço leve (2,1–3,2), vai à esquerda (3,15–3,32), atravessa (4,0–4,3)
    K(R(IC), [[2.15, 0, -1, -1], [2.45, 6, -1, -1], [2.75, -5, -1, -1], [3.05, 3, -1, -1], [3.20, 0, -1, -1]]);
    K(P(IC), [[3.15, [0, 0], -1, -1], [3.32, [-419, 0], -1, -1], [4.00, [-419, 0], -1, -1], [4.30, [377, 0], -1, -1], [4.45, [391, 0], -1, -1]]);
    // avião: sai do ícone, dá a volta (direita → cima → esquerda) em velocidade constante e volta (0,20–1,92)
    var av = shape(c, 'aviao'); caminho(av, 'a', [[-36, -30], [44, 0], [-36, 30], [-18, 0]], true); addFill(av, 'a', '#FFFFFF');
    av.parent = G;
    P(av).expression = [
        'var C = thisComp.layer("ICONE").transform.position;',
        'function E(a){ return [250*Math.cos(a), -70 - 230*Math.sin(a)]; }',
        'var t0 = 0.20, t1 = 0.33, t2 = 1.80, t3 = 1.92;',
        'if (time < t0 || time > t3) C;',
        'else if (time < t1) linear(time, t0, t1, C, E(-0.17));',
        'else if (time < t2) E(linear(time, t1, t2, -0.17, 3.42));',
        'else linear(time, t2, t3, E(3.42), C);'
    ].join('\n');
    R(av).setValue(-28);
    R(av).expression = 'var v = transform.position.velocity; (length(v) > 5) ? radiansToDegrees(Math.atan2(v[1], v[0])) : value + thisComp.layer("ICONE").transform.rotation;';
    av.moveToBeginning();
    // achata e some (4,80–4,95) — tudo junto
    K(S(G), [[4.80, [100, 100], -1, -1], [4.95, [100, 0], -1, -1]]);
    ev(0.20, 'move', 0.4, 0.4); ev(1.90, 'pouso', 0, 0.45); ev(2.10, 'notifica', 0.3, 0.5); ev(3.15, 'move', -0.4, 0.45);
    ev(3.35, 'abre', 0, 0.5); ev(3.70, 'texto', 0, 0.4); ev(4.00, 'empurra', 0.3, 0.55); ev(4.80, 'encolhe', 0, 0.5);
})();

// ================================================================ 2. ADOBE (5,5–7,15): ícone gigante pousa, grade, rótulo em onda
var AD = novaComp('ADOBE');
(function () {
    var c = AD;
    solid(c, 'fundo lilas', '#D4D4E0');
    var GR = NUL(c, 'GRADE', [540, 540]);
    K(P(GR), [[6.25, [540, 540], 33, 33], [6.50, [300, 540], 'a'], [7.00, [135, 540], 'a'], [7.15, [100, 540], 50, 33]]);
    var cinza = [['Pr', 0, -470], ['An', 0, 470], ['Ai', -470, 0], ['Xd', 470, 0], ['Ai', 940, 0], ['Xd', -940, 0]];
    for (var i = 0; i < cinza.length; i++) {
        var b = rr(c, 'icone ' + cinza[i][0] + i, 300, 300, 66, '#8E8E93', [0, 0]); filho(b, GR, [cinza[i][1], cinza[i][2]]);
        var l = TX(c, cinza[i][0], 'SFProDisplay-Semibold', 150, '#B9B9BE', [0, 0], ParagraphJustification.CENTER_JUSTIFY); filho(l, b, [0, 52]);
        var t0 = 5.62 + (i % 4) * F(1);
        K(O(b), [[t0, 0], [t0 + F(6), 100]]); K(S(b), [[t0, [80, 80], 33, 10], [t0 + F(8), [100, 100], 85, 33]]);
        O(l).expression = 'thisComp.layer("' + b.name + '").transform.opacity';
    }
    // Ae: entra a 250% e borrado, pousa em 100% (360 px) em ~15 q
    var ae = rr(c, 'Ae', 360, 360, 80, '#00005B', [0, 0]); filho(ae, GR, [0, 0]); mb(ae);
    var al = TX(c, 'Ae', 'SFProDisplay-Semibold', 200, '#9999FF', [0, 0], ParagraphJustification.CENTER_JUSTIFY); al.name = 'Ae letras'; filho(al, ae, [0, 70]);
    K(S(ae), [[5.50, [200, 200], 33, 8], [5.75, [106, 106], 'a'], [6.00, [100, 100], 60, 33]]);
    K(O(ae), [[5.50, 30], [5.72, 100]]); O(al).expression = 'thisComp.layer("Ae").transform.opacity';
    K(P(ae), [[5.50, [0, 120], 33, 8], [5.75, [0, 8], 'a'], [6.00, [0, 0], 60, 33]]);
    var bae = blur(ae); K(bae, [[5.50, 30, 33, 8], [5.95, 0, 88, 33]]);
    blur(al).expression = 'thisComp.layer("Ae").effect(1)(1)';
    // rótulo em onda (por caractere)
    var rot = TX(c, TEXTOS.rotuloAe, 'SFProDisplay-Semibold', 30, '#00005B', [0, 0], ParagraphJustification.CENTER_JUSTIFY); filho(rot, GR, [0, 236]);
    var an = rot.property('ADBE Text Properties').property('ADBE Text Animators').addProperty('ADBE Text Animator');
    an.property('ADBE Text Animator Properties').addProperty('ADBE Text Opacity').setValue(0);
    rot.property('ADBE Text Properties').property('ADBE Text Animators').property(1).property('ADBE Text Animator Properties').addProperty('ADBE Text Position 3D').setValue([0, 18, 0]);
    var sel = rot.property('ADBE Text Properties').property('ADBE Text Animators').property(1).property('ADBE Text Selectors').addProperty('ADBE Text Selector');
    sel.property('ADBE Text Range Advanced').property('ADBE Text Range Shape').setValue(3);   // rampa para cima (onda)
    K(sel.property('ADBE Text Percent Offset'), [[5.68, -100, 33, 33], [6.05, 100, 60, 33]]);
    ev(5.50, 'impacto', 0, 0.9); ev(5.58, 'pouso', 0, 0.6); ev(5.70, 'letras', 0, 0.4);
})();

// ================================================================ 3. PAINEL (6,25–8,0): arquivos, aviso de travamento, câmera aproxima
var PN = novaComp('PAINEL');
(function () {
    var c = PN;
    // o painel branco entra pela direita com desfoque direcional e cresce até virar o fundo
    var pn = rr(c, 'painel', 472, 520, 28, '#FFFFFF', [540, 540]); mb(pn);
    sombra(pn, 25, 30, 60);
    K(P(pn), [[6.28, [900, 527], 33, 10], [6.50, [600, 527], 'a'], [6.70, [540, 540], 'a'], [6.90, [540, 540], 50, 50]]);
    K(rectProp(pn, 'r', 'ADBE Vector Rect Size'), [[6.28, [60, 495], 33, 10], [6.50, [427, 495], 'a'], [6.70, [472, 500], 'a'], [6.90, [756, 810], 'a'], [7.00, [931, 995], 'a'], [7.12, [1200, 1200], 60, 33]]);
    K(cont(pn, 'r').property('ADBE Vector Graphic - Fill').property('ADBE Vector Fill Color'), [[6.90, rgb('#FFFFFF')], [7.15, rgb('#EDEDED')]]);
    var db = fx(pn, 'ADBE Motion Blur');
    K(pn.property('ADBE Effect Parade').property(db.name).property('ADBE Motion Blur-0002'), [[6.28, 60, 33, 10], [6.55, 0, 85, 33]]);
    pn.property('ADBE Effect Parade').property(db.name).property('ADBE Motion Blur-0001').setValue(90);
    // conteúdo da lista (null LISTA: o "zoom" da câmera é a escala dela, com foco no título)
    var LI = NUL(c, 'LISTA', [540, 540]);
    LI.parent = null;
    K(P(LI), [[6.28, [900, 527], 33, 10], [6.50, [600, 527], 'a'], [6.70, [540, 540], 'a'], [7.15, [540, 540], 40, 30], [7.75, [402, 694], 'a'], [7.95, [402, 900], 60, 33]]);
    K(S(LI), [[6.28, [55, 55], 33, 10], [6.70, [85, 85], 'a'], [7.00, [100, 100], 'a'], [7.15, [100, 100], 40, 30], [7.75, [140, 140], 60, 33]]);
    K(O(LI), [[6.28, 0], [6.40, 100]]);
    var tit = TX(c, TEXTOS.tituloArquivos, 'SFProText-Semibold', 30, '#1C1C1E', [0, 0]); filho(tit, LI, [-216, -210]);
    var lupa = shape(c, 'lupa'); addEllipse(lupa, 'o', 18, 18); addStroke(lupa, 'o', '#8E8E93', 3); filho(lupa, LI, [200, -220]);
    var linhas = [];
    for (var i = 0; i < 4; i++) {
        var y = -117 + i * 72;
        var gl = NUL(c, 'linha ' + i, [0, 0]); filho(gl, LI, [0, y]);
        var icn = rr(c, 'doc ' + i, 22, 28, 4, '#2C3E9E', [0, 0]); filho(icn, gl, [-200, -8]);
        var nm = TX(c, TEXTOS.arquivos[i][0], 'SFProText-Regular', 24, '#1C1C1E', [0, 0]); filho(nm, gl, [-174, 0]);
        var sz = TX(c, TEXTOS.arquivos[i][1], 'SFProText-Regular', 18, '#A1A1A6', [0, 0], ParagraphJustification.RIGHT_JUSTIFY); filho(sz, gl, [210, 0]);
        var fundo = rr(c, 'faixa ' + i, 440, 56, 12, '#F4F4F6', [0, 0]); filho(fundo, gl, [5, -8]); fundo.moveAfter(icn);
        // o aviso empurra a lista (7,15) e a profundidade de campo borra quem está embaixo
        K(P(gl), [[7.15, [0, y], 40, 10], [7.45, [0, y + 92], 85, 33]]);
        var bl = [icn, nm, sz, fundo];
        for (var k = 0; k < bl.length; k++) { mb(bl[k]); K(blur(bl[k]), [[7.15, 0], [7.75, i * 7]]); }
        linhas.push(gl);
    }
    // aviso vermelho
    var al = NUL(c, 'ALERTA', [0, 0]); filho(al, LI, [0, -128]);
    var alf = rr(c, 'alerta fundo', 440, 76, 14, '#FFFFFF', [0, 0]); filho(alf, al, [5, 0]); sombra(alf, 30, 6, 30);
    var alq = rr(c, 'alerta icone', 46, 46, 8, '#D01D2D', [0, 0]); filho(alq, al, [-186, 0]);
    var ala = TX(c, 'A', 'SFProDisplay-Bold', 30, '#FFFFFF', [0, 0], ParagraphJustification.CENTER_JUSTIFY); filho(ala, al, [-186, 11]);
    var at1 = TX(c, TEXTOS.alerta1, 'SFProText-Medium', 20, '#1C1C1E', [0, 0]); filho(at1, al, [-150, -4]);
    var at2 = TX(c, TEXTOS.alerta2, 'SFProText-Regular', 15, '#E0505E', [0, 0]); filho(at2, al, [-150, 20]);
    K(P(al), [[7.15, [0, -168], 33, 10], [7.45, [0, -128], 85, 33]]);
    K(O(al), [[7.15, 0], [7.30, 100]]);
    var filhosAl = [alf, alq, ala, at1, at2];
    for (i = 0; i < filhosAl.length; i++) { O(filhosAl[i]).expression = 'thisComp.layer("ALERTA").transform.opacity'; filhosAl[i].inPoint = 7.12; }
    // saída: a lista desce borrada (7,75–7,95)
    var todos = [tit, lupa];
    for (i = 0; i < todos.length; i++) K(blur(todos[i]), [[7.75, 0], [7.95, 20]]);
    K(O(LI), [[6.28, 0], [6.40, 100], [7.80, 100], [7.95, 0]]);
    var tudo = [tit, lupa, alf, alq, ala, at1, at2];
    for (i = 0; i < c.numLayers; i++) { }
    // opacidade do grupo LISTA não passa aos filhos: expressão em cada um
    var nomes = [];
    for (i = 1; i <= c.numLayers; i++) { var L = c.layer(i); if (L.parent && L.name != 'LISTA' && L.name.indexOf('alerta') < 0 && L.name.indexOf('ALERTA') < 0 && L.name != 'painel' && !(L instanceof AVLayer && L.nullLayer)) nomes.push(L); }
    for (i = 0; i < nomes.length; i++) { var op = O(nomes[i]); if (op.expression == '' && op.numKeys == 0) op.expression = 'thisComp.layer("LISTA").transform.opacity'; }
    ev(6.30, 'painel', 0.5, 0.6); ev(7.15, 'alerta', 0, 0.7); ev(7.78, 'sai', 0, 0.5);
})();

// ================================================================ 4. OBTER INFO (7,85–9,67): botão, clique, ripple, notificação
var GI = novaComp('OBTER INFO');
(function () {
    var c = GI;
    solid(c, 'fundo', '#EDEDED');
    // ripple cinza grande do clique
    var rp = circ(c, 'ripple', 1200, '#B9B9C6', [420, 562]);
    K(S(rp), [[8.48, [0, 0], 33, 10], [9.00, [100, 100], 80, 33]]); K(O(rp), [[8.48, 0], [8.60, 35], [9.00, 0]]);
    K(blur(rp), [[8.48, 60]]);
    var pill = rr(c, 'pilula', 270, 68, 34, '#E3E3E8', [540, 540]);
    K(O(pill), [[8.15, 0], [8.25, 100]]);
    K(cont(pill, 'r').property('ADBE Vector Graphic - Fill').property('ADBE Vector Fill Color'), [[8.70, rgb('#E3E3E8')], [8.85, rgb('#A7E6EE')]]);
    K(rectProp(pill, 'r', 'ADBE Vector Rect Size'), [[8.85, [270, 68], 33, 10], [9.00, [585, 150], 85, 33]]);
    K(rectProp(pill, 'r', 'ADBE Vector Rect Roundness'), [[8.85, 34, 33, 10], [9.00, 30, 85, 33]]);
    K(cont(pill, 'r').property('ADBE Vector Graphic - Fill').property('ADBE Vector Fill Color'), [[8.70, rgb('#E3E3E8')], [8.85, rgb('#A7E6EE')], [9.00, rgb('#E4E4E9')]]);
    K(blur(pill), [[8.85, 0], [8.92, 10], [9.00, 0]]);
    var ic = shape(c, 'i'); addEllipse(ic, 'o', 26, 26); addStroke(ic, 'o', '#3A3A3C', 2.5); P(ic).setValue([440, 540]);
    var ii = TX(c, 'i', 'SFProText-Semibold', 18, '#3A3A3C', [440, 547], ParagraphJustification.CENTER_JUSTIFY);
    var tx = TX(c, TEXTOS.info, 'SFProText-Medium', 24, '#1C1C1E', [466, 549]);
    digita(tx, 1, [[7.95, 0, -1, -1], [8.20, 100, -1, -1]]);
    K(O(ic), [[7.88, 0], [7.95, 100], [8.85, 100], [8.92, 0]]); O(ii).expression = 'thisComp.layer("i").transform.opacity';
    K(O(tx), [[8.85, 100], [8.92, 0]]);
    // notificação "mais memória" que nasce do botão
    var N = NUL(c, 'NOTIF', [540, 540]);
    var nq = rr(c, 'ae mini', 84, 84, 18, '#00005B', [0, 0]); filho(nq, N, [-220, 0]);
    var nqa = TX(c, 'Ae', 'SFProDisplay-Semibold', 40, '#9999FF', [0, 0], ParagraphJustification.CENTER_JUSTIFY); filho(nqa, N, [-220, 14]);
    var n1 = TX(c, TEXTOS.ram1, 'SFProText-Semibold', 28, '#1C1C1E', [0, 0]); filho(n1, N, [-160, -6]);
    var n2 = TX(c, TEXTOS.ram2, 'SFProText-Semibold', 24, '#1C1C1E', [0, 0], ParagraphJustification.RIGHT_JUSTIFY); filho(n2, N, [262, -6]);
    var n3 = TX(c, TEXTOS.ram3, 'SFProText-Regular', 17, '#8E8E93', [0, 0]); filho(n3, N, [-160, 26]);
    K(S(N), [[8.95, [70, 70], 33, 10], [9.10, [100, 100], 85, 33], [9.65, [103, 103], -1, -1]]);
    var nn = [nq, nqa, n1, n2, n3];
    for (var i = 0; i < nn.length; i++) { K(O(nn[i]), [[8.95, 0], [9.08, 100]]); nn[i].inPoint = 8.93; }
    // mão que clica
    var mao = img(c, ASSETS + 'mao-aponta.png'); mao.name = 'mao'; A(mao).setValue([258, 60]); mb(mao);
    K(P(mao), [[8.25, [700, 760], 33, 10], [8.42, [430, 560], 85, 50], [8.70, [436, 566], 40, 40], [8.85, [520, 760], 50, 33]]);
    K(S(mao), [[8.42, [24, 24]], [8.47, [20, 20]], [8.53, [24, 24]]]);
    K(O(mao), [[8.25, 0], [8.32, 100], [8.75, 100], [8.85, 0]]);
    mao.inPoint = 8.23; mao.outPoint = 8.9;
    ev(7.95, 'digita', 0, 0.4); ev(8.47, 'clique', -0.2, 0.7); ev(8.50, 'brilho', 0, 0.4); ev(8.97, 'notificacao', 0, 0.7);
})();

// ================================================================ 5. MÚSICA estilo Spotify (9,67–13,6), nosso conteúdo
var SP = novaComp('MUSICA');
(function () {
    var c = SP;
    solid(c, 'fundo', '#000000');
    var gl = circ(c, 'brilho verde', 1100, '#0B2E15', [380, 300]); K(blur(gl), [[0, 300]]); K(O(gl), [[9.72, 0], [10.0, 80]]);
    var lg = img(c, ASSETS + 'spotify-logo.png'); lg.name = 'logo'; mb(lg);
    K(P(lg), [[9.80, [540, 571], 33, 33], [10.30, [540, 571], 40, 10], [10.55, [315, 540], 85, 33]]);
    K(S(lg), [[9.80, [22, 22], 33, 10], [9.98, [37, 37], 85, 33], [10.30, [37, 37], 40, 10], [10.55, [33, 33], 85, 33]]);
    K(blur(lg), [[9.80, 30, 33, 10], [9.98, 0, 85, 33], [10.80, 0], [10.95, 25]]);
    K(O(lg), [[9.80, 0], [9.88, 100], [10.80, 100], [10.95, 0]]);
    lg.inPoint = 9.78; lg.outPoint = 11.0;
    var t1 = TX(c, TEXTOS.musica, 'SFProDisplay-Bold', 54, '#FFFFFF', [418, 559]);
    digita(t1, 1, [[10.40, 0, -1, -1], [10.70, 100, -1, -1]]);
    K(blur(t1), [[10.80, 0], [10.95, 25]]); K(O(t1), [[10.80, 100], [10.95, 0]]); t1.inPoint = 10.38; t1.outPoint = 11.0;
    // artista em destaque (avatar ilustrado/gerado, sem foto real)
    function avatar(nome, x, y, d, t, foto, cor, letra) {
        var a = circ(c, nome + ' anel', d + 14, '#1ED760', [x, y]);
        var b;
        if (foto) { b = img(c, ASSETS + 'avatar-pessoa.png'); S(b).setValue([d / 256 * 100, d / 256 * 100]); P(b).setValue([x, y]); }
        else { b = circ(c, nome + ' fundo', d, cor, [x, y]); var l = TX(c, letra, 'SFProRounded-Semibold', d * 0.42, cor == '#FFFFFF' ? '#111111' : '#FFFFFF', [x, y + d * 0.15], ParagraphJustification.CENTER_JUSTIFY); entra(l, t, 9, 20, 12); l.outPoint = 11.9; }
        entra(a, t, 9, 20, 12); entra(b, t, 9, 20, 12);
        return [a, b];
    }
    var i;
    // "Som Global" com 3 artistas
    var sg = TX(c, TEXTOS.somGlobal, 'SFProDisplay-Bold', 40, '#FFFFFF', [144, 192]); entra(sg, 10.95, 9, 20, 12);
    var XS = [292, 540, 770], CORES = ['#FFFFFF', '#3A6B4B', '#6B4B3A'], TA = [10.98, 11.08, 11.40];
    for (i = 0; i < 3; i++) {
        var av = (i == 1) ? avatar('artista' + i, XS[i], 540, 150, TA[i], true) : avatar('artista' + i, XS[i], 540, 150, TA[i], false, CORES[i], TEXTOS.artistas[i][0].charAt(0));
        var n1 = TX(c, TEXTOS.artistas[i][0], 'SFProText-Semibold', 22, '#FFFFFF', [XS[i], 660], ParagraphJustification.CENTER_JUSTIFY); entra(n1, TA[i] + F(2), 9, 15, 10);
        var n2 = TX(c, TEXTOS.artistas[i][1], 'SFProText-Regular', 16, '#9A9A9A', [XS[i], 688], ParagraphJustification.CENTER_JUSTIFY); entra(n2, TA[i] + F(3), 9, 15, 10);
        n1.outPoint = n2.outPoint = av[0].outPoint = av[1].outPoint = 11.9;
    }
    sg.outPoint = 11.9;
    // página "Imersão Global"
    var im = TX(c, TEXTOS.imersao, 'SFProDisplay-Bold', 46, '#FFFFFF', [185, 330]); entra(im, 11.92, 10, 25, 14);
    var pg = TX(c, TEXTOS.paragrafo, 'SFProText-Regular', 19, '#A0A0A0', [185, 380]); setLeading(pg, 27); entra(pg, 12.20, 10, 20, 10);
    var bt = shape(c, 'botao'); addRect(bt, 'r', 150, 46, 23); addStroke(bt, 'r', '#1ED760', 2); P(bt).setValue([260, 590]); entra(bt, 12.45, 9, 20, 8);
    var btt = TX(c, TEXTOS.botao, 'SFProText-Medium', 18, '#1ED760', [260, 596], ParagraphJustification.CENTER_JUSTIFY); entra(btt, 12.45, 9, 20, 8);
    var cp = img(c, ASSETS + 'capa-album.png'); S(cp).setValue([27, 27]); P(cp).setValue([190, 680]); entra(cp, 12.90, 9, 25, 10);
    var ft = TX(c, TEXTOS.faixa, 'SFProText-Semibold', 24, '#FFFFFF', [262, 674]); entra(ft, 12.92, 9, 25, 10);
    var fs = TX(c, TEXTOS.faixaSub, 'SFProText-Regular', 17, '#9A9A9A', [262, 702]); entra(fs, 12.94, 9, 25, 10);
    var sombraItem = rr(c, 'item apagado', 560, 90, 14, '#151515', [455, 880]); entra(sombraItem, 13.0, 9, 25, 10);
    // saída em riscos horizontais (13,35–13,55): estica e borra na horizontal
    var pag = [im, pg, bt, btt, cp, ft, fs, sombraItem];
    for (i = 0; i < pag.length; i++) {
        var p0 = P(pag[i]).value;
        var dbx = fx(pag[i], 'ADBE Motion Blur'); var nn = dbx.name;
        pag[i].property('ADBE Effect Parade').property(nn).property('ADBE Motion Blur-0001').setValue(90);
        K(pag[i].property('ADBE Effect Parade').property(nn).property('ADBE Motion Blur-0002'), [[13.32, 0], [13.52, 220]]);
        K(S(pag[i]), [[13.32, [S(pag[i]).value[0], S(pag[i]).value[1]], 50, 10], [13.52, [S(pag[i]).value[0] * 2.2, S(pag[i]).value[1]], 85, 33]]);
        pag[i].outPoint = 13.58;
    }
    ev(9.80, 'logo', 0, 0.7); ev(10.35, 'move', -0.3, 0.5); ev(10.40, 'digita', 0.3, 0.4); ev(10.95, 'texto', 0, 0.45);
    ev(10.98, 'pop', -0.4, 0.45); ev(11.08, 'pop', 0, 0.45); ev(11.40, 'pop', 0.4, 0.45); ev(11.92, 'texto', 0, 0.45);
    ev(12.45, 'pop', -0.3, 0.4); ev(12.90, 'card', -0.3, 0.45); ev(13.32, 'sai-tela', 0, 0.7);
})();

// ================================================================ 6. CARTÃO (13,55–14,35): barras azuis → cartão que gira e cresce
var CD = novaComp('CARTAO PRECOMP', 450, 495);
(function () {
    var c = CD;
    var mid = img(c, ASSETS + 'galeria-3.png'); S(mid).setValue([52, 52]); P(mid).setValue([225, 247]);
    var esc = solid(c, 'escurece', '#000000', 450, 495); O(esc).setValue(84);
    rr(c, 'azul topo', 450, 90, 0, '#2B47E6', [225, 45]); rr(c, 'azul base', 450, 90, 0, '#2B47E6', [225, 450]);
})();
var CT = novaComp('CARTAO');
(function () {
    var c = CT;
    var bg = solid(c, 'fundo', '#000000');
    var tint = fx(bg, 'ADBE Fill'); var tn = tint.name;
    K(bg.property('ADBE Effect Parade').property(tn).property('ADBE Fill-0002'), [[13.55, rgb('#0A0A0A'), -1, -1], [13.62, rgb('#7E7E7E'), -1, -1], [13.72, rgb('#BDBDBD'), -1, -1], [13.86, rgb('#FFFFFF'), -1, -1]]);
    var b1 = rr(c, 'barra 1', 450, 112, 0, '#2C40D0', [540, 270]), b2 = rr(c, 'barra 2', 450, 112, 0, '#2C40D0', [540, 800]);
    K(P(b1), [[13.58, [540, 270], 33, 10], [13.85, [504, 323], 85, 33]]); K(P(b2), [[13.58, [540, 800], 33, 10], [13.85, [504, 728], 85, 33]]);
    K(rectProp(b1, 'r', 'ADBE Vector Rect Size'), [[13.75, [450, 112]], [13.85, [450, 90]]]); K(rectProp(b2, 'r', 'ADBE Vector Rect Size'), [[13.75, [450, 112]], [13.85, [450, 90]]]);
    b1.outPoint = b2.outPoint = 13.87; mb(b1); mb(b2);
    var cd = c.layers.add(CD); cd.name = 'cartao'; mb(cd);
    cd.inPoint = 13.84;
    P(cd).setValue([504, 526]);
    K(S(cd), [[13.86, [100, 100], 33, 60], [14.10, [165, 165], 'a'], [14.20, [290, 290], 'a'], [14.30, [640, 640], 20, 33]]);
    K(R(cd), [[13.86, 0, 33, 60], [14.10, 6, 'a'], [14.20, 18, 'a'], [14.30, 34, 20, 33]]);
    ev(13.60, 'morph', 0, 0.6); ev(13.88, 'viagem', 0, 0.8);
})();

// ================================================================ 7. TELAS dos mockups
var TI = novaComp('TELA IPHONE', 390, 844);
(function () {
    var c = TI;
    rr(c, 'fundo', 390, 844, 56, '#0B0B10', [195, 422]);
    var g = img(c, ASSETS + 'galeria-1.png'); S(g).setValue([55, 30]); P(g).setValue([195, 470]); O(g).setValue(55);
    var mt = rr(c, 'molde', 330, 230, 22, '#FFFFFF', [195, 470]); g.moveAfter(mt); g.setTrackMatte(mt, TrackMatteType.ALPHA);
    circ(c, 'ponto', 14, '#3B82F6', [40, 100]);
    TX(c, TEXTOS.app, 'SFProText-Semibold', 18, '#FFFFFF', [56, 106]);
    var a = TX(c, TEXTOS.iphone1, 'SFProDisplay-Bold', 46, '#FFFFFF', [30, 200]);
    var b = TX(c, TEXTOS.iphone2, 'SFProDisplay-Bold', 46, '#4F8DFF', [30, 252]);
    digita(a, 1, [[14.95, 0, -1, -1], [15.20, 100, -1, -1]]); digita(b, 1, [[15.20, 0, -1, -1], [15.55, 100, -1, -1]]);
    rr(c, 'abrir', 330, 66, 33, '#2F6BFF', [195, 680]); TX(c, TEXTOS.abrir, 'SFProText-Semibold', 22, '#FFFFFF', [195, 688], ParagraphJustification.CENTER_JUSTIFY);
    rr(c, 'fechar', 330, 66, 33, '#2A2A30', [195, 760]); TX(c, TEXTOS.fechar, 'SFProText-Semibold', 22, '#FFFFFF', [195, 768], ParagraphJustification.CENTER_JUSTIFY);
})();
var TM = novaComp('TELA MAC', 1040, 650);
(function () {
    var c = TM;
    rr(c, 'fundo', 1040, 650, 10, '#0B0B10', [520, 325]);
    for (var i = 0; i < 6; i++) { var t = img(c, ASSETS + 'galeria-' + (i + 1) + '.png'); S(t).setValue([22, 22]); P(t).setValue([600 + (i % 3) * 150, 230 + Math.floor(i / 3) * 240]); O(t).setValue(70); }
    circ(c, 'ponto', 14, '#3B82F6', [50, 60]); TX(c, TEXTOS.app, 'SFProText-Semibold', 20, '#FFFFFF', [68, 67]);
    var a = TX(c, TEXTOS.mac1, 'SFProDisplay-Bold', 50, '#FFFFFF', [60, 300]);
    var b = TX(c, TEXTOS.mac2, 'SFProDisplay-Bold', 50, '#4F8DFF', [60, 360]);
    digita(a, 1, [[16.00, 0, -1, -1], [16.20, 100, -1, -1]]); digita(b, 1, [[16.20, 0, -1, -1], [16.45, 100, -1, -1]]);
})();

// ================================================================ 8. 3D (14,25–17,4): galeria, iPhone e MacBook
var TD = novaComp('TRES D');
(function () {
    var c = TD;
    solid(c, 'fundo', '#050614');
    // galeria escura atrás (cartões de imagem desfocados, deriva lenta)
    var G = NUL(c, 'GALERIA', [540, 540]);
    K(S(G), [[14.25, [112, 112], 33, 33], [17.4, [100, 100], 33, 33]]);
    K(P(G), [[14.25, [540, 540], 33, 33], [15.55, [500, 540], 'a'], [15.85, [260, 540], 'a'], [17.4, [200, 540], 33, 33]]);
    var pos = [[-420, -300], [0, -330], [420, -290], [-420, 330], [0, 300], [420, 340], [840, 0], [-840, 0], [1260, -300], [1260, 330]];
    for (var i = 0; i < pos.length; i++) {
        var t = img(c, ASSETS + 'galeria-' + (i % 6 + 1) + '.png'); t.name = 'galeria ' + i;
        filho(t, G, pos[i]); S(t).setValue([58, 58]);
        var m = rr(c, 'molde ' + i, 360, 580, 40, '#FFFFFF', [0, 0]); filho(m, G, pos[i]);
        t.moveAfter(m); t.setTrackMatte(m, TrackMatteType.ALPHA);
        K(blur(t), [[14.25, 20]]); O(t).setValue(38);
    }
    var cam = c.layers.addCamera('camera', [540, 540]);
    var zm = cam.property('ADBE Camera Options Group').property('ADBE Camera Zoom').value;
    P(cam).setValue([540, 540, -zm]);
    // iPhone: tela + moldura dourada + 8 cópias para a espessura (camadas 3D filhas do null IPHONE)
    var IP = NUL(c, 'IPHONE', [585, 1500]); IP.threeDLayer = true; A(IP).setValue([0, 0, 0]);
    K(P(IP), [[14.40, [585, 1500, 0], 33, 10], [14.95, [700, 560, 0], 82, 33], [15.55, [722, 548, 0], 40, 30], [15.80, [1550, 520, 0], 10, 33]]);
    K(R3(IP, 'y'), [[14.40, 85, 33, 10], [14.95, -16, 82, 33], [15.55, -20, 40, 30]]);
    K(R(IP), [[14.40, 0, 33, 10], [14.95, 6, 82, 33], [15.55, 4, 40, 30]]);
    S(IP).setValue([82, 82, 82]);
    var ts = c.layers.add(TI); ts.threeDLayer = true; filho(ts, IP, [0, 0, -2]); mb(ts);
    var fr = rr(c, 'moldura', 420, 874, 70, '#C9A46A', [0, 0]); fr.threeDLayer = true; filho(fr, IP, [0, 0, 0]); mb(fr);
    for (var k = 1; k <= 8; k++) { var e = rr(c, 'espessura ' + k, 420, 874, 70, '#8C6A3A', [0, 0]); e.threeDLayer = true; filho(e, IP, [0, 0, k * 3]); e.moveAfter(fr); }
    ts.moveBefore(fr);
    IP.inPoint = 14.35;
    // MacBook: tampa (tela) inclinada para trás + base deitada com teclado
    var MC = NUL(c, 'MACBOOK', [-700, 600]); MC.threeDLayer = true; A(MC).setValue([0, 0, 0]);
    K(P(MC), [[15.68, [-700, 640, 200], 33, 10], [15.95, [470, 600, 200], 85, 40], [16.60, [430, 590, 200], 'a'], [17.00, [300, 600, 200], 'a'], [17.30, [-500, 620, 200], 40, 33]]);
    R3(MC, 'y').setValue(26); R3(MC, 'x').setValue(22); S(MC).setValue([62, 62, 62]);   // visto de cima: aparece o teclado
    var tampa = NUL(c, 'TAMPA', [0, 0]); tampa.threeDLayer = true; filho(tampa, MC, [0, 0, 0]); A(tampa).setValue([0, 0, 0]);
    R3(tampa, 'x').setValue(-18);
    var lid = rr(c, 'tampa', 1100, 700, 26, '#1C1C1E', [0, 0]); lid.threeDLayer = true; filho(lid, tampa, [0, -350, 0]);
    var tm = c.layers.add(TM); tm.threeDLayer = true; filho(tm, tampa, [0, -350, -1]); tm.moveBefore(lid);
    var base = rr(c, 'base', 1180, 760, 30, '#AEB1B7', [0, 0]); base.threeDLayer = true; filho(base, MC, [0, 0, -380]); R3(base, 'x').setValue(90);
    var tec = rr(c, 'teclado', 1000, 360, 14, '#2A2A2E', [0, 0]); tec.threeDLayer = true; filho(tec, MC, [0, -4, -300]); R3(tec, 'x').setValue(90);
    var tp = rr(c, 'touchpad', 360, 200, 16, '#B5B7BC', [0, 0]); tp.threeDLayer = true; filho(tp, MC, [0, -4, -620]); R3(tp, 'x').setValue(90);
    var mcs = [lid, tm, base, tec, tp]; for (i = 0; i < mcs.length; i++) mb(mcs[i]);
    MC.inPoint = 15.65;
    ev(14.42, 'sobe', 0.3, 0.6); ev(14.95, 'pouso', 0.3, 0.5); ev(14.95, 'digita', 0.3, 0.35);
    ev(15.55, 'chicote', 0.5, 0.75); ev(15.95, 'pouso', -0.3, 0.55); ev(16.0, 'digita', -0.3, 0.35);
})();

// ================================================================ 9. FITA (16,8–19,35): onda azul → faixa com texto → pílula → check
var FT = novaComp('FITA');
(function () {
    var c = FT;
    var bg = solid(c, 'fundo', '#00010F'); K(O(bg), [[17.15, 0], [17.35, 100]]);
    // onda: traço grosso em S que entra por Trim Paths
    var onda = shape(c, 'onda');
    grupo(onda, 'o');
    var pth = cont(onda, 'o').addProperty('ADBE Vector Shape - Group');
    var s1 = new Shape(); s1.vertices = [[-150, 560], [320, 300], [760, 180], [1250, 420]];
    s1.inTangents = [[0, 0], [-160, 90], [-160, 0], [-150, -90]]; s1.outTangents = [[160, -90], [160, -90], [160, 0], [0, 0]]; s1.closed = false;
    var s2 = new Shape(); s2.vertices = [[-250, 760], [250, 700], [750, 630], [1350, 560]];
    s2.inTangents = [[0, 0], [-160, 20], [-160, 20], [-160, 20]]; s2.outTangents = [[160, -20], [160, -20], [160, -20], [0, 0]]; s2.closed = false;
    K(cont(onda, 'o').property('ADBE Vector Shape - Group').property('ADBE Vector Shape'), [[16.80, s1, 33, 33], [17.20, s1, 40, 10], [17.40, s2, 85, 33]]);
    var tr = cont(onda, 'o').addProperty('ADBE Vector Filter - Trim');
    var stk = cont(onda, 'o').addProperty('ADBE Vector Graphic - Stroke');
    stk = cont(onda, 'o').property('ADBE Vector Graphic - Stroke');
    stk.property('ADBE Vector Stroke Color').setValue(rgb('#1E9BDB'));
    stk.property('ADBE Vector Stroke Line Cap').setValue(1);
    K(stk.property('ADBE Vector Stroke Width'), [[16.80, 120, 33, 33], [17.40, 270, 60, 33]]);
    K(cont(onda, 'o').property('ADBE Vector Filter - Trim').property('ADBE Vector Trim End'), [[16.80, 0, 33, 10], [17.20, 100, 85, 33]]);
    onda.inPoint = 16.78; onda.outPoint = 17.45; mb(onda); P(onda).setValue([0, 0]);
    // faixa reta (null FAIXA gira e desce), com degradê azul e o texto correndo
    var FX = NUL(c, 'FAIXA', [540, 690]);
    K(P(FX), [[17.40, [540, 690], 'a'], [18.10, [540, 660], 'a'], [18.55, [560, 620], 50, 10], [18.62, [585, 520], 'a'], [18.90, [600, 540], 'a'], [19.05, [585, 540], 60, 33]]);
    K(R(FX), [[17.40, -3.5, 'a'], [18.10, -12, 'a'], [18.50, -16, 50, 10], [18.62, -4, 'a'], [18.90, 0, 60, 33]]);
    var fx1 = rr(c, 'faixa', 2400, 270, 0, '#1E9BDB', [0, 0]); filho(fx1, FX, [0, 0]); mb(fx1);
    K(rectProp(fx1, 'r', 'ADBE Vector Rect Size'), [[18.55, [2400, 270], 50, 10], [18.62, [990, 250], 'a'], [18.90, [675, 250], 'a'], [19.00, [450, 250], 'a'], [19.08, [250, 250], 70, 33]]);
    K(rectProp(fx1, 'r', 'ADBE Vector Rect Roundness'), [[18.55, 0], [18.62, 125]]);
    fx1.inPoint = 17.38; fx1.outPoint = 19.12;
    var grd = solid(c, 'degrade', '#000000', 2600, 600); filho(grd, FX, [0, 0]);
    var rp = fx(grd, 'ADBE Ramp'); var rpn = rp.name;
    grd.property('ADBE Effect Parade').property(rpn).property('ADBE Ramp-0001').setValue([400, 300]);
    grd.property('ADBE Effect Parade').property(rpn).property('ADBE Ramp-0002').setValue(rgb('#1784CC'));
    grd.property('ADBE Effect Parade').property(rpn).property('ADBE Ramp-0003').setValue([2200, 300]);
    grd.property('ADBE Effect Parade').property(rpn).property('ADBE Ramp-0004').setValue(rgb('#26BAE1'));
    var mold = rr(c, 'molde faixa', 2400, 270, 0, '#FFFFFF', [0, 0]); filho(mold, FX, [0, 0]);
    K(rectProp(mold, 'r', 'ADBE Vector Rect Size'), [[18.55, [2400, 270], 50, 10], [18.62, [990, 250], 'a'], [18.90, [675, 250], 'a'], [19.00, [450, 250], 'a'], [19.08, [250, 250], 70, 33]]);
    K(rectProp(mold, 'r', 'ADBE Vector Rect Roundness'), [[18.55, 0], [18.62, 125]]);
    grd.moveBefore(fx1); mold.moveBefore(grd); grd.setTrackMatte(mold, TrackMatteType.ALPHA);
    grd.inPoint = mold.inPoint = 17.38; grd.outPoint = mold.outPoint = 19.12;
    var tx = TX(c, TEXTOS.fita, 'SFProDisplay-Bold', 118, '#FFFFFF', [0, 0], ParagraphJustification.LEFT_JUSTIFY); filho(tx, FX, [0, 0]);
    var wtx = caixa(tx).width;
    K(P(tx), [[17.40, [-wtx / 2 + 120, 42], -1, -1], [18.55, [-wtx / 2 - 140, 42], 40, 10], [18.90, [-300, 42], 70, 33]]);
    tx.inPoint = 17.40; tx.outPoint = 19.05; mb(tx);
    // apaga da direita para a esquerda enquanto vira pílula
    var an = tx.property('ADBE Text Properties').property('ADBE Text Animators').addProperty('ADBE Text Animator');
    an.property('ADBE Text Animator Properties').addProperty('ADBE Text Opacity').setValue(0);
    var sl = tx.property('ADBE Text Properties').property('ADBE Text Animators').property(1).property('ADBE Text Selectors').addProperty('ADBE Text Selector');
    K(sl.property('ADBE Text Percent Start'), [[18.55, 100, -1, -1], [19.00, 0, -1, -1]]);
    var mt = rr(c, 'molde texto', 2400, 270, 0, '#FFFFFF', [0, 0]); filho(mt, FX, [0, 0]);
    K(rectProp(mt, 'r', 'ADBE Vector Rect Size'), [[18.55, [2400, 270], 50, 10], [18.62, [990, 250], 'a'], [18.90, [675, 250], 'a'], [19.00, [450, 250], 'a']]);
    tx.moveBefore(mold); mt.moveBefore(tx); tx.setTrackMatte(mt, TrackMatteType.ALPHA); mt.inPoint = 17.38; mt.outPoint = 19.05;
    // círculo: spinner → seta → check
    var cc = circ(c, 'circulo', 250, '#1E9BDB', [585, 540]); cc.inPoint = 19.05; cc.outPoint = 19.45;
    var sp = shape(c, 'spinner'); addEllipse(sp, 's', 110, 110); addStroke(sp, 's', '#FFFFFF', 10);
    var trs = cont(sp, 's').addProperty('ADBE Vector Filter - Trim'); trs = cont(sp, 's').property('ADBE Vector Filter - Trim');
    trs.property('ADBE Vector Trim End').setValue(30); K(trs.property('ADBE Vector Trim Offset'), [[19.05, 0, -1, -1], [19.12, 300, -1, -1]]);
    P(sp).setValue([585, 540]); sp.inPoint = 19.05; sp.outPoint = 19.12;
    var se = shape(c, 'seta'); caminho(se, 'a', [[0, -40], [0, 40]], false); addStroke(se, 'a', '#FFFFFF', 12);
    caminho(se, 'b', [[-30, 12], [0, 42], [30, 12]], false); addStroke(se, 'b', '#FFFFFF', 12);
    P(se).setValue([585, 540]); se.inPoint = 19.12; se.outPoint = 19.18;
    var ck = shape(c, 'check'); caminho(ck, 'c', [[-48, 2], [-14, 36], [50, -32]], false); addStroke(ck, 'c', '#FFFFFF', 16);
    var trc = cont(ck, 'c').addProperty('ADBE Vector Filter - Trim'); K(cont(ck, 'c').property('ADBE Vector Filter - Trim').property('ADBE Vector Trim End'), [[19.18, 0, -1, -1], [19.26, 100, 60, 33]]);
    P(ck).setValue([585, 540]); ck.inPoint = 19.18; ck.outPoint = 19.45;
    var fe = TX(c, TEXTOS.feito, 'SFProText-Medium', 26, '#1E9BDB', [585, 712], ParagraphJustification.CENTER_JUSTIFY); fe.inPoint = 19.22; fe.outPoint = 19.45;
    K(O(fe), [[19.22, 0], [19.28, 100]]);
    ev(16.82, 'viagem', 0.4, 0.75); ev(17.40, 'texto', 0, 0.5); ev(18.55, 'encolhe', 0, 0.55); ev(19.07, 'carregando', 0, 0.4); ev(19.19, 'check', 0, 0.7);
})();

// ================================================================ 10. NAVEGADOR (19,33–28,2): desktop, barra lateral rosa, pastas, arrastar
var NV = novaComp('JANELA', 1080, 2300);
var LIN = {};                                  // y de cada linha da barra lateral (coordenadas da JANELA)
(function () {
    var c = NV;
    // janela: barra lateral rosa (279–765) e área de conteúdo (765–1200)
    var jan = rr(c, 'janela', 940, 2300, 30, '#D46F8E', [279 + 470, 202 + 1150]); sombra(jan, 35, 20, 60);
    var area = rr(c, 'area conteudo', 440, 2240, 18, '#DB7F9A', [765 + 230, 232 + 1120]);
    var tb = [[300, '#FFFFFF'], [340, '#FFFFFF'], [890, '#FFFFFF'], [930, '#FFFFFF'], [970, '#FFFFFF']];
    for (var i = 0; i < tb.length; i++) { var d = circ(c, 'barra ferramentas ' + i, 16, tb[i][1], [tb[i][0], 232]); O(d).setValue(70); }
    // favoritos: quadrados que nascem e recebem o ícone
    var FAV = ['chatgpt', 'gmail', 'youtube'], FX = [369, 531, 697];
    for (i = 0; i < 3; i++) {
        var q = shape(c, 'favorito ' + i); addRect(q, 'r', 150, 120, 20); addFill(q, 'r', '#EE6F86'); addStroke(q, 'r', '#E8364E', 4); P(q).setValue([FX[i], 330]);
        var t0 = 19.45 + i * F(5);
        K(S(q), [[t0, [0, 0], 33, 10], [t0 + F(6), [100, 100], 85, 33]]);
        var ic = img(c, ICON + FAV[i] + '.png'); ic.name = 'icone ' + FAV[i]; S(ic).setValue([12, 12]); P(ic).setValue([FX[i], 330]);
        K(O(ic), [[19.95 + i * F(5), 0], [19.95 + i * F(5) + F(5), 100]]); K(S(ic), [[19.95 + i * F(5), [6, 6], 33, 10], [19.95 + i * F(5) + F(6), [12, 12], 85, 33]]);
        ev(t0, 'pop', -0.3 + i * 0.3, 0.4);
    }
    var esp = TX(c, TEXTOS.espaco, 'SFProText-Medium', 20, '#F6D2DC', [305, 430]); entra(esp, 20.55, 6, 8, 0);
    // pastas e itens (linhas de 75 px); a pasta Trabalho abre e empurra as outras 3 linhas para baixo
    function linha(nome, txt, icone, y, t, x) {
        var gL = NUL(c, nome, [x || 300, y]);
        var fd = rr(c, nome + ' destaque', 420, 64, 16, '#FFFFFF', [0, 0]); filho(fd, gL, [200, -8]); O(fd).setValue(0);
        var ic2;
        if (icone) { ic2 = img(c, ICON + icone + '.png'); S(ic2).setValue([7, 7]); filho(ic2, gL, [20, -8]); }
        else { ic2 = shape(c, nome + ' pasta'); addRect(ic2, 'r', 30, 24, 5); addStroke(ic2, 'r', '#C61F3E', 3); filho(ic2, gL, [20, -8]); }
        var tx = TX(c, txt, 'SFProText-Medium', 24, '#FFFFFF', [0, 0]); filho(tx, gL, [52, 0]);
        var ks = [ic2, tx];
        for (var k = 0; k < ks.length; k++) { K(O(ks[k]), [[t, 0], [t + F(6), 100]]); }
        K(P(gL), [[t, [x || 300, y + 12], 33, 10], [t + F(6), [x || 300, y], 85, 33]]);
        return { g: gL, fundo: fd, icone: ic2, texto: tx, y: y };
    }
    var Y0 = 520;
    var pastas = [];
    for (i = 0; i < 3; i++) pastas.push(linha('pasta ' + i, TEXTOS.pastas[i], null, Y0 + i * 75, 21.27 + i * F(5)));
    // clique em Trabalho (21,6): destaca e abre os filhos (22,27); as pastas de baixo descem 225 px
    K(O(pastas[0].fundo), [[21.70, 0], [21.80, 100]]);
    for (i = 1; i < 3; i++) { var yy = Y0 + i * 75; P(pastas[i].g).setValueAtTime(22.25, [300, yy]); P(pastas[i].g).setValueAtTime(22.45, [300, yy + 225]); }
    var ICF = ['pinterest', 'figma', 'gmail'], filhos = [];
    for (i = 0; i < 3; i++) filhos.push(linha('filho ' + i, TEXTOS.filhos[i], ICF[i], Y0 + 75 * (i + 1), 22.30 + i * F(3), 330));
    // linha divisória, nova aba e Instagram
    var dv = rr(c, 'divisoria', 400, 3, 1, '#E79AAE', [500, 1060]); K(O(dv), [[22.5, 0], [22.7, 100]]);
    var na = linha('nova aba', '+  ' + TEXTOS.novaAba, null, 1120, 22.55); na.icone.enabled = false; P(na.texto).setValue([12, 0]);
    O(na.texto).expression = 'value*0.7';
    var ins = linha('instagram', TEXTOS.insta, 'instagram', 1195, 22.60);
    // destaques ao passar por Pinterest (23,27), Figma (23,6) e Gmail (24,1)
    var hl = [[0, 23.27, 23.60], [1, 23.60, 24.10], [2, 24.10, 26.20]];
    for (i = 0; i < 3; i++) {
        var f = filhos[hl[i][0]].fundo;
        K(O(f), [[hl[i][1], 0], [hl[i][1] + F(3), 100], [hl[i][2], 100], [hl[i][2] + F(3), 0]]);
        K(O(pastas[0].fundo), [[21.70, 0], [21.80, 100], [23.20, 100], [23.30, 0]]);
        ev(hl[i][1], 'clique', 0.1, 0.45);
    }
    // arrastar o Instagram para "Redes sociais" (24,9–26,6): a linha segue o cursor com atraso
    var yRS = Y0 + 2 * 75 + 225;                        // y final de "Redes sociais"
    K(P(ins.g), [[22.60, [300, 1207], 33, 10], [22.60 + F(6), [300, 1195], 85, 33], [25.00, [300, 1195], 50, 30], [25.30, [330, 1180], 'a'],
                 [26.00, [330, 980], 'a'], [26.45, [320, yRS + 20], 'a'], [26.60, [330, yRS + 75], 70, 33]]);
    K(O(ins.fundo), [[25.00, 0], [25.10, 100], [26.55, 100], [26.70, 0]]);
    K(O(pastas[2].fundo), [[26.45, 0], [26.55, 100], [27.10, 100], [27.25, 60]]);
    ev(25.00, 'clique', 0.1, 0.5); ev(26.56, 'pouso', 0, 0.55); ev(27.0, 'pop', 0, 0.4);
    ev(21.65, 'clique', -0.2, 0.55); ev(22.30, 'abre', 0, 0.45);
    for (i = 0; i < 3; i++) ev(21.27 + i * F(5), 'pop', -0.2, 0.35);
    // painel branco à direita (22,93): prévia do site
    var PV = NUL(c, 'PREVIA', [1400, 820]);
    K(P(PV), [[22.93, [1400, 820], 33, 10], [23.25, [1000, 820], 85, 33], [27.0, [1000, 1100], 33, 33]]);
    var pf = rr(c, 'previa fundo', 420, 900, 18, '#FFFFFF', [0, 0]); filho(pf, PV, [0, 0]);
    for (i = 0; i < 9; i++) { var ln = rr(c, 'previa linha ' + i, i % 3 == 0 ? 160 : 240, 14, 7, '#E5E5EA', [0, 0]); filho(ln, PV, [-60 + (i % 3 == 0 ? -40 : 0), -360 + i * 46]); }
    var pi = img(c, ASSETS + 'galeria-5.png'); S(pi).setValue([45, 30]); filho(pi, PV, [0, 230]);
    var cores = ['#3B82F6', '#22C55E', '#EF4444', '#F5A524', '#3B82F6', '#22C55E', '#EF4444'];
    for (i = 0; i < 7; i++) { var dt = circ(c, 'rotulo ' + i, 22, cores[i], [0, 0]); filho(dt, PV, [170, -240 + i * 60]); K(O(dt), [[24.10, 0], [24.20, 100]]); }
    ev(22.95, 'painel', 0.6, 0.55);
    // texto da janela de trás (à esquerda, cortado)
    var lat = TX(c, TEXTOS.lateral.join('\r\r\r\r\r'), 'SFProDisplay-Bold', 40, '#16213E', [-30, 380]); setLeading(lat, 120); lat.moveToEnd();
    // cursor: seta (desliza) que vira mão ao arrastar
    var cur = shape(c, 'cursor'); caminho(cur, 'c', [[0, 0], [0, 34], [9, 26], [16, 40], [22, 37], [15, 24], [27, 24]], true); addFill(cur, 'c', '#FFFFFF'); addStroke(cur, 'c', '#111111', 2.5);
    K(P(cur), [[20.90, [620, 900], 33, 10], [21.60, [420, 525], 85, 40], [22.20, [430, 540], 'a'], [23.27, [470, 600], 'a'], [23.60, [470, 675], 'a'], [24.10, [470, 750], 'a'],
               [24.90, [420, 1190], 'a'], [25.30, [450, 1175], 'a'], [26.00, [450, 975], 'a'], [26.45, [440, yRS + 15], 'a'], [27.30, [470, yRS + 20], 50, 33]]);
    K(S(cur), [[21.60, [130, 130]], [21.65, [105, 105]], [21.72, [130, 130]], [25.00, [130, 130]], [25.05, [105, 105]], [25.12, [130, 130]]]);
    cur.inPoint = 20.88; mb(cur);
    var maoD = img(c, ASSETS + 'mao-agarra.png'); maoD.name = 'mao arrastando'; S(maoD).setValue([10, 10]); maoD.parent = cur; P(maoD).setValue([10, 10]);
    S(maoD).setValue([8, 8]); maoD.inPoint = 25.0; maoD.outPoint = 26.6;
})();
var DK = novaComp('DESKTOP');
(function () {
    var c = DK;
    var pp = img(c, ASSETS + 'papel-de-parede.png'); S(pp).setValue([52, 52]); P(pp).setValue([540, 540]);
    K(S(pp), [[19.33, [56, 56], 33, 33], [28.17, [52, 52], 33, 33]]);
    var tn = fx(pp, 'ADBE Tint'); pp.property('ADBE Effect Parade').property(tn.name).property('ADBE Tint-0001').setValue(rgb('#06207A'));
    pp.property('ADBE Effect Parade').property(tn.name).property('ADBE Tint-0002').setValue(rgb('#A9D2FF'));
    var j = c.layers.add(NV); j.name = 'JANELA'; mb(j);
    A(j).setValue([540, 0]);
    // câmera do navegador: sobe ~740 px em 7 s, quase sem parar, com degraus a cada ação
    K(P(j), [[19.33, [540, 0], 'a'], [21.0, [540, -110], 'a'], [22.5, [540, -300], 'a'], [24.0, [540, -560], 'a'], [25.5, [540, -700], 'a'], [27.0, [540, -840], 'a'], [28.17, [540, -900], 'a']]);
    P(j).expression = 'wiggle(4, 2)';   // tremida medida 2,2 px RMS
    K(S(j), [[19.33, [100, 100], 33, 33], [28.17, [102, 102], 33, 33]]);
})();

// ================================================================ RECRIACAO (comp final)
var M = proj.items.addComp('RECRIACAO', W, H, 1, DUR, FPS);
M.motionBlur = true; M.shutterAngle = 270; M.shutterPhase = -135; M.motionBlurSamplesPerFrame = 16;
solid(M, 'fundo', '#161616');
function poe(comp, nome, ini, fim) { var L = M.layers.add(comp); L.name = nome; L.inPoint = ini; L.outPoint = fim; return L; }
var l1 = poe(P1, 'ANTES', 0, 5.5);
var l2 = poe(AD, 'ADOBE', 5.5, 7.2);
var l3 = poe(PN, 'PAINEL', 6.25, 8.0); mb(l3);
var l4 = poe(GI, 'OBTER INFO', 7.85, F(290));
var l5 = poe(SP, 'MUSICA', F(290), 13.6);
var l6 = poe(CT, 'CARTAO', 13.55, 14.32);
var l7 = poe(TD, 'TRES D', 14.28, 17.45);
K(blur(l7), [[14.28, 18, 33, 10], [14.45, 0, 85, 33]]);
var l8 = poe(FT, 'FITA', 16.78, 19.45);
var l9 = poe(DK, 'DESKTOP', 19.33, DUR);
// íris de 3 quadros, borda suave de 120 px, centrada no check
var mk = l9.property('ADBE Mask Parade').addProperty('ADBE Mask Atom');
var el = new Shape(); var rx = 60, cx = 585, cy = 540, kk = 0.5523 * rx;
el.vertices = [[cx, cy - rx], [cx + rx, cy], [cx, cy + rx], [cx - rx, cy]];
el.inTangents = [[-kk, 0], [0, -kk], [kk, 0], [0, kk]]; el.outTangents = [[kk, 0], [0, kk], [-kk, 0], [0, -kk]]; el.closed = true;
l9.property('ADBE Mask Parade').property(1).property('ADBE Mask Shape').setValue(el);
l9.property('ADBE Mask Parade').property(1).property('ADBE Mask Feather').setValue([120, 120]);
K(l9.property('ADBE Mask Parade').property(1).property('ADBE Mask Offset'), [[19.33, -60, 33, 70], [19.43, 900, 20, 33]]);
ev(19.33, 'iris', 0, 0.7);
// títulos fixos no topo (antes: branco; depois: cinza escuro, apaga em 8,3–8,9)
var tA = TX(M, TEXTOS.tituloAntes, 'SFProDisplay-Medium', 84, '#FFFFFF', [540, 140], ParagraphJustification.CENTER_JUSTIFY); tA.outPoint = 5.5;
var tD = TX(M, TEXTOS.tituloDepois, 'SFProDisplay-Medium', 84, '#3A3A3C', [540, 140], ParagraphJustification.CENTER_JUSTIFY); tD.inPoint = 5.5; tD.outPoint = 9.0;
K(O(tD), [[8.30, 100], [8.90, 0]]);
var fim = solid(M, 'escurece', '#000000'); fim.inPoint = 27.4; K(O(fim), [[27.50, 0], [28.15, 100]]); fim.moveToBeginning();
ev(27.5, 'sai', 0, 0.35);

// ================================================================ salvar e eventos de som
EVENTOS.sort(function (a, b) { return a.t - b.t; });
var out = new File(BASE.fsName + '/audio/eventos.json');
out.encoding = 'UTF-8'; out.open('w');
var linhas = [];
for (var q = 0; q < EVENTOS.length; q++) { var e = EVENTOS[q]; linhas.push('{"t": ' + e.t + ', "kind": "' + e.kind + '", "pan": ' + (Math.round(e.pan * 100) / 100) + ', "v": ' + e.v + '}'); }
out.write('{"dur": ' + Math.round(DUR * 1000) / 1000 + ', "events": [\n' + linhas.join(',\n') + '\n]}\n'); out.close();
proj.save(new File(BASE.fsName + '/ae/trust-process.aep'));
return 'ok: ' + M.numLayers + ' camadas, ' + EVENTOS.length + ' eventos';
})();
