{"context":{"domain":"veste-app"},"layers":{"ApplicationLayer":{"reference":"ApplicationLayer","availableInstances":[{"reference":"ComponentsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"SystemsDataSet","params":{"filter":{"domain":"data2"},"pagination":{"size":1},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSource"}}}},{"reference":"ExternalComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"SystemsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"5e3b796d6228227ca637d0f4","name":"data2","domain":"data2","organization":"62292184611f480b3191c37c","visibility":"public","updatedAt":"2026-07-27T14:19:36.810Z"}]}},{"reference":"OrganizationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"DataComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"OneFileComponentInstancesDataSet","params":{"pagination":{"size":1},"master":{"dataset":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSet"}},"localField":"system","masterField":"_id"},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"FileComponentInstancesDataSource"}}}},{"reference":"ApplicationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ServiceComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@Data2TableDataSource","reference":"FileComponentInstancesDataSource","params":{"table":"fileComponentInstances","schema":[{"component":"data2-core-types@Field","params":{"key":"component","title":"Component","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"system","title":"System","component":"data2-core-primitives@ObjectId"}},{"component":"data2-core-types@Field","params":{"key":"displayName","title":"Display Name","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"params","title":"Params","component":"data2-core-primitives@Object"}},{"component":"data2-core-types@Field","params":{"key":"reference","title":"Reference","component":"data2-core-primitives@String"}}]}},{"component":"data2-core@MemoryDataSource","reference":"EmptyDataSource","params":{"initialData":[]}},{"reference":"ComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"UserComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"DataComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ServiceComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ExternalComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ApplicationsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}}],"processesParams":{}},"HostApplicationLayer":{"reference":"HostApplicationLayer","availableInstances":[{"_id":"5f15ff190528b92601890f71","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"SystemsTableDataSource"}},"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"domain"}}},"pk":"_id","fields":[{"component":"data2-core-types@FieldReference","params":{"key":"_id"}},{"component":"data2-core-types@FieldReference","params":{"key":"name"}},{"component":"data2-core-types@FieldReference","params":{"key":"domain"}},{"component":"data2-core-types@FieldReference","params":{"key":"visibility"}},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization._id"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.name"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.billingStatus"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.publicTrial.active"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"settings.defaultAccessPolicy"}}},"break":true}],"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"staticPagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"policies":[{"component":"data2-core-auth@Policy","params":{"allow":{"params":{"actions":[{"params":{"components":[{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"_id"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"domain"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"}]},"component":"data2-core-logical-operators@Or"}]},"component":"data2-core-flow@Series"}}}]},"reference":"SystemsDataSet","updatedAt":"2026-08-07T21:51:24.037Z","createdAt":"2020-07-20T20:31:21.838Z"},{"_id":"5f1601ce0528b92601890f7c","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":1000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"sort":{"params.package":1,"params.component":1},"pk":"_id","autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"staticFilter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}},"filter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}}},"reference":"ComponentsDataSet","updatedAt":"2025-11-05T19:37:01.935Z","createdAt":"2020-07-20T20:42:54.898Z"},{"_id":"5f9041dbc8da12be8b94aea4","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":2000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"UserComponentsDataSet","updatedAt":"2025-11-06T21:06:58.095Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"65d8c4fabc9dbb8f94de8d53","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ExternalComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ExternalComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:23.742Z","createdAt":"2024-02-23T16:17:01.816Z"},{"reference":"SystemsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"698a0c028a310c894be98bc8","name":"app","domain":"veste-app","visibility":"public","settings":{"defaultAccessPolicy":"private"},"updatedAt":"2026-08-14T20:00:20.536Z","createdAt":"2026-02-09T16:32:02.402Z"}]}},{"reference":"ComponentsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"5f52a278a575399a45d239b4","component":"data2-core-types@Component","params":{"package":"data2-core-primitives","component":"Router","interactions":{"component":"data2-core-types@FieldSet","params":{"fields":{"goBack":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-types@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"component":"data2-core-types@This","params":{}},"prop":"history.goBack","args":[]}}}},"icon":{"component":"data2-core-primitives@String","params":{"content":"arrow-left"}},"visibility":"public"}},"goTo":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"component":"data2-core-types@This","params":{}},"prop":"history.push","args":[{"component":"data2-core-types@Reference","params":{"reference":"url"}},{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"preserveQuery"}}}}]}},"parameters":[{"component":"data2-core-primitives@String","params":{"content":"url"}},{"component":"data2-core-primitives@String","params":{"content":"preserveQuery"}}]},"break":true},"icon":{"component":"data2-core-primitives@String","params":{"content":"share"}},"visibility":"public","arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Path to route"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Path to redirect user"}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"},{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Boolean"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Preserve Query"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Preserve query string parameters  preserve query parameters on navigating."}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"}]}},"open":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-types@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"component":"data2-core-types@This","params":{}},"prop":"history.push","args":[{"pathname":{"component":"data2-core-types@Reference","params":{"reference":"value"}}}]}},"parameters":["value"]}},"icon":{"component":"data2-core-primitives@String","params":{"content":"share"}},"visibility":"public","arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Link to open"}},"description":{"component":"data2-core-primitives@String","params":{"content":""}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"},{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Target"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Where to open the link"}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"oneOf":[{"params":{"content":"_blank"},"component":"data2-core-primitives@String"},{"params":{"content":"_self"},"component":"data2-core-primitives@String"},{"params":{"content":"_parent"},"component":"data2-core-primitives@String"},{"params":{"content":"_top"},"component":"data2-core-primitives@String"}]},"component":"data2-core-types@ComponentParameter"}]}},"close":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-types@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"params":{},"component":"data2-core-web@Window"},"prop":"close"}},"parameters":["value"]}},"icon":{"component":"data2-core-primitives@String","params":{"content":"times"}},"visibility":"public","arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Link to open"}},"description":{"component":"data2-core-primitives@String","params":{"content":""}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"},{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Target"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Where to open the link"}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"oneOf":[{"params":{"content":"_blank"},"component":"data2-core-primitives@String"},{"params":{"content":"_self"},"component":"data2-core-primitives@String"},{"params":{"content":"_parent"},"component":"data2-core-primitives@String"},{"params":{"content":"_top"},"component":"data2-core-primitives@String"}]},"component":"data2-core-types@ComponentParameter"}],"description":{"component":"data2-core-primitives@String","params":{"content":"Closes a window that was opened via router.open."}}}}}}}}},{"_id":"620d28658271aa4129919d89","component":"data2-core-types@Component","params":{"package":"data2-interface-services","component":"DeviceController","interactions":{"params":{"fields":{"postMessage":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":"data2-core-primitives@String","title":{"component":"data2-core-primitives@String","params":{"content":"data"}}}}]},"component":"data2-core-types@ComponentParameter"},"print":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Object"}},"flat":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"parameters":{"zoom":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Number"}},"title":{"component":"data2-core-primitives@String","params":{"content":"zoom"}},"visibility":"public"}}},"visibility":"public"},"component":"data2-core-types@ComponentParameter"}],"visibility":"public"},"component":"data2-core-types@ComponentParameter"},"share":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}}},"component":"data2-core-types@ComponentParameter"},"clipboard.copy":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}}}}]},"component":"data2-core-types@ComponentParameter"},"clipboard.paste":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}}}}]},"component":"data2-core-types@ComponentParameter"},"download":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Filename"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Content"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Object"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Options"}},"parameters":{"params":{"fields":{"type":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Mimetype"}}}}}},"component":"data2-core-types@FieldSet"}}}]},"component":"data2-core-types@ComponentParameter"},"downloadUrl":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Filename"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Url"}}}}]},"component":"data2-core-types@ComponentParameter"},"promptFiles":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":"data2-core-primitives@Object","flat":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"parameters":{"params":{"fields":{"multiple":{"component":"data2-core-types@ComponentParameter","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Multiple"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Whether or not to allow selecting multiple files"}},"component":"data2-core-primitives@Boolean"}},"acceptedFormats":{"component":"data2-core-types@ComponentParameter","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Accepted Formats"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Accepted file formats"}},"component":"data2-core-primitives@String","list":{"component":"data2-core-primitives@Boolean","params":{"content":true}}}},"timeout":{"component":"data2-core-types@ComponentParameter","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Timeout"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Max milliseconds to wait for file upload"}},"component":"data2-core-primitives@Number"}}}},"component":"data2-core-types@FieldSet"}}}],"visibility":"public"},"component":"data2-core-types@ComponentParameter"},"meetingRecord":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","definition":{"params":{"actions":[{"params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"meeting"}},"script":{"component":"data2-core-primitives@String","params":{"content":"(function() {\n  let mediaRecorder;\n  let audioChunks = [];\n  let combinedStream;\n  let audioContext;\n  \n  window.meetingCapture = async function() {\n    try {\n      // Solicitar acesso ao áudio da guia (e vídeo, que será ignorado depois)\n      const tabStream = await navigator.mediaDevices.getDisplayMedia({ \n        video: true, // Necessário para alguns navegadores\n        audio: true\n      });\n      \n      // Remover a trilha de vídeo\n      const tabAudioTrack = tabStream.getAudioTracks()[0];\n      \n      // Solicitar acesso ao microfone\n      const micStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n      const micAudioTrack = micStream.getAudioTracks()[0];\n      \n      // Criar um novo MediaStream com ambas as trilhas de áudio\n      combinedStream = new MediaStream([tabAudioTrack, micAudioTrack]);\n      \n      // Criar um contexto de áudio para misturar os streams\n      audioContext = new AudioContext();\n      const destination = audioContext.createMediaStreamDestination();\n      \n      // Conectar a trilha de áudio da guia\n      const tabSource = audioContext.createMediaStreamSource(new MediaStream([tabAudioTrack]));\n      tabSource.connect(destination);\n      \n      // Conectar a trilha de áudio do microfone\n      const micSource = audioContext.createMediaStreamSource(new MediaStream([micAudioTrack]));\n      micSource.connect(destination);\n      \n      // Iniciar gravação com o stream misturado\n      mediaRecorder = new MediaRecorder(destination.stream);\n      audioChunks = [];\n      mediaRecorder.ondataavailable = (e) => audioChunks.push(e.data);\n      mediaRecorder.start();\n      \n      console.log('Gravação iniciada. Chame meetingCaptureStop() para finalizar.');\n    } catch (error) {\n      console.error('Erro ao iniciar a captura:', error);\n    }\n  };\n  \n  window.meetingCaptureStop = function() {\n    return new Promise((resolve, reject) => {\n      if (!mediaRecorder) {\n        reject('Nenhuma gravação em andamento.');\n        return;\n      }\n      \n      mediaRecorder.onstop = () => {\n        const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });\n        combinedStream.getTracks().forEach(track => track.stop());\n        audioContext.close();\n        \n        resolve(audioBlob);\n        console.log('Gravação finalizada. O arquivo de áudio está pronto para upload.');\n      };\n      \n      mediaRecorder.stop();\n    });\n  };\n})();"}}},"component":"data2-core-web@Script"},{"component":"data2-core-types@Getter","params":{"module":{"params":{},"component":"data2-core-web@Window"},"prop":{"component":"data2-core-primitives@String","params":{"content":"meetingCapture"}}}}]},"component":"data2-core-flow@Series"}},"component":"data2-core-types@ComponentParameter"},"meetingRecordStop":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Filename"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Content"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Object"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Options"}},"parameters":{"params":{"fields":{"type":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Mimetype"}}}}}},"component":"data2-core-types@FieldSet"}}}],"definition":{"params":{"actions":[{"component":"data2-core-types@Getter","params":{"module":{"params":{},"component":"data2-core-web@Window"},"prop":{"component":"data2-core-primitives@String","params":{"content":"meetingCaptureStop"}}}}]},"component":"data2-core-flow@Series"}},"component":"data2-core-types@ComponentParameter"},"notify":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"private","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":"data2-core-primitives@Object","parameters":{"title":{"params":{"component":"data2-core-primitives@String","index":{"component":"data2-core-primitives@Number","params":{"content":0}},"title":{"component":"data2-core-primitives@String","params":{"content":"title"}}},"component":"data2-core-types@ComponentParameter"},"sound":{"params":{"component":"data2-core-types@FileComponentUrlReference","index":{"component":"data2-core-primitives@Number","params":{"content":1}},"title":{"component":"data2-core-primitives@String","params":{"content":"sound"}}},"component":"data2-core-types@ComponentParameter"}},"flat":{"component":"data2-core-primitives@Boolean","params":{"content":true}}}}]},"component":"data2-core-types@ComponentParameter"}}},"component":"data2-core-types@FieldSet"}}},{"_id":"6a99849b7848d0950257e0a0","component":"data2-core-types@Component","system":"698a0c028a310c894be98bc8","params":{"extends":"data2-core-primitives@Block","component":"johnjohn-deck-proposta","package":"veste-app","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"/* ───────────────────────────────────────────────────────────────────────────\n   Deck — Proposta de formalização · Veste S/A · John John\n   Provador virtual: POC e teste de 30 dias\n   Kit: apresentacao-data2 · arco de formalização · 11 slides\n   ─────────────────────────────────────────────────────────────────────────── */\n\n/* Assets no Drive do system veste-app */\nconst SYS   = 'veste-app'\nconst F_EXT = `https://${SYS}.data2.media/file/iNSYotTKA1cv_fJAa1K4E`\nconst F_LT  = `https://${SYS}.data2.media/file/6bERTVll1aRDU3Xo9NghW`\nconst LD2   = `https://${SYS}.data2.media/file/WLXAyS4HOHvTFytXu7S4P`\nconst RING  = `https://${SYS}.data2.media/file/TA2eFNVhnB7dlI9EPAEWb`\n\n/* Link da POC do John John — entra quando a demo do Gui estiver no ar */\nconst DEMO_URL = ''\n\nconst FONT_CSS = `@font-face{font-family:'AkzExt';src:url(${F_EXT}) format('opentype');font-weight:400;font-display:block}@font-face{font-family:'AkzExtLight';src:url(${F_LT}) format('opentype');font-weight:300;font-display:block}`\n\nconst PASS = 'johnjohn2026'\nconst OPEN = false\n\n/* Wordmark oficial John John — SVG do site, com currentColor para servir\n   claro sobre o --paper e branco sobre o fundo escuro */\nconst JJ_PATHS = `<path d=\"M1056.61,220.1c5.67,0,10.35-.71,14.02-2.13,3.67-1.41,6.34-3.71,8.01-6.88,1.67-3.17,2.5-7.59,2.5-13.27v-107.42h45.32v105.92c0,15.36-2.13,27.75-6.38,37.18-4.26,9.43-10.6,16.28-19.03,20.53-8.43,4.26-19.41,6.39-32.93,6.39-6.68,0-13.06-.42-19.15-1.25-6.09-.84-10.89-1.58-14.4-2.25v-38.06l1-1c7.18,1.67,14.19,2.42,21.03,2.25Z\"/><path d=\"M1151.76,126.95c6.84-12.93,16.19-22.49,28.04-28.67,11.85-6.17,25.37-9.26,40.56-9.26s29.46,3.09,41.31,9.26c11.85,6.18,21.11,15.74,27.79,28.67,6.68,12.94,10.02,29.26,10.02,48.95s-3.05,34.39-9.14,47.07c-6.09,12.69-15.02,22.33-26.79,28.92-11.77,6.6-26.17,9.89-43.19,9.89s-30.88-3.34-42.57-10.02c-11.69-6.68-20.66-16.4-26.92-29.17-6.26-12.77-9.39-28.33-9.39-46.7,0-19.7,3.42-36.01,10.27-48.95ZM1190.2,205.2c2.42,5.51,6.13,9.68,11.14,12.52,5.01,2.84,11.35,4.26,19.03,4.26s14.02-1.46,19.03-4.38c5.01-2.92,8.72-7.09,11.14-12.52,2.42-5.42,3.63-12.31,3.63-20.66v-18.53c0-7.84-1.17-14.48-3.51-19.91-2.34-5.42-6.01-9.64-11.02-12.65s-11.44-4.51-19.28-4.51-13.86,1.5-19.03,4.51c-5.18,3-8.93,7.22-11.27,12.65-2.34,5.43-3.51,12.06-3.51,19.91v18.53c0,8.35,1.21,15.27,3.63,20.78Z\"/><polygon points=\"1414.67 91.77 1414.67 155.37 1360.33 155.37 1360.33 91.77 1316.01 91.77 1316.01 259.03 1360.33 259.03 1360.33 194.18 1414.67 194.18 1414.67 259.03 1458.98 259.03 1458.98 91.77 1414.67 91.77\"/><path d=\"M1480.02,91.77h48.58l58.09,101.19-.33-101.19h44.65v167.26h-44.65l-62.01-101.19.25,101.19h-44.57V91.77Z\"/><path d=\"M22.03,220.1c5.67,0,10.35-.71,14.02-2.13,3.67-1.41,6.34-3.71,8.01-6.88,1.67-3.17,2.5-7.59,2.5-13.27v-107.42h45.32v105.92c0,15.36-2.13,27.75-6.38,37.18-4.26,9.43-10.6,16.28-19.03,20.53-8.43,4.26-19.41,6.39-32.93,6.39-6.68,0-13.06-.42-19.15-1.25-6.09-.84-10.89-1.58-14.4-2.25v-38.06l1-1c7.18,1.67,14.19,2.42,21.03,2.25Z\"/><path d=\"M117.18,126.95c6.84-12.93,16.19-22.49,28.04-28.67,11.85-6.17,25.37-9.26,40.56-9.26s29.46,3.09,41.31,9.26c11.85,6.18,21.11,15.74,27.79,28.67,6.68,12.94,10.02,29.26,10.02,48.95s-3.05,34.39-9.14,47.07c-6.09,12.69-15.02,22.33-26.79,28.92-11.77,6.6-26.17,9.89-43.19,9.89s-30.88-3.34-42.57-10.02c-11.69-6.68-20.66-16.4-26.92-29.17-6.26-12.77-9.39-28.33-9.39-46.7,0-19.7,3.42-36.01,10.27-48.95ZM155.61,205.2c2.42,5.51,6.13,9.68,11.14,12.52,5.01,2.84,11.35,4.26,19.03,4.26s14.02-1.46,19.03-4.38c5.01-2.92,8.72-7.09,11.14-12.52,2.42-5.42,3.63-12.31,3.63-20.66v-18.53c0-7.84-1.17-14.48-3.51-19.91-2.34-5.42-6.01-9.64-11.02-12.65s-11.44-4.51-19.28-4.51-13.86,1.5-19.03,4.51c-5.18,3-8.93,7.22-11.27,12.65-2.34,5.43-3.51,12.06-3.51,19.91v18.53c0,8.35,1.21,15.27,3.63,20.78Z\"/><polygon points=\"380.09 91.77 380.09 155.37 325.75 155.37 325.75 91.77 281.43 91.77 281.43 259.03 325.75 259.03 325.75 194.18 380.09 194.18 380.09 259.03 424.4 259.03 424.4 91.77 380.09 91.77\"/><path d=\"M445.43,91.77h48.58l58.09,101.19-.33-101.19h44.65v167.26h-44.65l-62.01-101.19.25,101.19h-44.57V91.77Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M754.28,328.55s.03-.06.05-.09\"/><path d=\"M861.77,331.93c-.15.19-.3.37-.46.56l.35-.43s.04-.06.1-.13Z\"/><path d=\"M992.02,218.74c-5.26-30.97-31.79-51.75-63.22-50.07-2.98.16-4.23,1.05-5.08,3.97-4.62,15.73-22.92,21.84-36.11,12.22-9.68-7.05-13.05-19.96-7.7-29.48,2.57-4.59,7.34-6.7,12.24-5.43-2.99,5.07-3.26,7.61-1.05,10.64,2.15,2.94,5.1,4.37,8.7,3.96,3.78-.43,6.22-2.82,7.71-6.16,3.62-8.11-1.29-17.68-10.63-20.84-13.02-4.4-26.41,2.67-30.81,16.21-7.73,23.77,7.3,43.73,21.45,50.82,4.4,2.21,9.33,3.37,14.41,5.15-.13,1.87-.51,4.27-.4,6.64.21,4.46-.23,9.24,1.24,13.29,4.91,13.53,15.14,21.26,29.16,23.69,13.1,2.27,25.02-6.77,26.83-19.94.64-4.65-.34-9.02-3.33-12.69-4.24-5.22-9.8-7.76-16.55-7.15-2.94.26-5.85,1.54-6.36,4.68-.32,1.98.39,4.58,1.56,6.26,1.79,2.58,4.71,2.19,7.44,1.17.75-.28,1.53-.52,2.29-.77,2.36,7.59-2.25,13.12-9.78,12.03-4.11-.6-7.24-2.75-9.26-6.29-2.79-4.91-3.35-10.2-2.53-15.79,1.6-10.96,17.46-20.03,29.93-17.33,9.18,1.98,14.49,8.32,18.83,16.14,11.93,21.52-1.42,46.05-17.97,54.46-9.5,4.83-19.21,4.5-28.94,1.32-19.23-6.28-32.02-18.51-34.99-39.29-.6-4.19-.56-8.47-.82-12.86-10.55.27-18.08-4.61-23.87-12.89-3.48-4.97-7.37-9.64-10.97-14.53-6.56-8.92-13.04-17.9-19.58-26.88.63-.9,1.13-1.7,1.72-2.43,8.8-11.05,17.63-22.07,26.4-33.13,5.68-7.17,13.09-10.04,22.11-9.35,1.22.09,2.59-.38,3.72-.94,3.22-1.6,5.13-3.98,4.5-7.92-.2-1.28.2-2.7.52-4.02,4.17-17.16,25.55-30.79,43.06-27.48,6.78,1.28,9.34,4.57,9.4,11.5.03,2.93-.67,4.24-3.95,4.36-5.1.19-7.28,4.52-5.03,9.22,1.95,4.06,7.05,5.96,11.89,4.18,5.79-2.13,9.45-6.45,11.42-12.15,3.76-10.91.27-22.64-9.05-30.53-3.41-2.88-6.99-5.56-10.62-8.43,5.17-6.78,6.12-13.94,1.54-21.28-2.87-4.6-7.18-6.78-13.09-6.3,4.23,7.24,4.38,14.16-1,20.58-5.21,6.23-12.48,6.86-19.8,6.47,0,2.9.09,5.42-.05,7.92-.05.92-.37,2.28-1,2.63-3.62,1.96-6.74,4.75-11.21,5.3-2.72.33-5.57,1.92-7.78,3.67-6.31,4.99-9.66,11.85-10.19,19.77-.31,4.68-2.72,7.44-6.53,8.99-7.79,3.17-13.87,8.43-19.42,14.51-.98,1.07-2.1,2.01-3.16,3.01-.22-.16-.44-.33-.66-.49.74-1.92,1.47-3.85,2.22-5.76,3.1-7.91,5.91-15.94,6.35-24.49.17-3.28,1.43-4.83,4.25-6.32,7.91-4.19,14.36-9.88,15.99-19.33,1.01-5.88.41-11.72-1.62-17.31-.83-2.27-.2-3.54,1.72-4.55,2.03-1.07,4-2.3,6.11-3.17,1.71-.7,2.29-1.64,2.29-3.48,0-3.02.17-6.08.62-9.06,1.51-9.89,7.55-14.87,17.5-14.66,1.03.02,2.06,0,3.1,0-.8-5.19-4.71-8.83-9.93-9.37-6.17-.63-11.52,1.41-16.41,4.98-1.14.83-2.25,1.71-3.11,2.37-2.45-2.19-4.36-4.58-6.83-5.99-10.17-5.84-20.79-5.89-31.27-1.02-5.85,2.72-9.67,7.59-11.19,13.99-1.3,5.48,2.36,10.96,7.87,11.96,3.98.72,8.45-1.58,10.17-5.22,1.47-3.11,1-4.29-3.14-7.97-.05-.05,0-.19,0-1.12,2.5.73,5.04.95,7.01,2.13,9.63,5.77,15.02,18.67,12.67,30.26-2.54,12.53-10.78,20.94-20.86,27.88-1.86,1.29-3.81,2.45-5.61,3.59.1.55.11.76.17.95.24.69.49,1.38.74,2.07,3.45,9.46,3.11,18.66-1.87,27.54-1.84,3.28-3.62,6.62-5.67,9.76-4.27,6.54-8.7,12.98-13.7,20.41-6.76-11.1-13.12-21.4-19.32-31.8-3.66-6.13-4.15-12.86-2.83-19.74.6-3.13,1.58-6.19,2.3-8.94-4.15-3.1-8.32-5.76-11.97-9.01-10.95-9.76-17.57-21.24-13.47-36.64,1.83-6.87,5.41-12.43,11.5-16.18,2.34-1.44,4.87-2.46,8-1.44-5.3,3.78-5.78,7.02-1.87,10.78,3.35,3.22,7.65,3.76,11.49,1.43,4.1-2.48,5.95-7.04,4.39-11.65-2.72-8.04-8.29-13.35-16.54-15.21-12.36-2.78-23.75-1.36-32.33,9.37-1.09-.87-2.05-1.68-3.06-2.42-4.78-3.51-10.01-5.53-16.07-5.2-4.73.25-9.7,3.7-10.49,9.44,1.25,0,2.5,0,3.74,0,8.99-.06,14.87,4.63,16.7,13.43.36,1.73.85,3.58.6,5.28-.81,5.54,1.33,8.65,6.6,10.69,4.59,1.78,4.39,2.31,3.15,7.07-4.01,15.39-.51,25.01,12.27,33.58,1.38.93,3.08,1.45,4.32,2.52,1.03.9,2,2.24,2.31,3.54,1.59,6.69,2.74,13.48,4.49,20.12,1.15,4.39,3.06,8.58,4.62,12.86-1.64-.82-2.77-1.98-3.87-3.17-5.05-5.49-10.26-10.88-17.34-13.67-5.47-2.16-8.5-5.32-9.04-11.62-1.03-12.05-8.82-19.76-20.76-22.65-3.1-.75-5.86-3.07-8.64-4.88-.53-.35-.57-1.67-.59-2.55-.07-2.55-.03-5.11-.03-7.69-16.72,2.07-29.56-10.94-21.22-26.85-5.17-.72-9.35.99-12.47,5.83-4.76,7.37-3.68,14.66,1.24,21.61-3.43,2.7-6.81,5.15-9.95,7.88-5.56,4.85-9.75,10.52-10.77,18.18-1.41,10.6,2.94,20.58,11.34,24.43,2.05.94,4.68,1.18,6.95.93,4.19-.47,7.27-4.44,7.03-8.32-.22-3.64-2.08-5.02-7.25-5.71-.86-.12-2.11-.99-2.32-1.75-1.95-7.1,1.93-12.66,9.27-13.83,6.1-.98,11.9.3,17.56,2.19,15.61,5.23,25.95,16.55,26.21,32.61.01.75.29,1.8.82,2.17,2.56,1.82,4.75,4.19,8.6,3.46,2.46-.47,5.38-.19,7.7.74,3.61,1.46,7.71,3.04,10.15,5.84,10.69,12.31,20.85,25.07,31.05,37.5-.59,1.08-.75,1.46-.99,1.79-10.74,14.44-21.51,28.85-32.2,43.32-4.55,6.15-10.76,9.07-18.18,9.82-1.11.11-2.23.17-3.56.26,0,1.42,0,2.66,0,3.89.06,6.74-.65,13.38-3.19,19.69-6.33,15.73-18.6,24.53-34.37,29.04-7.36,2.11-14.83,2.57-22.24,0-25.79-8.96-35.35-41.98-18.31-63.26,5.31-6.63,12.08-10.05,20.72-9.73,14.83.56,25.2,11.57,23.86,25.49-.79,8.23-6.11,14.07-13.07,14.5-5.68.36-11.36-4.23-8.62-11.9,1.6.36,3.2.84,4.84,1.06,2.99.41,5.04-.98,6.25-3.66,1.88-4.16-.93-8.36-6.05-9.07-8.8-1.22-18.13,5.45-19.81,14.16-2.39,12.4,8.6,25.51,21.55,25.98,17.39.62,39.15-16.01,35.5-38.14-.35-2.12-.33-4.31-.47-6.39.64-.25.92-.44,1.21-.47,11.53-1.26,20.28-7.19,27.36-16.05,11.25-14.07,11.94-31.47,4.65-44.69-6.57-11.92-23.62-15.38-34-7.11-7.17,5.71-7.98,16.28-1.67,21.7,3.34,2.87,8.16,2.77,11.79-.25,3.36-2.79,3.88-6.65,1.45-10.66-.39-.64-.75-1.29-1.19-2.07,7.78-.27,11.92,2.63,14.12,9.66,3.27,10.44-2.51,22.75-13.14,28-9.87,4.87-22.67,1.73-28.75-7.41-2.15-3.23-3.49-7-5.53-11.21-5.32.31-11.21.16-16.94,1.07-20.91,3.3-35.77,14.99-44.7,34-7.96,16.93-6.91,34.16-.15,51.17,4.34,10.93,10.47,20.77,20.04,27.97,13.76,10.34,29.21,11.5,45.41,7.75,4.32-1,8.59-2.24,13.64-3.58-4.65,8.3-9.42,15.49-17.22,20.01-4.71,2.73-9.56,2.75-14.26-.27-1.66-1.06-3.28-2.18-4.9-3.26-5.98,5.37-6.43,10.71-1.02,16.63,2.06,2.25,2.48,3.85,1.02,6.69-3.84,7.49-1.75,15.6-2.25,23.33,3.7-2.66,6.94-5.5,10.63-7.52,4.21-2.3,8.81-3.87,13.98-6.07,9.25,4.54,13.83,4.05,19.87-2.89-6.47-4.48-11.46-10.06-11.05-18.49.38-7.79,3.8-14.41,8.89-20.24.21,3.03-.04,5.92-.14,8.82-.49,13.82,3.44,26.03,13.38,35.94,7.39,7.35,15.78,12.04,26.76,9.54,9.27-2.1,21.48-9.01,22.98-23.06.09-.88.41-1.88.96-2.55,6.88-8.43,2.72-19.11-3.69-23.85-2.27-1.68-4.55-3.36-6.7-5.18-2.8-2.36-4.76-5.25-4.81-9.22.43-.06.83-.19,1.22-.17,2.57.18,4.69-.35,4.97-3.4.21-2.26-1.77-4.29-4.61-4.67-3.6-.49-6.85.48-9.7,2.73-5.01,3.97-7.28,11.09-5.25,17.57,1.13,3.64,2.82,7.1,4.25,10.65-10.71,8.51-11.31,14.26-2.44,24.83,2.86-1.35,3.76-3.59,4.21-6.36.63-3.89,3.82-5.06,6.83-2.65,2.11,1.69,2.79,3.79,1.55,6.39-3.43,7.22-13.84,10.17-20.46,5.63-7.48-5.13-11.77-12.43-11.98-21.36-.52-21.65,8.87-39.16,24.11-53.83,3.58-3.45,8.13-5.64,13.28-5.69,3.75-.03,6.48-1.84,9.31-4.22-3.59-4.14-4.28-8.92-3.3-13.94.58-2.96,1.39-5.92,2.52-8.71,5.1-12.63,13-23.58,20.95-34.49,1.56-2.14,3.19-4.24,5-6.64,9.93,13.14,19.62,25.89,25.84,40.81,3.21,7.7,5.1,15.61-.88,23.66,2.84,1.25,5.23,3.13,7.71,3.23,8.06.34,14.26,4.14,19.3,9.84,10.17,11.51,17.17,24.76,19.59,40.03,1.79,11.32-.33,21.68-9.48,29.7-3.46,3.03-7.39,4.21-11.89,3.59-5.45-.75-10.51-4.76-11.16-8.79-.5-3.13,1.32-5.81,4.24-6.25,2.88-.43,4.26.72,4.65,4.41.3,2.8,1.64,4.55,4.24,5.64,3.11-4.16,6.14-8.19,5.91-13.62-.24-5.8-4.98-8.29-8.67-11.35,1.39-3.05,2.9-5.82,3.95-8.75,2.44-6.78,1.38-13.02-3.71-18.28-3.31-3.43-7.45-4.52-12.08-3.42-2.35.56-3.55,2.26-3.34,4.63.2,2.29,1.83,3.12,3.99,3.08.71-.01,1.42,0,2.14,0-.14,4.3-1.56,6.97-5.32,9.98-2.29,1.83-4.7,3.51-6.95,5.38-5.24,4.35-9.47,14.19-3.42,22.25.85,1.13,1.56,2.59,1.71,3.97,1.04,9.38,6.53,15.53,14.56,19.44,8.94,4.35,18.05,5.76,27.11-.24,16.43-10.89,22.58-26.45,21.14-45.58-.15-1.92-.33-3.84-.5-5.76.27-.07.54-.13.81-.2,4.27,6.01,7.95,12.35,8.57,19.97.71,8.82-4.46,14.58-11.81,19.97,3.63,1.95,6.46,3.99,9.62,5.03,4.6,1.52,8.36-1.54,11.02-2.91,4.83,2.14,8.81,3.77,12.67,5.66,2.49,1.22,4.9,2.67,7.17,4.26,1.61,1.13,2.93,2.69,4.79,4.44,0-4.89.34-9.1-.1-13.23-.42-4-1.34-8.01-2.6-11.83-.67-2.04-.7-3.16.85-4.79,5.95-6.26,5.65-12.51-.67-17.53-.95.76-1.88,1.6-2.9,2.3-4.26,2.93-8.8,4.47-13.87,2.26-9.41-4.09-14.23-12.36-19.67-21.42,4.38,1.32,7.81,2.5,11.31,3.39,14.74,3.71,29.21,3.9,42.95-3.75,9.67-5.38,16.22-13.68,21.33-23.26,7.38-13.86,10.97-28.55,8.31-44.2Z\"/>`\n\nconst JJ = (cls) => `<svg class=\"${cls||''}\" viewBox=\"0 0 1631 350.8\" fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"John John\">${JJ_PATHS}</svg>`\n\nconst FUNDO = `<div class=\"bg\"><div class=\"grid\"></div>${JJ('mark')}</div>`\n\nconst CHIP = DEMO_URL\n  ? `<a class=\"chip\" href=\"${DEMO_URL}\" target=\"_blank\" rel=\"noopener\">Ver o provador funcionando</a>`\n  : ``\n\nconst GATE = `<div class=\"gwrap\">${FUNDO}\n  <div class=\"gcard\">\n    <div class=\"glock\"><img src=\"${LD2}\" style=\"height:22px\" alt=\"Data²\"><span>+</span>${JJ('gcb')}</div>\n    <div class=\"gsub\">Proposta · Veste S/A · John John</div>\n    <input class=\"ginput\" type=\"password\" placeholder=\"Senha de acesso\" autocomplete=\"off\"/>\n    <button class=\"gbtn\">Entrar</button>\n    <div class=\"gerr\">Senha incorreta — tente novamente.</div>\n  </div></div>`\n\nconst DECK = `<div class=\"deckwrap\">\n<header><img class=\"d2\" src=\"${LD2}\" alt=\"Data²\">${JJ('cb')}</header>\n<div class=\"counter\" id=\"counter\">01 — 11</div>\n<div class=\"hint\">↓ navegue</div>\n<nav class=\"dots\" id=\"dots\" aria-label=\"Slides\"></nav>\n<div class=\"deckroot\">\n\n  <!-- 01 · CAPA -->\n  <section class=\"capa\" id=\"capa\">\n    <div class=\"frame rv\">${FUNDO}\n      <div class=\"mid\">\n        <div class=\"lockup\">\n          <img class=\"d2m\" src=\"${LD2}\" alt=\"Data²\"><span class=\"plus\">+</span>${JJ('cbm')}\n        </div>\n        <div class=\"sub\">Provador virtual · POC e teste de 30 dias</div>\n      </div>\n    </div>\n    <div class=\"caption rv\">\n      <div class=\"frase-cap\">We build Data² while imagining a world where things just … work.</div>\n      <div class=\"meta\">Proposta · Setembro 2026</div>\n    </div>\n  </section>\n\n  <!-- 02 · ÍNDICE -->\n  <section id=\"indice\">\n    <div class=\"eyebrow rv\">Índice</div>\n    <div class=\"indice rv\">\n      <a href=\"#tese\"><span class=\"n\">01</span><span class=\"t\">A proposta</span></a>\n      <a href=\"#provador\"><span class=\"n\">02</span><span class=\"t\">O provador</span></a>\n      <a href=\"#pratica\"><span class=\"n\">03</span><span class=\"t\">Na prática</span></a>\n      <a href=\"#arq\"><span class=\"n\">04</span><span class=\"t\">Arquitetura</span></a>\n      <a href=\"#teste\"><span class=\"n\">05</span><span class=\"t\">O teste de 30 dias</span></a>\n      <a href=\"#kpis\"><span class=\"n\">06</span><span class=\"t\">O que vamos medir</span></a>\n      <a href=\"#comercial\"><span class=\"n\">07</span><span class=\"t\">Condições comerciais</span></a>\n      <a href=\"#respons\"><span class=\"n\">08</span><span class=\"t\">Responsabilidades</span></a>\n    </div>\n  </section>\n\n  <!-- 03 · STATEMENT -->\n  <section class=\"statement\" id=\"tese\">\n    <div class=\"eyebrow rv\">A proposta · <b>Veste S/A · John John</b></div>\n    <div class=\"split\">\n      <h1 class=\"rv\">O provador entra no site por 30 dias.</h1>\n      <p class=\"apoio destaque rv\">Sem custo de sprint, com 30 dias de geração de imagem\n        liberada e sem mexer no que já funciona. Esta proposta formaliza o que a POC entrega,\n        qual número ela precisa mover e como a continuidade vira um acordo pago.</p>\n    </div>\n  </section>\n\n  <!-- 04 · O PROVADOR -->\n  <section id=\"provador\">\n    <div class=\"eyebrow rv\">O provador</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(30px,6vh,60px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(28px,4vw,56px);line-height:1.12;max-width:16ch\">\n        Prova, combina e compra na mesma sessão.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">A peça do catálogo é aplicada na foto do próprio\n        cliente, em segundos. Cada prova fica salva no nome dele, com o preço e o caminho de\n        volta para a página do produto.</p>\n    </div>\n    <div class=\"pilares\">\n      <div class=\"pilar rv d2\"><span class=\"k\">01 · Provador</span>\n        <div class=\"t\">A peça no corpo do cliente</div>\n        <p>Ele manda uma foto, escolhe a peça e vê o resultado. A roupa atual é removida antes\n           da troca, e o enquadramento da foto original é preservado.</p></div>\n      <div class=\"pilar rv d3\"><span class=\"k\">02 · Meu Look</span>\n        <div class=\"t\">Várias peças, uma foto</div>\n        <p>Camisa, calça e jaqueta provadas em sequência, sobre o resultado anterior. É como o\n           cliente compra de verdade: por look, não por item.</p></div>\n      <div class=\"pilar rv d4\"><span class=\"k\">03 · Minhas Provas</span>\n        <div class=\"t\">A prova vira vitrine</div>\n        <p>Cada prova fica salva com preço e link para a PDP. O cliente volta para a galeria\n           dele e compra de lá, dias depois.</p></div>\n    </div>\n    <div class=\"rv d5\">${CHIP}</div>\n  </section>\n\n  <!-- 05 · NA PRÁTICA -->\n  <section id=\"pratica\">\n    <div class=\"eyebrow rv\">Na prática</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(26px,5vh,48px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">\n        Duas dúvidas que hoje terminam em devolução.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">Se a peça combina com quem vai usar, e se ela\n        combina com o resto do look. Nenhuma das duas a foto da modelo responde, e as duas\n        acontecem no site do John John toda semana.</p>\n    </div>\n    <div class=\"comps rv\">\n      <div class=\"comp\">\n        <div class=\"ctit\">Decidir se a peça combina com você</div>\n        <div class=\"hj\">\n          <div class=\"lk\">Hoje · a foto da modelo</div>\n          <ul class=\"steps\">\n            <li>O cliente vê a peça num corpo que não é o dele</li>\n            <li>Tenta imaginar a cor e o comprimento em si mesmo</li>\n            <li>Compra na dúvida — e devolve quando não gosta do que vê</li>\n          </ul>\n        </div>\n        <div class=\"cn\">\n          <div class=\"lk\">Com o provador · segundos</div>\n          <ul class=\"steps\">\n            <li>Manda uma foto de corpo inteiro, uma vez</li>\n            <li>Escolhe a peça no catálogo e vê ela em si mesmo</li>\n            <li>Só leva o que já viu vestido</li>\n          </ul>\n        </div>\n      </div>\n      <div class=\"comp\">\n        <div class=\"ctit\">Montar um look</div>\n        <div class=\"hj\">\n          <div class=\"lk\">Hoje · quatro abas abertas</div>\n          <ul class=\"steps\">\n            <li>Abre uma aba por produto e compara fotos de modelos diferentes</li>\n            <li>Imagina a camisa com a calça sem nunca ver as duas juntas</li>\n            <li>Leva uma peça e deixa o resto</li>\n          </ul>\n        </div>\n        <div class=\"cn\">\n          <div class=\"lk\">Com o Meu Look · uma foto</div>\n          <ul class=\"steps\">\n            <li>Marca as peças que quer provar juntas</li>\n            <li>Prova as quatro na mesma foto, em sequência</li>\n            <li>Compra o look inteiro pela galeria de provas</li>\n          </ul>\n        </div>\n      </div>\n    </div>\n  </section>\n\n  <!-- 06 · ARQUITETURA -->\n  <section id=\"arq\">\n    <div class=\"eyebrow rv\">Arquitetura e integração</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,42px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">\n        Integramos por leitura. Nada do que funciona muda.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">O provador consulta a API pública de catálogo do\n        johnjohndenim.com.br no momento da prova. Não há réplica de base, carga noturna nem\n        alteração no tema da loja.</p>\n    </div>\n    <div class=\"arq rv\">\n      <div class=\"col\">\n        <div class=\"col-h\">Sistemas do John John · intocados</div>\n        <div class=\"box\"><div class=\"bn\">VTEX</div>\n          <div class=\"bd\">Catálogo, PDP, carrinho e checkout seguem como estão</div></div>\n        <div class=\"box\"><div class=\"bn\">johnjohndenim.com.br</div>\n          <div class=\"bd\">O provador entra como um bloco no tema, sem reescrever a loja</div></div>\n      </div>\n      <div class=\"link\"><span>leitura · API</span></div>\n      <div class=\"core\">\n        <div class=\"ch\">Data² · engine de provador</div>\n        <div class=\"box\"><div class=\"bn\">Leitura de catálogo</div>\n          <div class=\"bd\">Consulta as categorias reais — Camisas, Camisetas, Calças, Jaquetas,\n            Vestidos — na hora da prova</div></div>\n        <div class=\"box\"><div class=\"bn\">Provador de IA</div>\n          <div class=\"bd\">Checa a foto, decide o que remover e aplica a peça mantendo o\n            enquadramento</div></div>\n        <div class=\"box\"><div class=\"bn\">Painel de resultados</div>\n          <div class=\"bd\">Registra cada prova, cada clique em Comprar e os produtos mais\n            provados</div></div>\n      </div>\n      <div class=\"link\"><span>embed</span></div>\n      <div class=\"col\">\n        <div class=\"col-h\">Cliente final</div>\n        <div class=\"box\"><div class=\"bn\">Navegador</div>\n          <div class=\"bd\">Dentro do site, na mesma sessão de compra</div></div>\n        <div class=\"box\"><div class=\"bn\">Minhas Provas</div>\n          <div class=\"bd\">Galeria por e-mail, com preço e Comprar apontando para a PDP</div></div>\n      </div>\n    </div>\n  </section>\n\n  <!-- 05 · O TESTE DE 30 DIAS -->\n  <section id=\"teste\">\n    <div class=\"eyebrow rv\">O teste</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(20px,3.4vh,34px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">\n        Trinta dias no ar, com três marcos.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">A janela começa no dia em que o provador entra no\n        site. As datas de calendário são fixadas na confirmação desta proposta.</p>\n    </div>\n    <div class=\"ondas rv\">\n      <div class=\"onda\"><div class=\"fase\">Dia 1</div><div class=\"t\">No ar</div>\n        <ul>\n          <li>Provador publicado como embed no site do John John</li>\n          <li>Geração de imagem liberada, até 2.000 provas</li>\n          <li>Linha de base de conversão registrada</li>\n          <li>Datapoints do funil chegando ao time do John John</li>\n        </ul></div>\n      <div class=\"onda\"><div class=\"fase\">Dia 15</div><div class=\"t\">Primeira leitura</div>\n        <ul>\n          <li>Volume de provas e taxa de conclusão</li>\n          <li>Ajuste de prompt e de catálogo, se preciso</li>\n          <li>Geração de imagem segue liberada até o dia 30</li>\n        </ul></div>\n      <div class=\"onda\"><div class=\"fase\">Dia 30</div><div class=\"t\">Análise e acordo</div>\n        <ul>\n          <li>Conversão de quem provou contra a média do site</li>\n          <li>Cliques em Comprar depois da prova</li>\n          <li>Resultados analisados e continuidade em acordo pago</li>\n        </ul></div>\n    </div>\n  </section>\n\n  <!-- 09 · O QUE VAMOS MEDIR -->\n  <section id=\"kpis\">\n    <div class=\"eyebrow rv\">O que vamos medir</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,44px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">\n        Dois números decidem a continuidade.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">Não medimos engajamento nem tempo de página. O\n        teste responde se quem prova compra mais — e se a prova leva ao carrinho. O provador\n        entra como embed no site, e a engine envia os datapoints do funil ao time do John John.</p>\n    </div>\n    <div class=\"kpis seis rv\">\n      <div class=\"k\"><div class=\"kt\">Conversão de quem provou</div>\n        <p>Taxa de conversão das sessões que geraram prova, contra a média do site no mesmo\n           período.</p>\n        <div class=\"kb\">Linha de base: a conversão do site hoje, informada no dia 1</div></div>\n      <div class=\"k\"><div class=\"kt\">Clique em Comprar após a prova</div>\n        <p>Quantas provas terminam em clique para a página do produto. Mede intenção direta,\n           não curiosidade.</p>\n        <div class=\"kb\">Registrado pela engine desde a primeira prova</div></div>\n      <div class=\"k\"><div class=\"kt\">Como medimos</div>\n        <p>Cada prova, cadastro e clique sai da engine como datapoint, com produto, horário e\n           sessão. O funil é montado na ferramenta que o John John já usa, e o painel da Data²\n           fica aberto durante os 30 dias para os dois lados conferirem o mesmo número.</p>\n        <div class=\"kb\">Formato combinado com o time: dataLayer, webhook ou export</div></div>\n    </div>\n  </section>\n\n  <!-- 10 · CONDIÇÕES COMERCIAIS -->\n  <section id=\"comercial\">\n    <div class=\"eyebrow rv\" style=\"margin-bottom:clamp(14px,2.4vh,24px)\">Condições comerciais</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(14px,2.2vh,22px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.4vw,48px);line-height:1.12;max-width:16ch\">\n        Trinta dias liberados. Depois, um acordo pago.</h2>\n      <p class=\"apoio destaque rv\" style=\"margin-top:0\">A construção e o teste correm por conta\n        da Data², com a geração de imagem liberada por 30 dias, até 2.000 provas. No fim da\n        janela os resultados são analisados e a continuidade vira um acordo pago.</p>\n    </div>\n    <div class=\"custos rv\">\n      <div class=\"row\"><div>\n        <div class=\"t\">Construção da POC</div>\n        <div class=\"d\">Engine de provador com o catálogo John John ao vivo, Meu Look, Minhas\n          Provas, painel de resultados e o bloco de embed para o site.</div>\n      </div><div class=\"v\">R$ 0</div></div>\n      <div class=\"row\"><div>\n        <div class=\"t\">Teste de 30 dias</div>\n        <div class=\"d\">Acompanhamento durante a janela: ajuste de prompt, ajuste de catálogo e\n          leitura dos números com o time do John John.</div>\n      </div><div class=\"v\">R$ 0</div></div>\n      <div class=\"row\"><div>\n        <div class=\"t\">Geração de imagem · 30 dias</div>\n        <div class=\"d\">Até 2.000 provas na janela. Catálogo, storage e acessos incluídos.</div>\n      </div><div class=\"v\">Liberada</div></div>\n      <div class=\"row total\"><div>\n        <div class=\"t\">Depois dos 30 dias</div>\n        <div class=\"d\">Continuidade dimensionada pelo volume que a POC mostrou.</div>\n      </div><div class=\"v\">Acordo pago</div></div>\n    </div>\n    <p class=\"cond rv\">Ao se aproximar das 2.000 provas, a Data² avisa antes de qualquer\n      cobrança. Evolução de escopo é orçada em separado.</p>\n  </section>\n\n  <!-- 11 · RESPONSABILIDADES -->\n  <section id=\"respons\">\n    <div class=\"eyebrow rv\">Responsabilidades</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,44px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">\n        O que cada lado põe na mesa.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">A POC não depende de projeto de TI. Depende de\n        cinco liberações pequenas — e cada uma tem dono. A única que precisa de agenda é a\n        presença do time nas sessões de decisão.</p>\n    </div>\n    <div class=\"pilares dois\">\n      <div class=\"pilar rv d2\"><span class=\"k\">A Data² entrega</span>\n        <ul class=\"klist\">\n          <li><b>Engine no ar</b> — provador, Meu Look e Minhas Provas publicados e monitorados</li>\n          <li><b>Bloco de embed</b> — um trecho para o time de front colar, sem alterar o tema</li>\n          <li><b>Datapoints do funil</b> — cada prova, cadastro e clique no formato combinado</li>\n          <li><b>Painel de resultados</b> — aberto ao John John durante os 30 dias</li>\n          <li><b>Acompanhamento</b> — ajuste de prompt e de catálogo dentro da janela</li>\n        </ul></div>\n      <div class=\"pilar rv d3\"><span class=\"k\">O John John libera</span>\n        <ul class=\"klist\">\n          <li><b>Time nas sessões de decisão</b> — Tech, UI/UX e stakeholders presentes nos pontos de decisão da janela</li>\n          <li><b>Publicação do embed</b> — um contato de plataforma que coloca o bloco no ar</li>\n          <li><b>Onde o provador entra</b> — página de produto, home ou landing de campanha</li>\n          <li><b>Linha de base de conversão</b> — o número do site hoje, para a comparação</li>\n          <li><b>Uso de imagem</b> — aprovação para o cliente gerar e guardar a própria prova</li>\n        </ul></div>\n    </div>\n  </section>\n\n  <!-- 11 · FECHAMENTO -->\n  <section class=\"dark fecho\" data-dark id=\"fim\">${FUNDO}\n    <div class=\"mid\">\n      <img class=\"ring branco rv\" style=\"width:52px\" src=\"${RING}\" alt=\"\">\n      <p class=\"frase rv\">We build Data² while imagining a world where things just <i>…</i> work.</p>\n      <div class=\"lockup rv\">\n        <img class=\"d2m\" style=\"height:26px\" src=\"${LD2}\" alt=\"Data²\">\n        <span class=\"plus\" style=\"font-size:20px\">+</span>${JJ('cbm-s')}\n      </div>\n      <div class=\"sub rv\">gabi.carmo@data2.app · data2.app</div>\n    </div>\n  </section>\n\n</div></div>`\n\nfunction injectFonts(){\n  try{\n    if(!document.getElementById('akz-deck-fonts')){\n      const st=document.createElement('style')\n      st.id='akz-deck-fonts'\n      st.textContent=FONT_CSS\n      document.head.appendChild(st)\n    }\n  }catch(e){}\n}\n\nfunction initDeck(host){\n  const wrap=host&&host.querySelector('.deckwrap'); if(!wrap) return\n  if(wrap.dataset.init==='1') return\n  wrap.dataset.init='1'\n  const rootEl=wrap.querySelector('.deckroot')\n  const slides=[].slice.call(rootEl.querySelectorAll('section'))\n  const dots=wrap.querySelector('.dots'), counter=wrap.querySelector('.counter')\n  dots.innerHTML=''\n  const pad=n=>(n<10?'0':'')+n\n  let cur=0\n  counter.textContent=pad(1)+' — '+pad(slides.length)\n  slides.forEach((s,i)=>{\n    const a=document.createElement('a')\n    a.href='#'+s.id; a.setAttribute('aria-label','Slide '+(i+1))\n    dots.appendChild(a)\n  })\n  const links=[].slice.call(dots.children)\n  if(links[0])links[0].classList.add('on')\n\n  const setActive=i=>{\n    if(i===cur)return\n    cur=i\n    counter.textContent=pad(cur+1)+' — '+pad(slides.length)\n    links.forEach((l,k)=>l.classList.toggle('on',k===cur))\n    wrap.classList.toggle('on-dark',slides[cur].hasAttribute('data-dark'))\n    wrap.classList.toggle('last',cur===slides.length-1)\n  }\n\n  const revIO=new IntersectionObserver(es=>{\n    es.forEach(e=>{if(e.isIntersecting){e.target.classList.add('in');revIO.unobserve(e.target)}})\n  },{root:rootEl,rootMargin:'0px 0px 12% 0px',threshold:.01})\n  slides.forEach(s=>revIO.observe(s))\n\n  const ratios=new Array(slides.length).fill(0)\n  const actIO=new IntersectionObserver(es=>{\n    es.forEach(e=>{const i=slides.indexOf(e.target);if(i>-1)ratios[i]=e.isIntersecting?e.intersectionRatio:0})\n    let bi=cur,bv=-1\n    ratios.forEach((r,i)=>{if(r>bv){bv=r;bi=i}})\n    if(bv>0)setActive(bi)\n  },{root:rootEl,threshold:[0,.15,.35,.55,.75,1]})\n  slides.forEach(s=>actIO.observe(s))\n\n  setTimeout(()=>{\n    if(!rootEl.querySelector('section.in'))slides.forEach(s=>s.classList.add('in'))\n  },500)\n\n  const rm=(typeof matchMedia==='function')&&matchMedia('(prefers-reduced-motion: reduce)').matches\n  const go=i=>{\n    i=Math.max(0,Math.min(slides.length-1,i))\n    slides[i].scrollIntoView({behavior:rm?'auto':'smooth'})\n  }\n\n  wrap.addEventListener('click',ev=>{\n    const a=ev.target.closest&&ev.target.closest('a[href^=\"#\"]'); if(!a)return\n    ev.preventDefault()\n    const t=slides.find(s=>s.id===a.getAttribute('href').slice(1))\n    if(t)t.scrollIntoView({behavior:rm?'auto':'smooth'})\n  })\n\n  window.addEventListener('keydown',e=>{\n    if(!wrap.isConnected)return\n    if(e.target&&/^(INPUT|TEXTAREA)$/.test(e.target.tagName))return\n    if(e.key==='ArrowDown'||e.key==='ArrowRight'||e.key==='PageDown'||e.key===' '){e.preventDefault();go(cur+1)}\n    if(e.key==='ArrowUp'||e.key==='ArrowLeft'||e.key==='PageUp'){e.preventDefault();go(cur-1)}\n    if(e.key==='Home'){e.preventDefault();go(0)}\n    if(e.key==='End'){e.preventDefault();go(slides.length-1)}\n  })\n}\n\n/* Este player não re-renderiza de forma confiável quando d2.state muda: a senha\n   gravava a sessão e o gate continuava na tela. Então a fase vive numa variável de\n   módulo e a troca de tela é feita na mão, com innerHTML. */\nlet phase = 'gate'\n\nfunction mountGate(host){\n  const card=host.querySelector('.gcard'); if(!card||card.dataset.wired==='1') return\n  card.dataset.wired='1'\n  const inp=host.querySelector('.ginput'), btn=host.querySelector('.gbtn')\n  const check=()=>{\n    if(!inp) return\n    if(inp.value===PASS){\n      try{sessionStorage.setItem('deckJohnJohnUnlocked','1')}catch(e){}\n      showDeck(host)\n    } else {\n      const er=host.querySelector('.gerr')\n      if(er)er.style.display='block'\n      card.classList.remove('shake');void card.offsetWidth;card.classList.add('shake')\n      if(inp.select)inp.select()\n    }\n  }\n  if(btn)btn.addEventListener('click',check)\n  if(inp)inp.addEventListener('keydown',e=>{if(e.key==='Enter')check()})\n}\n\nfunction showDeck(host){\n  phase='deck'\n  host.innerHTML=DECK\n  initDeck(host)\n}\n\nfunction sync(d2,root){\n  const host=(d2&&d2.$&&d2.$('.deckhost'))||((root||document).querySelector('.deckhost'))\n  if(!host) return\n  if(phase==='deck'){\n    if(!host.querySelector('.deckwrap')) host.innerHTML=DECK\n    initDeck(host)\n    return\n  }\n  if(!host.querySelector('.gwrap')) host.innerHTML=GATE\n  mountGate(host)\n}\n\nexport default {\n  css:`\n:host,.deckwrap,.gwrap{\n  --paper:#F5F4F0;\n  --ink:#15161A;\n  --muted:#6A6E77;\n  --accent:#96570F;\n  --accent-soft:#C89A4A;\n  --ok:#2C6B4A;\n  --bad:#A33427;\n  --dark:#17253F;\n  --dark-2:#22314F;\n  --linha:rgba(21,22,26,.13);\n  --mx:clamp(20px,4vw,56px);\n  --ext:'AkzExt','Helvetica Neue',Helvetica,Arial,sans-serif;\n  --lt:'AkzExtLight','Helvetica Neue',Helvetica,Arial,sans-serif;\n  --sf:-apple-system,BlinkMacSystemFont,'SF Pro Text','Inter','Helvetica Neue',Helvetica,Arial,sans-serif;\n}\n*{box-sizing:border-box;margin:0;padding:0}\n.deckhost{display:block;width:100%;height:100%}\n\n/* ---------- arquitetura de scroll ---------- */\n.deckwrap{position:relative;height:100vh;height:100svh;overflow:hidden;\n  background:var(--paper);color:var(--ink);font-family:var(--lt);\n  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}\n.deckroot{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;\n  scroll-snap-type:y proximity;scroll-behavior:smooth;\n  -webkit-overflow-scrolling:touch;overscroll-behavior-y:contain}\n\n/* ---------- chrome ---------- */\nheader{position:absolute;inset:0 0 auto 0;z-index:40;display:flex;\n  justify-content:space-between;align-items:center;padding:22px var(--mx) 34px;\n  pointer-events:none;background:linear-gradient(to bottom,var(--paper) 52%,rgba(245,244,240,0))}\n.deckwrap.on-dark header{background:none}\nheader img{height:16px;display:block;filter:brightness(0);opacity:.92}\nheader svg.cb{height:15px;width:auto;display:block;color:var(--ink)}\n.deckwrap.on-dark header img{filter:none;opacity:1}\n.deckwrap.on-dark header svg.cb{color:#fff}\n.counter{position:absolute;z-index:40;left:var(--mx);bottom:38px;font-family:var(--lt);\n  font-size:11px;letter-spacing:.22em;color:var(--muted)}\n.deckwrap.on-dark .counter{color:rgba(255,255,255,.75)}\nnav.dots{position:absolute;z-index:40;right:clamp(14px,2.4vw,32px);top:50%;\n  transform:translateY(-50%);display:flex;flex-direction:column;gap:14px}\nnav.dots a{width:6px;height:6px;border-radius:50%;background:var(--muted);opacity:.35;\n  transition:opacity .3s,transform .3s}\nnav.dots a.on{opacity:1;transform:scale(1.5);background:var(--ink)}\n.deckwrap.on-dark nav.dots a,.deckwrap.on-dark nav.dots a.on{background:#fff}\n.hint{position:absolute;z-index:40;right:var(--mx);bottom:38px;font-size:11px;\n  letter-spacing:.22em;color:var(--muted);text-transform:uppercase;transition:opacity .4s}\n.deckwrap.last .hint{opacity:0}\n.deckwrap.on-dark .hint{color:rgba(255,255,255,.6)}\n\n/* ---------- slide ---------- */\nsection{min-height:100vh;min-height:100svh;scroll-snap-align:start;position:relative;\n  display:flex;flex-direction:column;justify-content:center;\n  padding:clamp(84px,12vh,140px) clamp(20px,7vw,120px);overflow:hidden}\n.eyebrow{font-size:12px;letter-spacing:.3em;text-transform:uppercase;color:var(--muted);\n  margin-bottom:clamp(20px,4vh,44px)}\n.eyebrow b{font-weight:400;color:var(--accent)}\n\n/* ---------- reveals ---------- */\n.rv{opacity:0;transform:translateY(26px);\n  transition:opacity .9s cubic-bezier(.2,.6,.2,1),transform .9s cubic-bezier(.2,.6,.2,1)}\nsection.in .rv{opacity:1;transform:none}\nsection.in .rv:nth-child(2),section.in .d2{transition-delay:.12s}\nsection.in .rv:nth-child(3),section.in .d3{transition-delay:.24s}\nsection.in .rv:nth-child(4),section.in .d4{transition-delay:.36s}\nsection.in .rv:nth-child(5),section.in .d5{transition-delay:.48s}\nsection.in .rv:nth-child(6),section.in .d6{transition-delay:.6s}\n\n/* ---------- tipografia ---------- */\nh1,h2{font-family:var(--ext);font-weight:400;text-wrap:balance}\n.apoio{max-width:44ch;font-size:clamp(15px,1.5vw,19px);line-height:1.65;color:var(--muted)}\n.apoio::before{content:'';display:block;width:36px;height:2px;background:var(--accent);\n  margin-bottom:18px}\n.apoio.destaque{color:var(--ink);font-size:clamp(16px,1.7vw,21px);line-height:1.6}\n.split{display:grid;grid-template-columns:1.4fr .8fr;gap:clamp(28px,6vw,90px);align-items:end}\n.split>*{min-width:0}\n@media(max-width:820px){.split{grid-template-columns:1fr}}\n\n.apoio,.lead,.pilar p,.onda li,.custos .row .d,.cond,.arq .box .bd,\n.kpis .k p,.klist li,.steps li{font-family:var(--sf)}\n\n:focus-visible{outline:2px solid var(--accent);outline-offset:4px}\n@media (prefers-reduced-motion:reduce){\n  .deckroot{scroll-behavior:auto}\n  .rv{opacity:1;transform:none;transition:none}\n}\n\n/* ---------- fundo gráfico ---------- */\n.bg{position:absolute;inset:0;z-index:0;overflow:hidden;background:\n  radial-gradient(ellipse 70% 60% at 18% 85%,rgba(35,71,127,.66),transparent 62%),\n  radial-gradient(ellipse 50% 45% at 88% 12%,rgba(200,154,74,.24),transparent 60%),\n  linear-gradient(135deg,var(--dark) 0%,var(--dark-2) 55%,#0E1729 100%)}\n.bg .grid{position:absolute;inset:0;\n  background-image:linear-gradient(rgba(255,255,255,.055) 1px,transparent 1px),\n                   linear-gradient(90deg,rgba(255,255,255,.055) 1px,transparent 1px);\n  background-size:64px 64px;\n  mask-image:radial-gradient(ellipse 85% 80% at 50% 50%,#000 30%,transparent 100%);\n  -webkit-mask-image:radial-gradient(ellipse 85% 80% at 50% 50%,#000 30%,transparent 100%)}\n.bg .mark{position:absolute;left:50%;transform:translateX(-50%);bottom:-7%;width:76%;height:auto;color:#fff;opacity:.05}\n@media(max-width:820px){.bg .mark{width:150%;bottom:4%}}\n\n/* ---------- capa ---------- */\n.capa{padding:clamp(72px,10vh,104px) var(--mx) clamp(62px,9vh,88px);background:var(--paper)}\n.capa .frame{position:relative;border-radius:clamp(18px,2.4vw,30px);overflow:hidden;flex:1;\n  min-height:min(58vh,640px);display:flex;align-items:center;justify-content:center;color:#fff}\n.capa .frame .mid{position:relative;z-index:1;display:flex;flex-direction:column;\n  align-items:center;text-align:center;gap:30px}\n.capa .frame .sub{font-family:var(--lt);font-size:clamp(12px,1.3vw,16px);letter-spacing:.16em;\n  text-transform:uppercase;opacity:.92}\n.capa .caption{display:flex;justify-content:space-between;align-items:baseline;gap:24px;\n  padding:clamp(16px,2.6vh,26px) 0 0;flex-wrap:wrap}\n.capa .caption .frase-cap{font-family:var(--lt);font-size:clamp(14px,1.55vw,19px);\n  color:var(--ink);letter-spacing:.01em}\n.capa .caption .meta{font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted)}\n\n.lockup{display:flex;align-items:center;gap:clamp(18px,3vw,34px)}\n.lockup img{display:block}\n.lockup .d2m{height:clamp(30px,4.6vw,54px)}\n.lockup svg.cbm{height:clamp(26px,3.6vw,42px);width:auto;display:block;color:#fff}\n.lockup svg.cbm-s{height:21px;width:auto;display:block;color:#fff}\n.lockup .plus{font-family:var(--lt);font-size:clamp(22px,3vw,36px);line-height:1;opacity:.9}\n\n/* ---------- índice ---------- */\n.indice{display:grid;grid-template-columns:1fr 1fr;gap:0 clamp(28px,5vw,90px);\n  border-top:1px solid var(--linha)}\n.indice a{display:flex;align-items:baseline;gap:18px;padding:clamp(13px,2.2vh,22px) 0;\n  border-bottom:1px solid var(--linha);text-decoration:none;color:var(--ink)}\n.indice a .n{font-family:var(--lt);font-size:11px;letter-spacing:.18em;color:var(--muted);\n  min-width:28px;transition:color .25s}\n.indice a .t{font-family:var(--ext);font-size:clamp(16px,1.9vw,26px);line-height:1.25;\n  transition:transform .3s cubic-bezier(.2,.6,.2,1)}\n.indice a:hover .n,.indice a:focus-visible .n{color:var(--accent)}\n.indice a:hover .t,.indice a:focus-visible .t{transform:translateX(6px)}\n@media(max-width:820px){.indice{grid-template-columns:1fr}}\n\n/* ---------- statement ---------- */\n.statement h1{font-size:clamp(34px,5.6vw,86px);line-height:1.08;letter-spacing:-.01em;max-width:16ch}\n\n/* ---------- pilares ---------- */\n.pilares{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(22px,3.4vw,56px);\n  border-top:1px solid var(--linha);padding-top:clamp(26px,5vh,52px)}\n.pilares.dois{grid-template-columns:1fr 1fr}\n.pilar .k{display:block;font-size:11px;letter-spacing:.26em;color:var(--accent);\n  text-transform:uppercase;margin-bottom:18px}\n.pilar .t{font-family:var(--ext);font-size:clamp(17px,1.7vw,23px);line-height:1.3;margin-bottom:16px}\n.pilar p{font-size:14.5px;line-height:1.7;color:var(--muted)}\n@media(max-width:820px){.pilares,.pilares.dois{grid-template-columns:1fr}}\n\n/* ---------- chip de link ---------- */\n.chip{display:inline-flex;align-items:center;gap:10px;margin-top:clamp(22px,3.6vh,34px);\n  padding:11px 20px;border:1px solid var(--linha);border-radius:999px;font-family:var(--lt);\n  font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--accent);\n  text-decoration:none;transition:border-color .25s}\n.chip:hover{border-color:var(--accent)}\n.chip.pend{color:var(--muted);border-style:dashed}\n\n/* ---------- hoje × depois ---------- */\n.comps{display:flex;flex-direction:column;gap:clamp(18px,3vh,32px)}\n.comp{display:grid;grid-template-columns:1fr 1fr;gap:clamp(18px,3vw,48px);\n  border-top:1px solid var(--linha);padding-top:clamp(14px,2.2vh,22px)}\n.comp .ctit{grid-column:1/-1;font-family:var(--ext);font-size:clamp(15px,1.6vw,20px)}\n.comp .lk{font-family:var(--lt);font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;\n  margin-bottom:12px}\n.comp .hj .lk{color:var(--bad)}\n.comp .cn .lk{color:var(--ok)}\n.steps{list-style:none;counter-reset:s;display:flex;flex-direction:column;gap:9px}\n.steps li{font-size:12.5px;line-height:1.55;color:var(--muted);display:flex;gap:10px;align-items:baseline}\n.steps li::before{counter-increment:s;content:counter(s);font-family:var(--lt);font-size:10px;\n  color:var(--bad);border:1px solid currentColor;border-radius:50%;width:17px;height:17px;\n  display:flex;align-items:center;justify-content:center;flex:none;position:relative;top:2px}\n.comp .cn .steps li::before{color:var(--ok)}\n@media(max-width:820px){.comp{grid-template-columns:1fr}}\n\n/* ---------- arquitetura ---------- */\n.arq{display:grid;grid-template-columns:1fr 44px 1.15fr 44px 1fr;gap:clamp(10px,1.2vw,18px);\n  align-items:stretch;border-top:1px solid var(--linha);padding-top:clamp(24px,4vh,44px)}\n.arq .col{display:flex;flex-direction:column;gap:10px}\n.arq .col-h{font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted);\n  margin-bottom:8px;line-height:1.5}\n.arq .box{border:1px solid var(--linha);border-radius:14px;padding:13px 15px}\n.arq .box .bn{font-family:var(--ext);font-size:12.5px;line-height:1.4}\n.arq .box .bd{font-size:11.5px;color:var(--muted);margin-top:4px;line-height:1.5}\n.arq .core{background:var(--dark);color:#fff;border-radius:18px;padding:clamp(16px,2.4vh,26px);\n  display:flex;flex-direction:column;gap:12px;height:100%}\n.arq .core .ch{font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--accent-soft)}\n.arq .core .box{border-color:rgba(255,255,255,.25)}\n.arq .core .box .bd{color:rgba(255,255,255,.72)}\n.arq .link{position:relative;display:flex;align-items:center;justify-content:center}\n.arq .link::before{content:'';position:absolute;left:-6px;right:-6px;top:50%;height:1px;\n  background:var(--muted);opacity:.5}\n.arq .link span{position:relative;background:var(--paper);font-size:9px;letter-spacing:.2em;\n  text-transform:uppercase;color:var(--muted);transform:rotate(-90deg);white-space:nowrap;padding:0 6px}\n@media(max-width:900px){\n  .arq{grid-template-columns:1fr}\n  .arq .link{min-height:34px}\n  .arq .link::before{left:50%;right:auto;top:0;bottom:0;width:1px;height:auto}\n  .arq .link span{transform:none}\n}\n\n/* ---------- frentes de escopo ---------- */\n.leg{display:flex;gap:26px;flex-wrap:wrap;margin-bottom:clamp(18px,3vh,30px);\n  font-family:var(--sf);font-size:12.5px;color:var(--muted)}\n.leg span{display:flex;align-items:center;gap:8px}\n.leg i{width:9px;height:9px;border-radius:50%;display:inline-block}\n.leg .ok{background:var(--ok)}\n.leg .nv{background:var(--accent)}\n.frentes{display:grid;grid-template-columns:1fr 1fr;border-top:1px solid var(--linha);\n  column-gap:clamp(24px,4vw,64px)}\n.frentes .f{border-bottom:1px solid var(--linha);padding:clamp(12px,1.8vh,18px) 0}\n.frentes .fn{font-family:var(--ext);font-size:clamp(13px,1.2vw,15.5px);margin-bottom:8px;\n  display:flex;justify-content:space-between;gap:12px;align-items:baseline}\n.frentes .fn .ct{font-family:var(--sf);font-size:10.5px;color:var(--muted);white-space:nowrap;\n  letter-spacing:.04em}\n.frentes .fi{display:flex;gap:8px;align-items:baseline;font-family:var(--sf);font-size:12px;\n  line-height:1.5;color:var(--ink);padding:2.5px 0}\n.frentes .fi::before{content:'';width:6px;height:6px;border-radius:50%;flex:none;\n  position:relative;top:-1px}\n.frentes .fi.ok::before{background:var(--ok)}\n.frentes .fi.nv::before{background:var(--accent)}\n@media(max-width:900px){.frentes{grid-template-columns:1fr}}\n\n/* ---------- kpis ---------- */\n.kpis{display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid var(--linha)}\n.kpis.seis{grid-template-columns:repeat(3,1fr)}\n.kpis .k{padding:clamp(16px,2.6vh,26px) 22px clamp(16px,2.6vh,26px) 0;border-bottom:1px solid var(--linha)}\n.kpis .k .kt{font-family:var(--ext);font-size:clamp(13.5px,1.25vw,16px);line-height:1.35}\n.kpis .k p{font-size:12.5px;color:var(--muted);line-height:1.6;margin-top:8px}\n.kpis .k .kb{font-family:var(--sf);font-size:11.5px;color:var(--accent);margin-top:8px;line-height:1.5}\n@media(max-width:900px){.kpis,.kpis.seis{grid-template-columns:1fr 1fr}}\n@media(max-width:600px){.kpis,.kpis.seis{grid-template-columns:1fr}}\n\n/* ---------- cronograma ---------- */\n.ondas{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(22px,3vw,48px);\n  position:relative;padding-top:clamp(30px,5vh,52px)}\n.ondas::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:var(--linha)}\n.onda{position:relative}\n.onda::before{content:'';position:absolute;top:calc(-1 * clamp(30px,5vh,52px));left:0;\n  width:9px;height:9px;border-radius:50%;background:var(--accent);transform:translateY(-4px)}\n.onda .fase{font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:var(--muted);\n  margin-bottom:10px}\n.onda .t{font-family:var(--ext);font-size:clamp(17px,1.8vw,24px);margin-bottom:18px}\n.onda ul{list-style:none}\n.onda li{font-size:14px;line-height:1.6;color:var(--muted);padding:9px 0;border-bottom:1px solid var(--linha)}\n@media(max-width:820px){.ondas{grid-template-columns:1fr}.onda::before{display:none}}\n\n/* ---------- investimento ---------- */\n.custos{border-top:1px solid var(--linha);max-width:880px}\n.custos .row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:24px;\n  padding:clamp(10px,1.8vh,18px) 0;border-bottom:1px solid var(--linha)}\n.custos .row .t{font-family:var(--ext);font-size:clamp(15px,1.5vw,20px)}\n.custos .row .d{font-size:13px;color:var(--muted);margin-top:5px;max-width:56ch;line-height:1.6}\n.custos .row .v{font-family:var(--ext);font-size:clamp(19px,2.1vw,30px);\n  font-variant-numeric:tabular-nums;white-space:nowrap}\n.custos .row .v em{font-style:normal;color:var(--muted);font-family:var(--lt);font-size:.55em;\n  letter-spacing:.1em}\n.custos .total .v{color:var(--accent)}\n.cond{margin-top:clamp(14px,2.2vh,22px);font-size:13px;line-height:1.7;color:var(--muted);max-width:64ch}\n\n/* ---------- listas de compromisso ---------- */\n.klist{list-style:none;margin-top:6px}\n.klist li{font-size:13.5px;line-height:1.6;color:var(--ink);padding:10px 0;\n  border-bottom:1px solid var(--linha)}\n.klist li b{font-weight:600}\n\n/* ---------- fechamento ---------- */\n.dark{color:#fff}\n.dark .mid{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;\n  text-align:center;gap:34px}\n.dark .sub{font-family:var(--lt);font-size:clamp(13px,1.4vw,17px);letter-spacing:.14em;\n  text-transform:uppercase;opacity:.92}\n.fecho .mid{gap:44px}\n.fecho .frase{font-family:var(--lt);font-size:clamp(16px,1.8vw,25px);line-height:1.65;\n  letter-spacing:.025em;max-width:44ch;text-wrap:balance}\n.fecho .frase i{font-style:normal;opacity:.65}\n.ring{width:clamp(54px,5.4vw,80px);height:auto;display:block}\n.ring.branco{filter:brightness(0) invert(1)}\n@media(max-width:820px){.fecho .frase{font-size:15px}}\n\n/* ---------- mobile ---------- */\n@media(max-width:820px){\n  .deckroot{scroll-snap-type:y proximity}\n  /* véu de papel sob o contador, como o do header: em slide mais alto que a tela\n     o texto passaria por baixo do chrome */\n  .deckwrap::after{content:'';position:absolute;left:0;right:0;bottom:0;height:56px;z-index:35;\n    pointer-events:none;background:linear-gradient(to top,var(--paper) 42%,rgba(245,244,240,0));\n    height:78px}\n  .deckwrap.on-dark::after{display:none}\n  nav.dots{display:none}\n  section{padding:72px 20px 82px}\n  .counter,.hint{bottom:34px}\n  .eyebrow{margin-bottom:18px}\n  .capa{padding:60px var(--mx) 96px}\n  .capa .frame{min-height:42svh}\n  .capa .frame .mid{gap:18px;padding:0 20px}\n  .capa .frame .sub{font-size:10.5px;letter-spacing:.12em;text-wrap:balance;line-height:1.7}\n  .capa .lockup{gap:14px}\n  .capa .lockup .d2m{height:25px}\n  .capa .lockup svg.cbm{height:20px}\n  .capa .lockup .plus{font-size:17px}\n  .capa .caption{flex-direction:column;align-items:flex-start;gap:10px;padding:18px 2px 0}\n  .capa .caption .frase-cap{font-size:15px;line-height:1.5;max-width:34ch}\n}\n\n/* ---------- gate ---------- */\n.gwrap{position:relative;height:100vh;height:100svh;overflow:hidden;display:flex;\n  align-items:center;justify-content:center;background:var(--dark);font-family:var(--lt)}\n.gcard{position:relative;z-index:1;background:var(--paper);border-radius:20px;\n  padding:40px 36px 32px;width:min(380px,88vw);text-align:center;\n  box-shadow:0 30px 80px rgba(0,0,0,.45)}\n.glock{display:flex;align-items:center;justify-content:center;gap:12px;margin-bottom:14px}\n.glock img{filter:brightness(0);display:block}\n.glock svg.gcb{height:17px;width:auto;display:block;color:var(--ink)}\n.glock span{font-family:var(--lt);font-size:15px;color:var(--ink)}\n.gsub{font-family:var(--lt);font-size:10px;letter-spacing:.24em;text-transform:uppercase;\n  color:var(--muted);margin-bottom:26px}\n.ginput{width:100%;box-sizing:border-box;padding:13px 14px;border:1px solid var(--linha);\n  border-radius:10px;background:#fff;font-size:15px;text-align:center;outline:none;\n  font-family:var(--sf);color:var(--ink)}\n.ginput:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(150,87,15,.16)}\n.gbtn{width:100%;margin-top:12px;padding:13px;border:none;border-radius:10px;\n  background:var(--accent);color:#fff;font-size:12px;letter-spacing:.24em;\n  text-transform:uppercase;cursor:pointer;font-family:var(--lt)}\n.gbtn:hover{filter:brightness(.9)}\n.gerr{display:none;color:var(--bad);font-size:13px;margin-top:12px;font-family:var(--sf)}\n.shake{animation:gsh .4s}\n@keyframes gsh{0%,100%{transform:translateX(0)}20%{transform:translateX(-9px)}\n  40%{transform:translateX(9px)}60%{transform:translateX(-5px)}80%{transform:translateX(5px)}}\n  `,\n  render(){ return `<div class=\"deckhost\"></div>` },\n  mounted(d2,root){\n    injectFonts()\n    let ok=OPEN\n    try{ if(sessionStorage.getItem('deckJohnJohnUnlocked')==='1') ok=true }catch(e){}\n    try{ if((location.search||'').indexOf('k='+PASS)>-1) ok=true }catch(e){}\n    if(ok) phase='deck'\n    sync(d2,root)\n  },\n  updated(d2,root){ sync(d2,root) }\n}"}}}}}}}},{"_id":"6a9acde99e4fa8f6878f53b4","component":"data2-core-types@Component","system":"698a0c028a310c894be98bc8","params":{"extends":"data2-core-primitives@Block","component":"veste-deck-proposta","package":"veste-app","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"/* ───────────────────────────────────────────────────────────────────────────\n   Deck — Proposta comercial · Veste S/A (grupo)\n   Provador virtual com IA para Le Lis, John John, Bo.Bô, Individual e Dudalina\n   Kit: apresentacao-data2 (Akzidenz Ext + logo oficial Data²) · 18 slides\n   Recriado a partir de proposta-veste.people-gabi-carmo, com o discurso\n   corrigido: a prova NÃO promete tamanho/caimento; o número da POC é\n   conversão de visitantes; troca/devolução é a leitura pós-janela.\n   ─────────────────────────────────────────────────────────────────────────── */\n\nconst SYS   = 'veste-app'\nconst F_EXT = `https://${SYS}.data2.media/file/iNSYotTKA1cv_fJAa1K4E`\nconst F_LT  = `https://${SYS}.data2.media/file/6bERTVll1aRDU3Xo9NghW`\nconst LD2   = `https://${SYS}.data2.media/file/WLXAyS4HOHvTFytXu7S4P`\nconst RING  = `https://${SYS}.data2.media/file/TA2eFNVhnB7dlI9EPAEWb`\nconst VESTE = `https://${SYS}.data2.media/file/F5sYItInqXvAlz2_oR4AO`\nconst RUSH  = `https://${SYS}.data2apis.com/rush`\n\nconst POC_URL = 'https://veste.people-gabi-carmo.next.data2.app/'\nconst PASS    = 'veste2026'\nconst OPEN    = false\n\nconst FONT_CSS = `@font-face{font-family:'AkzExt';src:url(${F_EXT}) format('opentype');font-weight:400;font-display:block}@font-face{font-family:'AkzExtLight';src:url(${F_LT}) format('opentype');font-weight:300;font-display:block}`\n\nconst VS = (cls) => `<img class=\"${cls || ''}\" src=\"${VESTE}\" alt=\"Veste\">`\nconst FUNDO = `<div class=\"bg\"><div class=\"grid\"></div><img class=\"mark\" src=\"${VESTE}\" alt=\"\"></div>`\n\nconst esc = (s) => String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\nconst fmtDT = (iso) => { try { return new Date(iso).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' }) } catch (e) { return '—' } }\nconst shortDev = (ua) => {\n  ua = String(ua || '')\n  const os = /iphone|ipad/i.test(ua) ? 'iOS' : /android/i.test(ua) ? 'Android' : /windows/i.test(ua) ? 'Windows' : /macintosh|mac os x/i.test(ua) ? 'Mac' : /linux/i.test(ua) ? 'Linux' : '—'\n  const br = /edg/i.test(ua) ? 'Edge' : /opr|opera/i.test(ua) ? 'Opera' : /chrome/i.test(ua) ? 'Chrome' : /firefox/i.test(ua) ? 'Firefox' : /safari/i.test(ua) ? 'Safari' : ''\n  return os + (br ? ' · ' + br : '')\n}\n\nconst GATE = `<div class=\"gwrap\">${FUNDO}\n  <div class=\"gcard\">\n    <div class=\"glock\"><img src=\"${LD2}\" style=\"height:20px\" alt=\"Data²\"><span>+</span>${VS('gvs')}</div>\n    <div class=\"gsub\">Proposta · Veste S/A</div>\n    <input class=\"ginput\" type=\"password\" placeholder=\"Senha de acesso\" autocomplete=\"off\"/>\n    <button class=\"gbtn\">Entrar</button>\n    <div class=\"gerr\">Senha incorreta — tente novamente.</div>\n  </div></div>`\n\nconst DECK = `<div class=\"deckwrap\">\n<header><img class=\"d2\" src=\"${LD2}\" alt=\"Data²\">${VS('hvs')}</header>\n<div class=\"counter\" id=\"counter\">01 — 17</div>\n<div class=\"hint\">↓ navegue</div>\n<nav class=\"dots\" id=\"dots\" aria-label=\"Slides\"></nav>\n<div class=\"deckroot\">\n\n  <!-- 01 · CAPA -->\n  <section class=\"capa\" id=\"capa\">\n    <div class=\"frame rv\">${FUNDO}\n      <div class=\"mid\">\n        <div class=\"lockup\">\n          <img class=\"d2m\" src=\"${LD2}\" alt=\"Data²\"><span class=\"plus\">+</span>${VS('vsm')}\n        </div>\n        <div class=\"sub\">Provador virtual com IA · Proposta comercial</div>\n        <div class=\"brands\">Le Lis · John John · Bo.Bô · Individual · Dudalina</div>\n      </div>\n    </div>\n    <div class=\"caption rv\">\n      <div class=\"frase-cap\">We build Data² while imagining a world where things just … work.</div>\n      <div class=\"meta\">Proposta · Setembro 2026</div>\n    </div>\n  </section>\n\n  <!-- 02 · ÍNDICE -->\n  <section id=\"indice\">\n    <div class=\"eyebrow rv\">Índice</div>\n    <div class=\"indice rv\">\n      <a href=\"#proposta\"><span class=\"n\">01</span><span class=\"t\">A proposta</span></a>\n      <a href=\"#perda\"><span class=\"n\">02</span><span class=\"t\">O que a marca perde hoje</span></a>\n      <a href=\"#provador\"><span class=\"n\">03</span><span class=\"t\">O provador</span></a>\n      <a href=\"#limites\"><span class=\"n\">04</span><span class=\"t\">O que a prova responde</span></a>\n      <a href=\"#arq\"><span class=\"n\">05</span><span class=\"t\">Arquitetura e integração</span></a>\n      <a href=\"#escopo\"><span class=\"n\">06</span><span class=\"t\">Escopo da entrega</span></a>\n      <a href=\"#poc\"><span class=\"n\">07</span><span class=\"t\">A POC no período</span></a>\n      <a href=\"#medir\"><span class=\"n\">08</span><span class=\"t\">O que vamos medir</span></a>\n      <a href=\"#comercial\"><span class=\"n\">09</span><span class=\"t\">Condições comerciais</span></a>\n      <a href=\"#dep1\"><span class=\"n\">10</span><span class=\"t\">Depois do período · imagem</span></a>\n      <a href=\"#dep2\"><span class=\"n\">11</span><span class=\"t\">Depois do período · plataforma</span></a>\n      <a href=\"#dep3\"><span class=\"n\">12</span><span class=\"t\">Custo de operação por tier</span></a>\n      <a href=\"#respons\"><span class=\"n\">13</span><span class=\"t\">Responsabilidades</span></a>\n      <a href=\"#fora\"><span class=\"n\">14</span><span class=\"t\">Fora do escopo</span></a>\n    </div>\n  </section>\n\n  <!-- 03 · A PROPOSTA -->\n  <section class=\"statement\" id=\"proposta\">\n    <div class=\"eyebrow rv\">A proposta · <b>Veste S/A</b></div>\n    <div class=\"split\">\n      <h1 class=\"rv\">Um provador virtual para as cinco marcas do grupo.</h1>\n      <p class=\"apoio destaque rv\">Le Lis, John John, Bo.Bô, Individual e Dudalina em uma engine\n        só. Sem custo de sprint e com 30 dias de geração de imagem liberada. Esta proposta define\n        o que a Data² entrega, qual número a POC precisa mover e o que passa a valer depois.</p>\n    </div>\n  </section>\n\n  <!-- 04 · O QUE A MARCA PERDE HOJE -->\n  <section id=\"perda\">\n    <div class=\"eyebrow rv\">O problema</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(30px,6vh,60px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(28px,4vw,56px);line-height:1.12;max-width:16ch\">\n        A peça só é experimentada depois de comprada.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">Quem compra online decide pela foto da modelo. A\n        primeira vez que vê a peça em si mesmo é quando o pedido chega em casa. Três coisas\n        nascem daí.</p>\n    </div>\n    <div class=\"pilares\">\n      <div class=\"pilar rv d2\"><span class=\"k\">01 · Troca e devolução</span>\n        <div class=\"t\">O que volta para o CD</div>\n        <p>Logística reversa, peça que retorna ao estoque fora de estação e crédito que o\n           cliente gasta onde quiser. A devolução cobra duas vezes: o frete e a margem da peça\n           parada.</p></div>\n      <div class=\"pilar rv d3\"><span class=\"k\">02 · A peça que não é usada</span>\n        <div class=\"t\">Comprou e não veste</div>\n        <p>Nem toda compra frustrada volta. Parte fica no armário com a etiqueta inteira, e a\n           marca fica registrada como a que não deu certo. Não aparece no índice de devolução —\n           aparece na recompra que não acontece.</p></div>\n      <div class=\"pilar rv d4\"><span class=\"k\">03 · O visitante que sai sem comprar</span>\n        <div class=\"t\">A maior parte do tráfego</div>\n        <p>A maioria de quem entra no site sai sem levar nada. Uma parte dessa saída é a dúvida\n           sobre como a peça fica nele — e a foto da modelo não responde isso.</p></div>\n    </div>\n  </section>\n\n  <!-- 05 · O PROVADOR -->\n  <section id=\"provador\">\n    <div class=\"eyebrow rv\">O provador</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(30px,6vh,60px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(28px,4vw,56px);line-height:1.12;max-width:16ch\">\n        A peça na foto do próprio cliente, em segundos.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">Ele manda uma foto, escolhe a peça no catálogo da\n        marca e vê o resultado. Cada prova fica salva no nome dele, com o preço e o caminho de\n        volta para a página do produto.</p>\n    </div>\n    <div class=\"pilares\">\n      <div class=\"pilar rv d2\"><span class=\"k\">01 · Provador</span>\n        <div class=\"t\">A peça no lugar da que ele está usando</div>\n        <p>A roupa atual é removida antes da troca, e o enquadramento da foto original é\n           preservado — sem cortar cabeça nem pés.</p></div>\n      <div class=\"pilar rv d3\"><span class=\"k\">02 · Meu Look</span>\n        <div class=\"t\">Várias peças, uma foto</div>\n        <p>Camisa, calça e alfaiataria provadas em sequência, sobre o resultado anterior. É como\n           o cliente compra de verdade: por look, não por item.</p></div>\n      <div class=\"pilar rv d4\"><span class=\"k\">03 · Minhas Provas</span>\n        <div class=\"t\">A prova vira vitrine</div>\n        <p>Cada prova fica salva com preço e link para a página do produto. O cliente volta para\n           a galeria dele e compra de lá, dias depois.</p></div>\n    </div>\n    <div class=\"rv d5\"><a class=\"chip\" href=\"${POC_URL}\" target=\"_blank\" rel=\"noopener\">Ver o provador funcionando</a></div>\n  </section>\n\n  <!-- 06 · LIMITES DA PROVA -->\n  <section id=\"limites\">\n    <div class=\"eyebrow rv\">Limites da prova</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(26px,5vh,50px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:17ch\">\n        O provador mostra a peça em você. Ele não mede o seu corpo.</h2>\n      <p class=\"apoio destaque rv\" style=\"margin-top:0\">A prova responde se a peça combina com\n        quem está na foto. Ela não diz qual é o seu tamanho, e esta proposta não vende isso. A\n        distinção é o que faz o resultado do período ser discutível com número na mesa.</p>\n    </div>\n    <div class=\"pilares dois\">\n      <div class=\"pilar rv d2\"><span class=\"k\">A prova responde</span>\n        <ul class=\"klist\">\n          <li><b>Como fica em mim</b> — a peça no corpo do cliente, e não no da modelo</li>\n          <li><b>Cor, comprimento e proporção</b> — o que a foto de catálogo achata</li>\n          <li><b>A peça dentro de um look</b> — a camisa junto da calça que ele já escolheu</li>\n          <li><b>Se ele quer levar</b> — a decisão sai da imaginação e vai para a tela</li>\n        </ul></div>\n      <div class=\"pilar rv d3\"><span class=\"k\">A prova não responde</span>\n        <ul class=\"klist neg\">\n          <li><b>Qual é o tamanho</b> — P, M ou G continua sendo tabela de medidas</li>\n          <li><b>Se vai apertar ou sobrar</b> — cintura, manga, comprimento de perna</li>\n          <li><b>Como o tecido cai em movimento</b> — peso e caimento real da peça</li>\n          <li><b>Nada disso entra na leitura</b> — o número do período é conversão, não caimento</li>\n        </ul></div>\n    </div>\n  </section>\n\n  <!-- 07 · ARQUITETURA -->\n  <section id=\"arq\">\n    <div class=\"eyebrow rv\">Arquitetura e integração</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,42px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">\n        Integramos por leitura. Nada do que funciona muda.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">O provador consulta a API de catálogo de cada\n        marca no momento da prova. Não há réplica de base, carga noturna nem alteração no tema\n        das lojas.</p>\n    </div>\n    <div class=\"arq rv\">\n      <div class=\"col\">\n        <div class=\"col-h\">Sistemas da Veste · intocados</div>\n        <div class=\"box\"><div class=\"bn\">VTEX</div>\n          <div class=\"bd\">Catálogo, PDP, carrinho e checkout seguem como estão</div></div>\n        <div class=\"box\"><div class=\"bn\">Sites das cinco marcas</div>\n          <div class=\"bd\">O provador entra como um bloco no tema, sem reescrever a loja</div></div>\n      </div>\n      <div class=\"link\"><span>leitura · API</span></div>\n      <div class=\"core\">\n        <div class=\"ch\">Data² · engine de provador</div>\n        <div class=\"box\"><div class=\"bn\">Leitura de catálogo</div>\n          <div class=\"bd\">Consulta as categorias reais de cada marca na hora da prova</div></div>\n        <div class=\"box\"><div class=\"bn\">Provador de IA</div>\n          <div class=\"bd\">Checa a foto, decide o que remover e aplica a peça mantendo o\n            enquadramento</div></div>\n        <div class=\"box\"><div class=\"bn\">Painel de resultados</div>\n          <div class=\"bd\">Registra cada prova, cada clique em Comprar e os produtos mais\n            provados</div></div>\n      </div>\n      <div class=\"link\"><span>embed</span></div>\n      <div class=\"col\">\n        <div class=\"col-h\">Cliente final</div>\n        <div class=\"box\"><div class=\"bn\">Navegador</div>\n          <div class=\"bd\">Dentro do site, na mesma sessão de compra</div></div>\n        <div class=\"box\"><div class=\"bn\">Minhas Provas</div>\n          <div class=\"bd\">Galeria por e-mail, com preço e Comprar apontando para a PDP</div></div>\n      </div>\n    </div>\n  </section>\n\n  <!-- 08 · ESCOPO DA ENTREGA -->\n  <section id=\"escopo\">\n    <div class=\"eyebrow rv\">Escopo da entrega</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(20px,3.4vh,34px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.4vw,48px);line-height:1.12;max-width:16ch\">\n        Uma engine, cinco camadas de marca.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">A engine de provador está publicada e testada com\n        catálogo real. A sprint acrescenta a camada de cada marca — catálogo, prompt calibrado e\n        o bloco de embed.</p>\n    </div>\n    <div class=\"leg rv\">\n      <span><i class=\"ok\"></i>Validado — já roda na engine</span>\n      <span><i class=\"nv\"></i>Novo — específico das marcas da Veste</span>\n    </div>\n    <div class=\"frentes rv\">\n      <div class=\"f\">\n        <div class=\"fn\">Provador <span class=\"ct\">3 validados · 1 novo</span></div>\n        <div class=\"fi ok\">Checagem da foto antes de gerar</div>\n        <div class=\"fi ok\">Remove a peça atual em vez de sobrepor</div>\n        <div class=\"fi ok\">Preserva o enquadramento — não corta cabeça nem pés</div>\n        <div class=\"fi nv\">Prompt calibrado por marca, do jeans à alfaiataria</div>\n      </div>\n      <div class=\"f\">\n        <div class=\"fn\">Catálogo <span class=\"ct\">1 validado · 2 novos</span></div>\n        <div class=\"fi ok\">Leitura ao vivo, sem réplica de base</div>\n        <div class=\"fi nv\">Categorias das cinco marcas, masculino e feminino</div>\n        <div class=\"fi nv\">Filtro que deixa fora calçados, acessórios e cartões</div>\n      </div>\n      <div class=\"f\">\n        <div class=\"fn\">Meu Look e Minhas Provas <span class=\"ct\">3 validados</span></div>\n        <div class=\"fi ok\">Provar várias peças em sequência na mesma foto</div>\n        <div class=\"fi ok\">Galeria por e-mail, com preço e Comprar</div>\n        <div class=\"fi ok\">Cliente remove a prova que não quiser guardar</div>\n      </div>\n      <div class=\"f\">\n        <div class=\"fn\">Painel de resultados <span class=\"ct\">2 validados · 2 novos</span></div>\n        <div class=\"fi ok\">Provas geradas, conclusão e tempo de geração</div>\n        <div class=\"fi ok\">Cliques em Comprar e produtos mais provados</div>\n        <div class=\"fi nv\">Comparação contra a linha de base de cada site</div>\n        <div class=\"fi nv\">Visão consolidada do grupo, marca por marca</div>\n      </div>\n    </div>\n  </section>\n\n  <!-- 09 · A POC NO PERÍODO -->\n  <section id=\"poc\">\n    <div class=\"eyebrow rv\">O período de prova</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(20px,3.4vh,34px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">\n        Trinta dias no ar, com três marcos de leitura.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">A janela começa no dia em que o provador entra no\n        primeiro site. As datas de calendário são fixadas na confirmação desta proposta.</p>\n    </div>\n    <div class=\"ondas rv\">\n      <div class=\"onda\"><div class=\"fase\">Dia 1</div><div class=\"t\">No ar</div>\n        <ul>\n          <li>Provador publicado no site da primeira marca</li>\n          <li>Geração de imagem liberada, até 2.000 provas</li>\n          <li>Linha de base de conversão registrada com o time da Veste</li>\n          <li>Painel medindo desde a primeira prova</li>\n        </ul></div>\n      <div class=\"onda\"><div class=\"fase\">Dia 15</div><div class=\"t\">Primeira leitura</div>\n        <ul>\n          <li>Volume de provas e taxa de conclusão</li>\n          <li>Ajuste de prompt e de catálogo, se preciso</li>\n          <li>Extensão para as marcas seguintes</li>\n        </ul></div>\n      <div class=\"onda\"><div class=\"fase\">Dia 30</div><div class=\"t\">Análise e acordo</div>\n        <ul>\n          <li>Conversão de quem provou contra a média do site</li>\n          <li>Cliques em Comprar depois da prova</li>\n          <li>Resultados analisados e continuidade em acordo pago</li>\n        </ul></div>\n    </div>\n  </section>\n\n  <!-- 10 · O QUE VAMOS MEDIR -->\n  <section id=\"medir\">\n    <div class=\"eyebrow rv\">O que vamos medir</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(22px,3.8vh,42px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:17ch\">\n        A conversão de visitantes é o número que a POC prova.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">Tempo de página e engajamento ficam de fora. O\n        período responde se quem prova compra mais. A troca é a segunda leitura, e ela só fecha\n        depois da janela de devolução da Veste.</p>\n    </div>\n    <div class=\"kpis rv\">\n      <div class=\"k\"><div class=\"kt\">Conversão de visitantes</div>\n        <p>Taxa de conversão das sessões que geraram prova, contra a média do site no mesmo\n           período. É o que fica provado dentro dos 30 dias.</p>\n        <div class=\"kb\">Linha de base: a conversão do site hoje, informada no dia 1</div></div>\n      <div class=\"k\"><div class=\"kt\">Clique em Comprar após a prova</div>\n        <p>Quantas provas terminam em clique para a página do produto. Mede intenção direta, não\n           curiosidade.</p>\n        <div class=\"kb\">Registrado pela engine desde a primeira prova</div></div>\n      <div class=\"k\"><div class=\"kt\">Troca e devolução</div>\n        <p>Cada pedido que veio de uma prova fica marcado. Quando a janela de devolução fecha, o\n           índice de troca desses pedidos é comparado com o do resto da base.</p>\n        <div class=\"kb\">Não fecha em 30 dias — a marcação sai pronta da POC</div></div>\n      <div class=\"k\"><div class=\"kt\">Como medimos</div>\n        <p>Cada prova, cadastro e clique é gravado com produto e horário. O painel fica aberto\n           durante o período, para os dois lados olharem o mesmo número.</p></div>\n    </div>\n  </section>\n\n  <!-- 11 · CONDIÇÕES COMERCIAIS -->\n  <section id=\"comercial\">\n    <div class=\"eyebrow rv\">Condições comerciais</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(16px,2.6vh,26px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.2vw,44px);line-height:1.12;max-width:24ch\">\n        Trinta dias liberados. Depois, um acordo pago.</h2>\n      <p class=\"apoio destaque rv\" style=\"margin-top:0\">A construção e o teste correm por conta\n        da Data², com a geração de imagem liberada por 30 dias, até 2.000 provas. No fim da\n        janela os resultados são analisados e a continuidade vira um acordo pago.</p>\n    </div>\n    <div class=\"custos rv\">\n      <div class=\"row\"><div>\n        <div class=\"t\">Construção da POC</div>\n        <div class=\"d\">Engine de provador com o catálogo das cinco marcas ao vivo, Meu Look,\n          Minhas Provas, painel de resultados e o bloco de embed para os sites.</div>\n      </div><div class=\"v\">R$ 0</div></div>\n      <div class=\"row\"><div>\n        <div class=\"t\">Teste no período</div>\n        <div class=\"d\">Acompanhamento durante a janela: ajuste de prompt, ajuste de catálogo e\n          leitura dos números com o time da Veste.</div>\n      </div><div class=\"v\">R$ 0</div></div>\n      <div class=\"row\"><div>\n        <div class=\"t\">Geração de imagem · 30 dias</div>\n        <div class=\"d\">Até 2.000 provas na janela. Catálogo, storage e acessos incluídos.</div>\n      </div><div class=\"v\">Liberada</div></div>\n      <div class=\"row total\"><div>\n        <div class=\"t\">Depois dos 30 dias</div>\n        <div class=\"d\">Continuidade dimensionada pelo volume que a POC mostrou.</div>\n      </div><div class=\"v\">Acordo pago</div></div>\n    </div>\n    <p class=\"cond rv\">Ao se aproximar das 2.000 provas, a Data² avisa antes de qualquer\n      cobrança. Evolução de escopo é orçada em separado.</p>\n  </section>\n\n  <!-- 12 · DEPOIS DO PERÍODO · IMAGEM -->\n  <section id=\"dep1\">\n    <div class=\"eyebrow rv\">Depois do período · 01</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(18px,3vh,30px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.4vw,48px);line-height:1.12;max-width:16ch\">\n        Cada prova gera uma imagem.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">Quando a janela fecha, a imagem passa a ser\n        cobrada. Quanto maior o volume mensal contratado, menor o preço por imagem. Valores em\n        US$.</p>\n    </div>\n    <div class=\"tbw rv\"><table class=\"tb\"><thead><tr>\n      <th>Faixa</th><th>Mínimo mensal</th><th>Desconto</th><th>Preço/imagem</th>\n      <th>Spend mínimo/mês</th><th>Preço cheio equivalente</th></tr></thead><tbody>\n      <tr><td>Sem compromisso</td><td>—</td><td>0%</td><td><strong>$0,090</strong></td><td>—</td><td>—</td></tr>\n      <tr><td>Tier 1</td><td>5.000 img</td><td>50%</td><td><strong>$0,045</strong></td><td>$225/mês</td><td>$450</td></tr>\n      <tr><td>Tier 2</td><td>15.000 img</td><td>60%</td><td><strong>$0,036</strong></td><td>$540/mês</td><td>$1.350</td></tr>\n      <tr><td>Tier 3</td><td>50.000 img</td><td>70%</td><td><strong>$0,027</strong></td><td>$1.350/mês</td><td>$4.500</td></tr>\n    </tbody></table></div>\n    <p class=\"cond rv\">O tier é escolhido pelo volume mensal que a Veste se compromete a\n      consumir. Abaixo do mínimo, vale o preço cheio da faixa sem compromisso.</p>\n  </section>\n\n  <!-- 13 · DEPOIS DO PERÍODO · PLATAFORMA -->\n  <section id=\"dep2\">\n    <div class=\"eyebrow rv\">Depois do período · 02</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(18px,3vh,30px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.4vw,48px);line-height:1.12;max-width:16ch\">\n        O que o provador consome da plataforma.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">Custos de uso da plataforma Data² para operar o\n        provador depois do período, conforme a tabela pública. Valores em US$.</p>\n    </div>\n    <div class=\"tbw rv\" style=\"max-width:640px\"><table class=\"tb\" style=\"min-width:380px\"><thead><tr>\n      <th>Item</th><th>Preço</th></tr></thead><tbody>\n      <tr><td>Tokens de IA · análise da foto</td><td><strong>US$ 0,0001</strong> / token</td></tr>\n      <tr><td>Escrita de dados</td><td><strong>US$ 0,0005</strong> / registro</td></tr>\n      <tr><td>Leitura de dados</td><td><strong>US$ 0,00001</strong> / registro</td></tr>\n      <tr><td>Rush · listener (backend)</td><td><strong>US$ 0,0001</strong> / invocação</td></tr>\n      <tr><td>Connect · request (catálogo)</td><td><strong>US$ 0,0001</strong> / request</td></tr>\n      <tr><td>Media · armazenamento das provas</td><td><strong>US$ 1,00</strong> / GB</td></tr>\n    </tbody></table></div>\n    <a class=\"chip\" href=\"https://data2.app/pricing\" target=\"_blank\" rel=\"noopener\">Ver a tabela completa em data2.app/pricing</a>\n  </section>\n\n  <!-- 14 · DEPOIS DO PERÍODO · OPERAÇÃO POR TIER -->\n  <section id=\"dep3\">\n    <div class=\"eyebrow rv\">Depois do período · 03</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(18px,3vh,30px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.4vw,48px);line-height:1.12;max-width:16ch\">\n        Custo de operação estimado, mês a mês.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">Imagem e plataforma somadas, por tier. A conta é\n        estimada — o que vale na fatura é o volume medido.</p>\n    </div>\n    <div class=\"tbw rv\"><table class=\"tb\"><thead><tr>\n      <th>Tier</th><th>Provas/mês</th><th>Imagem</th><th>Plataforma Data²</th><th>Total/mês</th></tr></thead><tbody>\n      <tr><td>Tier 1</td><td>5.000</td><td>$225</td><td>~$549</td><td><strong>~$774</strong></td></tr>\n      <tr><td>Tier 2</td><td>15.000</td><td>$540</td><td>~$1.648</td><td><strong>~$2.188</strong></td></tr>\n      <tr><td>Tier 3</td><td>50.000</td><td>$1.350</td><td>~$5.493</td><td><strong>~$6.843</strong></td></tr>\n    </tbody></table></div>\n    <p class=\"cond rv\">Plataforma estimada com base em cerca de 1.000 tokens de IA por prova, na\n      análise da foto — perto de 90% do custo de plataforma e a principal alavanca. Enviando a\n      foto de análise reduzida (~500 tokens por prova), essa parcela cai aproximadamente pela\n      metade. Valores em US$, conforme data2.app/pricing.</p>\n  </section>\n\n  <!-- 15 · RESPONSABILIDADES -->\n  <section id=\"respons\">\n    <div class=\"eyebrow rv\">Responsabilidades</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,44px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">\n        O que cada lado põe na mesa.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">A entrega não depende de projeto de TI. Depende de\n        quatro liberações pequenas — e cada uma tem dono.</p>\n    </div>\n    <div class=\"pilares dois\">\n      <div class=\"pilar rv d2\"><span class=\"k\">A Data² entrega</span>\n        <ul class=\"klist\">\n          <li><b>Engine no ar</b> — provador, Meu Look e Minhas Provas publicados e monitorados</li>\n          <li><b>Bloco de embed</b> — um trecho para o time de front colar, sem alterar o tema</li>\n          <li><b>Painel de resultados</b> — aberto à Veste durante o período</li>\n          <li><b>Acompanhamento</b> — ajuste de prompt e de catálogo dentro da janela</li>\n        </ul></div>\n      <div class=\"pilar rv d3\"><span class=\"k\">A Veste libera</span>\n        <ul class=\"klist\">\n          <li><b>Publicação do embed</b> — um contato de plataforma por marca que coloca o bloco no ar</li>\n          <li><b>Onde o provador entra</b> — página de produto, home ou landing de campanha</li>\n          <li><b>Linha de base de conversão</b> — o número de cada site hoje, para a comparação</li>\n          <li><b>Uso de imagem</b> — aprovação para o cliente gerar e guardar a própria prova</li>\n        </ul></div>\n    </div>\n  </section>\n\n  <!-- 16 · FORA DO ESCOPO -->\n  <section id=\"fora\">\n    <div class=\"eyebrow rv\">Limites</div>\n    <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,44px)\">\n      <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">\n        O que esta proposta não faz.</h2>\n      <p class=\"apoio rv\" style=\"margin-top:0\">Dizer o limite agora é o que faz o período\n        terminar sem discussão. Nada da coluna da direita está contratado aqui, e evolução de\n        escopo é orçada em separado.</p>\n    </div>\n    <div class=\"pilares dois\">\n      <div class=\"pilar rv d2\"><span class=\"k\">Fora do escopo</span>\n        <ul class=\"klist neg\">\n          <li><b>Recomendação de tamanho</b> — a prova não mede o corpo do cliente</li>\n          <li><b>Integração com ERP, OMS ou estoque</b> — o provador lê catálogo, e só</li>\n          <li><b>App nativo</b> — o provador roda no navegador</li>\n          <li><b>Fechar o ciclo de troca em 30 dias</b> — a janela de devolução é mais longa</li>\n        </ul></div>\n      <div class=\"pilar rv d3\"><span class=\"k\">Fica para depois do período</span>\n        <ul class=\"klist\">\n          <li>Provador na página de produto de toda a base</li>\n          <li>Leitura de troca com a janela de devolução fechada</li>\n          <li>Campanha com a prova que o próprio cliente gerou</li>\n          <li>Provador na loja física</li>\n        </ul></div>\n    </div>\n  </section>\n\n  <!-- 17 · FECHAMENTO -->\n  <section class=\"dark fecho\" data-dark id=\"fim\">${FUNDO}\n    <div class=\"mid\">\n      <img class=\"ring branco rv\" style=\"width:52px\" src=\"${RING}\" alt=\"\">\n      <p class=\"frase rv\">We build Data² while imagining a world where things just <i>…</i> work.</p>\n      <div class=\"lockup rv\">\n        <img class=\"d2m\" style=\"height:26px\" src=\"${LD2}\" alt=\"Data²\">\n        <span class=\"plus\" style=\"font-size:20px\">+</span>${VS('vsm-s')}\n      </div>\n      <div class=\"sub rv\">gabi.carmo@data2.app · +55 (11) 98962-6170 · data2.app</div>\n    </div>\n  </section>\n\n</div></div>`\n\nconst acessosHTML = (st) => {\n  const status = st.status || 'locked'\n  let inner\n  if (status === 'loading') {\n    inner = `<div class=\"acmsg\">Carregando…</div>`\n  } else if (status !== 'done') {\n    inner = `<div class=\"acgate\">\n      <input class=\"ginput acpass\" type=\"password\" placeholder=\"Senha do painel\" autocomplete=\"off\"/>\n      <button class=\"gbtn acbtn\">Entrar</button>\n      ${st.error ? '<div class=\"acerr\">' + esc(st.error) + '</div>' : ''}\n    </div>`\n  } else {\n    const ac = st.ac || {}\n    const recent = ac.recent || []\n    const seen = {}\n    recent.forEach(r => { if (r && r.clientId) seen[r.clientId] = 1 })\n    const rows = recent.slice(0, 60).map(r => `<tr><td>${fmtDT(r.createdAt)}</td><td>${r.event === 'login' ? 'Entrou com a senha' : 'Abriu'}</td><td>${esc(shortDev(r.device))}</td><td class=\"cid\">${esc(String(r.clientId || '').slice(0, 10))}</td></tr>`).join('')\n    inner = `<div class=\"ackpis\">\n        <div class=\"ackpi\"><div class=\"acl\">Aberturas</div><div class=\"acv\">${ac.opens || 0}</div></div>\n        <div class=\"ackpi\"><div class=\"acl\">Entradas com a senha</div><div class=\"acv\">${ac.logins || 0}</div></div>\n        <div class=\"ackpi\"><div class=\"acl\">Dispositivos distintos</div><div class=\"acv\">${Object.keys(seen).length}</div></div>\n      </div>\n      <div class=\"acsub\">Acessos recentes</div>\n      <div class=\"tbw\"><table class=\"tb\"><thead><tr><th>Quando</th><th>Evento</th><th>Dispositivo</th><th>ID do navegador</th></tr></thead><tbody>${rows || '<tr><td>Sem acessos ainda.</td><td>—</td><td>—</td><td>—</td></tr>'}</tbody></table></div>\n      <button class=\"chip acrefresh\" style=\"cursor:pointer;background:none\">Atualizar</button>`\n  }\n  return `<div class=\"acwrap\">\n    <header><img class=\"d2\" src=\"${LD2}\" alt=\"Data²\">${VS('hvs')}</header>\n    <div class=\"acbody\">\n      <div class=\"eyebrow\">Monitoramento · Proposta Veste S/A</div>\n      <h2 class=\"actit\">Quem acessou</h2>\n      ${inner}\n    </div>\n  </div>`\n}\n\nfunction injectFonts() {\n  try {\n    if (!document.getElementById('akz-deck-fonts')) {\n      const st = document.createElement('style')\n      st.id = 'akz-deck-fonts'\n      st.textContent = FONT_CSS\n      document.head.appendChild(st)\n    }\n  } catch (e) {}\n}\n\nfunction initDeck(host) {\n  const wrap = host && host.querySelector('.deckwrap'); if (!wrap) return\n  if (wrap.dataset.init === '1') return\n  wrap.dataset.init = '1'\n  const rootEl = wrap.querySelector('.deckroot')\n  const slides = [].slice.call(rootEl.querySelectorAll('section'))\n  const dots = wrap.querySelector('.dots'), counter = wrap.querySelector('.counter')\n  dots.innerHTML = ''\n  const pad = n => (n < 10 ? '0' : '') + n\n  let cur = 0\n  counter.textContent = pad(1) + ' — ' + pad(slides.length)\n  slides.forEach((s, i) => {\n    const a = document.createElement('a')\n    a.href = '#' + s.id; a.setAttribute('aria-label', 'Slide ' + (i + 1))\n    dots.appendChild(a)\n  })\n  const links = [].slice.call(dots.children)\n  if (links[0]) links[0].classList.add('on')\n\n  const setActive = i => {\n    if (i === cur) return\n    cur = i\n    counter.textContent = pad(cur + 1) + ' — ' + pad(slides.length)\n    links.forEach((l, k) => l.classList.toggle('on', k === cur))\n    wrap.classList.toggle('on-dark', slides[cur].hasAttribute('data-dark'))\n    wrap.classList.toggle('last', cur === slides.length - 1)\n  }\n\n  const revIO = new IntersectionObserver(es => {\n    es.forEach(e => { if (e.isIntersecting) { e.target.classList.add('in'); revIO.unobserve(e.target) } })\n  }, { root: rootEl, rootMargin: '0px 0px 12% 0px', threshold: .01 })\n  slides.forEach(s => revIO.observe(s))\n\n  const ratios = new Array(slides.length).fill(0)\n  const actIO = new IntersectionObserver(es => {\n    es.forEach(e => { const i = slides.indexOf(e.target); if (i > -1) ratios[i] = e.isIntersecting ? e.intersectionRatio : 0 })\n    let bi = cur, bv = -1\n    ratios.forEach((r, i) => { if (r > bv) { bv = r; bi = i } })\n    if (bv > 0) setActive(bi)\n  }, { root: rootEl, threshold: [0, .15, .35, .55, .75, 1] })\n  slides.forEach(s => actIO.observe(s))\n\n  setTimeout(() => {\n    if (!rootEl.querySelector('section.in')) slides.forEach(s => s.classList.add('in'))\n  }, 500)\n\n  const rm = (typeof matchMedia === 'function') && matchMedia('(prefers-reduced-motion: reduce)').matches\n  const go = i => {\n    i = Math.max(0, Math.min(slides.length - 1, i))\n    slides[i].scrollIntoView({ behavior: rm ? 'auto' : 'smooth' })\n  }\n\n  wrap.addEventListener('click', ev => {\n    const a = ev.target.closest && ev.target.closest('a[href^=\"#\"]'); if (!a) return\n    ev.preventDefault()\n    const t = slides.find(s => s.id === a.getAttribute('href').slice(1))\n    if (t) t.scrollIntoView({ behavior: rm ? 'auto' : 'smooth' })\n  })\n\n  window.addEventListener('keydown', e => {\n    if (!wrap.isConnected) return\n    if (e.target && /^(INPUT|TEXTAREA)$/.test(e.target.tagName)) return\n    if (e.key === 'ArrowDown' || e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') { e.preventDefault(); go(cur + 1) }\n    if (e.key === 'ArrowUp' || e.key === 'ArrowLeft' || e.key === 'PageUp') { e.preventDefault(); go(cur - 1) }\n    if (e.key === 'Home') { e.preventDefault(); go(0) }\n    if (e.key === 'End') { e.preventDefault(); go(slides.length - 1) }\n  })\n}\n\n/* Este player não re-renderiza de forma confiável quando d2.state muda: a senha\n   gravava a sessão e o gate continuava na tela. Então a fase vive numa variável\n   de módulo e a troca de tela é feita na mão, com innerHTML. */\nlet phase = 'gate'\nlet acState = { status: 'locked' }\nlet clientId = ''\n\nfunction cid() {\n  if (clientId) return clientId\n  try {\n    clientId = window.localStorage.getItem('veste_prop_cid') || ''\n    if (!clientId) {\n      clientId = 'c' + Date.now().toString(36) + Math.floor(Math.random() * 1e6).toString(36)\n      window.localStorage.setItem('veste_prop_cid', clientId)\n    }\n  } catch (e) { clientId = 'c-anon' }\n  return clientId\n}\n\nfunction track(event) {\n  try {\n    /* probe automatizado (inspect_code_component, crawler headless) não é\n       abertura de proposta — não suja o painel de acessos */\n    if (navigator.webdriver === true) return\n    fetch(RUSH + '/veste-prop-track', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({\n        event: event,\n        clientId: cid(),\n        device: String(navigator.userAgent || '').slice(0, 180),\n        ref: String(document.referrer || '')\n      })\n    }).catch(() => {})\n  } catch (e) {}\n}\n\nfunction paintAcessos(host) {\n  host.innerHTML = acessosHTML(acState)\n  const wire = (sel, evt, fn) => { const el = host.querySelector(sel); if (el) el.addEventListener(evt, fn) }\n  wire('.acbtn', 'click', () => {\n    const el = host.querySelector('.acpass')\n    const pw = (el && el.value) || ''\n    if (!pw) { acState = { status: 'locked', error: 'Digite a senha.' }; paintAcessos(host); return }\n    loadAcessos(host, pw)\n  })\n  wire('.acpass', 'keydown', (e) => { if (e.key === 'Enter') { const b = host.querySelector('.acbtn'); if (b) b.click() } })\n  wire('.acrefresh', 'click', () => {\n    let pw = ''\n    try { pw = window.localStorage.getItem('veste_prop_admin') || '' } catch (e) {}\n    loadAcessos(host, pw)\n  })\n}\n\nfunction loadAcessos(host, pw) {\n  acState = { status: 'loading' }\n  paintAcessos(host)\n  fetch(RUSH + '/veste-prop-acessos', {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({ password: pw })\n  })\n    .then(r => r.json())\n    .then(r => {\n      const s = (r && r.data) ? r.data : r\n      if (!s || s.ok !== true) {\n        try { window.localStorage.removeItem('veste_prop_admin') } catch (e) {}\n        acState = { status: 'locked', error: pw ? 'Senha incorreta.' : null }\n      } else {\n        try { window.localStorage.setItem('veste_prop_admin', pw) } catch (e) {}\n        acState = { status: 'done', ac: s }\n      }\n      paintAcessos(host)\n    })\n    .catch(err => {\n      acState = { status: 'locked', error: 'Falha ao carregar: ' + String((err && err.message) || err) }\n      paintAcessos(host)\n    })\n}\n\nfunction mountGate(host) {\n  const card = host.querySelector('.gcard'); if (!card || card.dataset.wired === '1') return\n  card.dataset.wired = '1'\n  const inp = host.querySelector('.ginput'), btn = host.querySelector('.gbtn')\n  const check = () => {\n    if (!inp) return\n    if (inp.value === PASS) {\n      try { sessionStorage.setItem('deckVesteUnlocked', '1') } catch (e) {}\n      track('login')\n      showDeck(host)\n    } else {\n      const er = host.querySelector('.gerr')\n      if (er) er.style.display = 'block'\n      card.classList.remove('shake'); void card.offsetWidth; card.classList.add('shake')\n      if (inp.select) inp.select()\n    }\n  }\n  if (btn) btn.addEventListener('click', check)\n  if (inp) inp.addEventListener('keydown', e => { if (e.key === 'Enter') check() })\n}\n\nfunction showDeck(host) {\n  phase = 'deck'\n  host.innerHTML = DECK\n  initDeck(host)\n}\n\nfunction sync(d2, root) {\n  const host = (d2 && d2.$ && d2.$('.deckhost')) || ((root || document).querySelector('.deckhost'))\n  if (!host) return\n  if (phase === 'acessos') {\n    if (!host.querySelector('.acwrap')) paintAcessos(host)\n    return\n  }\n  if (phase === 'deck') {\n    if (!host.querySelector('.deckwrap')) host.innerHTML = DECK\n    initDeck(host)\n    return\n  }\n  if (!host.querySelector('.gwrap')) host.innerHTML = GATE\n  mountGate(host)\n}\n\nexport default {\n  css: `\n:host,.deckwrap,.gwrap,.acwrap{\n  --paper:#F5F4F0;\n  --ink:#15161A;\n  --muted:#6A6E77;\n  --accent:#96570F;\n  --accent-soft:#C89A4A;\n  --ok:#2C6B4A;\n  --bad:#A33427;\n  --dark:#17253F;\n  --dark-2:#22314F;\n  --linha:rgba(21,22,26,.13);\n  --mx:clamp(20px,4vw,56px);\n  --ext:'AkzExt','Helvetica Neue',Helvetica,Arial,sans-serif;\n  --lt:'AkzExtLight','Helvetica Neue',Helvetica,Arial,sans-serif;\n  --sf:-apple-system,BlinkMacSystemFont,'SF Pro Text','Inter','Helvetica Neue',Helvetica,Arial,sans-serif;\n}\n*{box-sizing:border-box;margin:0;padding:0}\n.deckhost{display:block;width:100%;height:100%}\n\n/* ---------- arquitetura de scroll ---------- */\n.deckwrap{position:relative;height:100vh;height:100svh;overflow:hidden;\n  background:var(--paper);color:var(--ink);font-family:var(--lt);\n  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}\n.deckroot{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;\n  scroll-snap-type:y proximity;scroll-behavior:smooth;\n  -webkit-overflow-scrolling:touch;overscroll-behavior-y:contain}\n\n/* ---------- chrome ---------- */\nheader{position:absolute;inset:0 0 auto 0;z-index:40;display:flex;\n  justify-content:space-between;align-items:center;padding:22px var(--mx) 34px;\n  pointer-events:none;background:linear-gradient(to bottom,var(--paper) 52%,rgba(245,244,240,0))}\n.deckwrap.on-dark header{background:none}\nheader img.d2{height:16px;display:block;filter:brightness(0);opacity:.92}\nheader img.hvs{height:13px;width:auto;display:block;opacity:.92}\n.deckwrap.on-dark header img.d2{filter:none;opacity:1}\n.deckwrap.on-dark header img.hvs{filter:brightness(0) invert(1);opacity:1}\n.counter{position:absolute;z-index:40;left:var(--mx);bottom:38px;font-family:var(--lt);\n  font-size:11px;letter-spacing:.22em;color:var(--muted)}\n.deckwrap.on-dark .counter{color:rgba(255,255,255,.75)}\nnav.dots{position:absolute;z-index:40;right:clamp(14px,2.4vw,32px);top:50%;\n  transform:translateY(-50%);display:flex;flex-direction:column;gap:12px}\nnav.dots a{width:6px;height:6px;border-radius:50%;background:var(--muted);opacity:.35;\n  transition:opacity .3s,transform .3s}\nnav.dots a.on{opacity:1;transform:scale(1.5);background:var(--ink)}\n.deckwrap.on-dark nav.dots a,.deckwrap.on-dark nav.dots a.on{background:#fff}\n.hint{position:absolute;z-index:40;right:var(--mx);bottom:38px;font-size:11px;\n  letter-spacing:.22em;color:var(--muted);text-transform:uppercase;transition:opacity .4s}\n.deckwrap.last .hint{opacity:0}\n.deckwrap.on-dark .hint{color:rgba(255,255,255,.6)}\n\n/* ---------- slide ---------- */\nsection{min-height:100vh;min-height:100svh;scroll-snap-align:start;position:relative;\n  display:flex;flex-direction:column;justify-content:center;\n  padding:clamp(84px,12vh,140px) clamp(20px,7vw,120px)}\n.eyebrow{font-size:12px;letter-spacing:.3em;text-transform:uppercase;color:var(--muted);\n  margin-bottom:clamp(20px,4vh,44px)}\n.eyebrow b{font-weight:400;color:var(--accent)}\n\n/* ---------- reveals ---------- */\n.rv{opacity:0;transform:translateY(26px);\n  transition:opacity .9s cubic-bezier(.2,.6,.2,1),transform .9s cubic-bezier(.2,.6,.2,1)}\nsection.in .rv{opacity:1;transform:none}\nsection.in .rv:nth-child(2),section.in .d2{transition-delay:.12s}\nsection.in .rv:nth-child(3),section.in .d3{transition-delay:.24s}\nsection.in .rv:nth-child(4),section.in .d4{transition-delay:.36s}\nsection.in .rv:nth-child(5),section.in .d5{transition-delay:.48s}\nsection.in .rv:nth-child(6),section.in .d6{transition-delay:.6s}\n\n/* ---------- tipografia ---------- */\nh1,h2{font-family:var(--ext);font-weight:400;text-wrap:balance}\n.apoio{max-width:44ch;font-size:clamp(15px,1.5vw,19px);line-height:1.65;color:var(--muted)}\n.apoio::before{content:'';display:block;width:36px;height:2px;background:var(--accent);\n  margin-bottom:18px}\n.apoio.destaque{color:var(--ink);font-size:clamp(16px,1.7vw,21px);line-height:1.6}\n.split{display:grid;grid-template-columns:1.4fr .8fr;gap:clamp(28px,6vw,90px);align-items:end}\n.split>*{min-width:0}\n@media(max-width:820px){.split{grid-template-columns:1fr}}\n\n.apoio,.lead,.pilar p,.onda li,.custos .row .d,.cond,.arq .box .bd,\n.kpis .k p,.klist li,.tb{font-family:var(--sf)}\n\n:focus-visible{outline:2px solid var(--accent);outline-offset:4px}\n@media (prefers-reduced-motion:reduce){\n  .deckroot{scroll-behavior:auto}\n  .rv{opacity:1;transform:none;transition:none}\n}\n\n/* ---------- fundo gráfico ---------- */\n.bg{position:absolute;inset:0;z-index:0;overflow:hidden;background:\n  radial-gradient(ellipse 70% 60% at 18% 85%,rgba(35,71,127,.66),transparent 62%),\n  radial-gradient(ellipse 50% 45% at 88% 12%,rgba(200,154,74,.24),transparent 60%),\n  linear-gradient(135deg,var(--dark) 0%,var(--dark-2) 55%,#0E1729 100%)}\n.bg .grid{position:absolute;inset:0;\n  background-image:linear-gradient(rgba(255,255,255,.055) 1px,transparent 1px),\n                   linear-gradient(90deg,rgba(255,255,255,.055) 1px,transparent 1px);\n  background-size:64px 64px;\n  mask-image:radial-gradient(ellipse 85% 80% at 50% 50%,#000 30%,transparent 100%);\n  -webkit-mask-image:radial-gradient(ellipse 85% 80% at 50% 50%,#000 30%,transparent 100%)}\n.bg .mark{position:absolute;left:50%;transform:translateX(-50%);bottom:6%;width:74%;height:auto;\n  filter:brightness(0) invert(1);opacity:.055}\n@media(max-width:820px){.bg .mark{width:150%;bottom:12%}}\n\n/* ---------- capa ---------- */\n.capa{padding:clamp(72px,10vh,104px) var(--mx) clamp(62px,9vh,88px);background:var(--paper)}\n.capa .frame{position:relative;border-radius:clamp(18px,2.4vw,30px);overflow:hidden;flex:1;\n  min-height:min(58vh,640px);display:flex;align-items:center;justify-content:center;color:#fff}\n.capa .frame .mid{position:relative;z-index:1;display:flex;flex-direction:column;\n  align-items:center;text-align:center;gap:28px}\n.capa .frame .sub{font-family:var(--lt);font-size:clamp(12px,1.3vw,16px);letter-spacing:.16em;\n  text-transform:uppercase;opacity:.92}\n.capa .frame .brands{font-family:var(--lt);font-size:clamp(10px,1.05vw,12.5px);\n  letter-spacing:.24em;text-transform:uppercase;opacity:.6}\n.capa .caption{display:flex;justify-content:space-between;align-items:baseline;gap:24px;\n  padding:clamp(16px,2.6vh,26px) 0 0;flex-wrap:wrap}\n.capa .caption .frase-cap{font-family:var(--lt);font-size:clamp(14px,1.55vw,19px);\n  color:var(--ink);letter-spacing:.01em}\n.capa .caption .meta{font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted)}\n\n.lockup{display:flex;align-items:center;gap:clamp(18px,3vw,34px)}\n.lockup img{display:block}\n.lockup .d2m{height:clamp(30px,4.6vw,54px)}\n.lockup img.vsm{height:clamp(20px,2.9vw,34px);width:auto;filter:brightness(0) invert(1)}\n.lockup img.vsm-s{height:17px;width:auto;filter:brightness(0) invert(1)}\n.lockup .plus{font-family:var(--lt);font-size:clamp(22px,3vw,36px);line-height:1;opacity:.9}\n\n/* ---------- índice ---------- */\n.indice{display:grid;grid-template-columns:1fr 1fr;gap:0 clamp(28px,5vw,90px);\n  border-top:1px solid var(--linha)}\n.indice a{display:flex;align-items:baseline;gap:18px;padding:clamp(10px,1.7vh,17px) 0;\n  border-bottom:1px solid var(--linha);text-decoration:none;color:var(--ink)}\n.indice a .n{font-family:var(--lt);font-size:11px;letter-spacing:.18em;color:var(--muted);\n  min-width:28px;transition:color .25s}\n.indice a .t{font-family:var(--ext);font-size:clamp(15px,1.7vw,23px);line-height:1.25;\n  transition:transform .3s cubic-bezier(.2,.6,.2,1)}\n.indice a:hover .n,.indice a:focus-visible .n{color:var(--accent)}\n.indice a:hover .t,.indice a:focus-visible .t{transform:translateX(6px)}\n@media(max-width:820px){.indice{grid-template-columns:1fr}}\n\n/* ---------- statement ---------- */\n.statement h1{font-size:clamp(34px,5.6vw,86px);line-height:1.08;letter-spacing:-.01em;max-width:16ch}\n\n/* ---------- pilares ---------- */\n.pilares{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(22px,3.4vw,56px);\n  border-top:1px solid var(--linha);padding-top:clamp(26px,5vh,52px)}\n.pilares.dois{grid-template-columns:1fr 1fr}\n.pilar .k{display:block;font-size:11px;letter-spacing:.26em;color:var(--accent);\n  text-transform:uppercase;margin-bottom:18px}\n.pilar .t{font-family:var(--ext);font-size:clamp(17px,1.7vw,23px);line-height:1.3;margin-bottom:16px}\n.pilar p{font-size:14.5px;line-height:1.7;color:var(--muted)}\n@media(max-width:820px){.pilares,.pilares.dois{grid-template-columns:1fr}}\n\n/* ---------- chip de link ---------- */\n.chip{display:inline-flex;align-items:center;gap:10px;margin-top:clamp(22px,3.6vh,34px);\n  padding:11px 20px;border:1px solid var(--linha);border-radius:999px;font-family:var(--lt);\n  font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--accent);\n  text-decoration:none;transition:border-color .25s}\n.chip:hover{border-color:var(--accent)}\n\n/* ---------- arquitetura ---------- */\n.arq{display:grid;grid-template-columns:1fr 44px 1.15fr 44px 1fr;gap:clamp(10px,1.2vw,18px);\n  align-items:stretch;border-top:1px solid var(--linha);padding-top:clamp(24px,4vh,44px)}\n.arq .col{display:flex;flex-direction:column;gap:10px}\n.arq .col-h{font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted);\n  margin-bottom:8px;line-height:1.5}\n.arq .box{border:1px solid var(--linha);border-radius:14px;padding:13px 15px}\n.arq .box .bn{font-family:var(--ext);font-size:12.5px;line-height:1.4}\n.arq .box .bd{font-size:11.5px;color:var(--muted);margin-top:4px;line-height:1.5}\n.arq .core{background:var(--dark);color:#fff;border-radius:18px;padding:clamp(16px,2.4vh,26px);\n  display:flex;flex-direction:column;gap:12px;height:100%}\n.arq .core .ch{font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--accent-soft)}\n.arq .core .box{border-color:rgba(255,255,255,.25)}\n.arq .core .box .bd{color:rgba(255,255,255,.72)}\n.arq .link{position:relative;display:flex;align-items:center;justify-content:center}\n.arq .link::before{content:'';position:absolute;left:-6px;right:-6px;top:50%;height:1px;\n  background:var(--muted);opacity:.5}\n.arq .link span{position:relative;background:var(--paper);font-size:9px;letter-spacing:.2em;\n  text-transform:uppercase;color:var(--muted);transform:rotate(-90deg);white-space:nowrap;padding:0 6px}\n@media(max-width:900px){\n  .arq{grid-template-columns:1fr}\n  .arq .link{min-height:34px}\n  .arq .link::before{left:50%;right:auto;top:0;bottom:0;width:1px;height:auto}\n  .arq .link span{transform:none}\n}\n\n/* ---------- frentes de escopo ---------- */\n.leg{display:flex;gap:26px;flex-wrap:wrap;margin-bottom:clamp(18px,3vh,30px);\n  font-family:var(--sf);font-size:12.5px;color:var(--muted)}\n.leg span{display:flex;align-items:center;gap:8px}\n.leg i{width:9px;height:9px;border-radius:50%;display:inline-block}\n.leg .ok{background:var(--ok)}\n.leg .nv{background:var(--accent)}\n.frentes{display:grid;grid-template-columns:1fr 1fr;border-top:1px solid var(--linha);\n  column-gap:clamp(24px,4vw,64px)}\n.frentes .f{border-bottom:1px solid var(--linha);padding:clamp(12px,1.8vh,18px) 0}\n.frentes .fn{font-family:var(--ext);font-size:clamp(13px,1.2vw,15.5px);margin-bottom:8px;\n  display:flex;justify-content:space-between;gap:12px;align-items:baseline}\n.frentes .fn .ct{font-family:var(--sf);font-size:10.5px;color:var(--muted);white-space:nowrap;\n  letter-spacing:.04em}\n.frentes .fi{display:flex;gap:8px;align-items:baseline;font-family:var(--sf);font-size:12px;\n  line-height:1.5;color:var(--ink);padding:2.5px 0}\n.frentes .fi::before{content:'';width:6px;height:6px;border-radius:50%;flex:none;\n  position:relative;top:-1px}\n.frentes .fi.ok::before{background:var(--ok)}\n.frentes .fi.nv::before{background:var(--accent)}\n@media(max-width:900px){.frentes{grid-template-columns:1fr}}\n\n/* ---------- kpis ---------- */\n.kpis{display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid var(--linha)}\n.kpis .k{padding:clamp(16px,2.6vh,26px) 22px clamp(16px,2.6vh,26px) 0;border-bottom:1px solid var(--linha)}\n.kpis .k .kt{font-family:var(--ext);font-size:clamp(13.5px,1.25vw,16px);line-height:1.35}\n.kpis .k p{font-size:12.5px;color:var(--muted);line-height:1.6;margin-top:8px}\n.kpis .k .kb{font-family:var(--sf);font-size:11.5px;color:var(--accent);margin-top:8px;line-height:1.5}\n@media(max-width:900px){.kpis{grid-template-columns:1fr 1fr}}\n@media(max-width:600px){.kpis{grid-template-columns:1fr}}\n\n/* ---------- cronograma ---------- */\n.ondas{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(22px,3vw,48px);\n  position:relative;padding-top:clamp(30px,5vh,52px)}\n.ondas::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:var(--linha)}\n.onda{position:relative}\n.onda::before{content:'';position:absolute;top:calc(-1 * clamp(30px,5vh,52px));left:0;\n  width:9px;height:9px;border-radius:50%;background:var(--accent);transform:translateY(-4px)}\n.onda .fase{font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:var(--muted);\n  margin-bottom:10px}\n.onda .t{font-family:var(--ext);font-size:clamp(17px,1.8vw,24px);margin-bottom:18px}\n.onda ul{list-style:none}\n.onda li{font-size:14px;line-height:1.6;color:var(--muted);padding:9px 0;border-bottom:1px solid var(--linha)}\n@media(max-width:820px){.ondas{grid-template-columns:1fr}.onda::before{display:none}}\n\n/* ---------- investimento ---------- */\n.custos{border-top:1px solid var(--linha);max-width:880px}\n.custos .row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:24px;\n  padding:clamp(10px,1.8vh,18px) 0;border-bottom:1px solid var(--linha)}\n.custos .row .t{font-family:var(--ext);font-size:clamp(15px,1.5vw,20px)}\n.custos .row .d{font-size:13px;color:var(--muted);margin-top:5px;max-width:56ch;line-height:1.6}\n.custos .row .v{font-family:var(--ext);font-size:clamp(19px,2.1vw,30px);\n  font-variant-numeric:tabular-nums;white-space:nowrap}\n.custos .row .v em{font-style:normal;color:var(--muted);font-family:var(--lt);font-size:.55em;\n  letter-spacing:.1em}\n.custos .total .v{color:var(--accent)}\n.cond{margin-top:clamp(14px,2.2vh,22px);font-size:13px;line-height:1.7;color:var(--muted);max-width:64ch}\n\n/* ---------- tabelas comerciais ---------- */\n.tbw{overflow-x:auto;border-top:1px solid var(--linha)}\n.tb{width:100%;border-collapse:collapse;min-width:560px}\n.tb th{text-align:left;font-family:var(--lt);font-weight:400;font-size:10px;letter-spacing:.2em;\n  text-transform:uppercase;color:var(--muted);padding:14px 22px 12px 0;\n  border-bottom:1px solid var(--linha);white-space:nowrap}\n.tb td{padding:13px 22px 13px 0;font-size:13px;color:var(--muted);line-height:1.5;\n  border-bottom:1px solid var(--linha);white-space:nowrap;font-variant-numeric:tabular-nums}\n.tb td:first-child{font-family:var(--ext);color:var(--ink);font-size:13.5px}\n.tb td strong{font-family:var(--ext);font-weight:400;color:var(--ink)}\n.tb tbody tr:last-child td{border-bottom:0}\n\n/* ---------- listas de compromisso ---------- */\n.klist{list-style:none;margin-top:6px}\n.klist li{font-size:13.5px;line-height:1.6;color:var(--ink);padding:10px 0;\n  border-bottom:1px solid var(--linha);display:flex;gap:10px;align-items:baseline}\n.klist li b{font-weight:600}\n.klist li::before{content:'';width:6px;height:6px;border-radius:50%;flex:none;\n  background:var(--ok);position:relative;top:-1px}\n.klist.neg li::before{background:var(--bad)}\n\n/* ---------- fechamento ---------- */\n.dark{color:#fff}\n.dark .mid{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;\n  text-align:center;gap:34px}\n.dark .sub{font-family:var(--lt);font-size:clamp(12px,1.3vw,16px);letter-spacing:.14em;\n  text-transform:uppercase;opacity:.92}\n.fecho .mid{gap:44px}\n.fecho .frase{font-family:var(--lt);font-size:clamp(16px,1.8vw,25px);line-height:1.65;\n  letter-spacing:.025em;max-width:44ch;text-wrap:balance}\n.fecho .frase i{font-style:normal;opacity:.65}\n.ring{width:clamp(54px,5.4vw,80px);height:auto;display:block}\n.ring.branco{filter:brightness(0) invert(1)}\n@media(max-width:820px){.fecho .frase{font-size:15px}}\n\n/* ---------- mobile ---------- */\n@media(max-width:820px){\n  .deckroot{scroll-snap-type:y proximity}\n  .deckwrap::after{content:'';position:absolute;left:0;right:0;bottom:0;z-index:35;\n    pointer-events:none;background:linear-gradient(to top,var(--paper) 42%,rgba(245,244,240,0));\n    height:78px}\n  .deckwrap.on-dark::after{display:none}\n  nav.dots{display:none}\n  section{padding:72px 20px 82px}\n  .counter,.hint{bottom:34px}\n  .eyebrow{margin-bottom:18px}\n  .capa{padding:60px var(--mx) 96px}\n  .capa .frame{min-height:42svh}\n  .capa .frame .mid{gap:16px;padding:0 20px}\n  .capa .frame .sub{font-size:10.5px;letter-spacing:.12em;text-wrap:balance;line-height:1.7}\n  .capa .frame .brands{font-size:9px;letter-spacing:.18em;line-height:1.8}\n  .capa .lockup{gap:14px}\n  .capa .lockup .d2m{height:25px}\n  .capa .lockup img.vsm{height:16px}\n  .capa .lockup .plus{font-size:17px}\n  .capa .caption{flex-direction:column;align-items:flex-start;gap:10px;padding:18px 2px 0}\n  .capa .caption .frase-cap{font-size:15px;line-height:1.5;max-width:34ch}\n}\n\n/* ---------- gate ---------- */\n.gwrap{position:relative;height:100vh;height:100svh;overflow:hidden;display:flex;\n  align-items:center;justify-content:center;background:var(--dark);font-family:var(--lt)}\n.gcard{position:relative;z-index:1;background:var(--paper);border-radius:20px;\n  padding:40px 36px 32px;width:min(380px,88vw);text-align:center;\n  box-shadow:0 30px 80px rgba(0,0,0,.45)}\n.glock{display:flex;align-items:center;justify-content:center;gap:12px;margin-bottom:14px}\n.glock img{filter:brightness(0);display:block}\n.glock img.gvs{height:14px;width:auto;filter:none}\n.glock span{font-family:var(--lt);font-size:15px;color:var(--ink)}\n.gsub{font-family:var(--lt);font-size:10px;letter-spacing:.24em;text-transform:uppercase;\n  color:var(--muted);margin-bottom:26px}\n.ginput{width:100%;box-sizing:border-box;padding:13px 14px;border:1px solid var(--linha);\n  border-radius:10px;background:#fff;font-size:15px;text-align:center;outline:none;\n  font-family:var(--sf);color:var(--ink)}\n.ginput:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(150,87,15,.16)}\n.gbtn{width:100%;margin-top:12px;padding:13px;border:none;border-radius:10px;\n  background:var(--accent);color:#fff;font-size:12px;letter-spacing:.24em;\n  text-transform:uppercase;cursor:pointer;font-family:var(--lt)}\n.gbtn:hover{filter:brightness(.9)}\n.gerr{display:none;color:var(--bad);font-size:13px;margin-top:12px;font-family:var(--sf)}\n.shake{animation:gsh .4s}\n@keyframes gsh{0%,100%{transform:translateX(0)}20%{transform:translateX(-9px)}\n  40%{transform:translateX(9px)}60%{transform:translateX(-5px)}80%{transform:translateX(5px)}}\n\n/* ---------- painel de acessos ---------- */\n.acwrap{position:relative;min-height:100vh;min-height:100svh;background:var(--paper);\n  color:var(--ink);font-family:var(--lt);overflow-y:auto}\n.acwrap header{position:relative;background:none}\n.acbody{max-width:900px;margin:0 auto;padding:8px clamp(20px,5vw,48px) 80px}\n.actit{font-family:var(--ext);font-weight:400;font-size:clamp(28px,4vw,46px);\n  line-height:1.1;margin-bottom:clamp(22px,4vh,40px)}\n.acgate{max-width:320px}\n.acerr{color:var(--bad);font-size:13px;margin-top:12px;font-family:var(--sf)}\n.acmsg{color:var(--muted);font-family:var(--sf);padding:26px 0}\n.ackpis{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,2vw,26px);\n  border-top:1px solid var(--linha);padding-top:clamp(18px,3vh,28px);\n  margin-bottom:clamp(26px,5vh,46px)}\n.acl{font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--muted);\n  margin-bottom:10px}\n.acv{font-family:var(--ext);font-size:clamp(30px,4.4vw,48px);font-variant-numeric:tabular-nums}\n.acsub{font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:var(--muted);\n  margin-bottom:14px}\n.acwrap .tb{min-width:480px}\n.acwrap .tb .cid{color:var(--muted);font-size:11.5px}\n@media(max-width:700px){.ackpis{grid-template-columns:1fr}}\n  `,\n  render() { return `<div class=\"deckhost\"></div>` },\n  mounted(d2, root) {\n    injectFonts()\n    let admin = false\n    try { admin = ((window.location.search || '') + (window.location.hash || '')).indexOf('acessos') >= 0 } catch (e) {}\n    if (admin) {\n      phase = 'acessos'\n      sync(d2, root)\n      let saved = ''\n      try { saved = window.localStorage.getItem('veste_prop_admin') || '' } catch (e) {}\n      const host = (d2 && d2.$ && d2.$('.deckhost')) || ((root || document).querySelector('.deckhost'))\n      if (saved && host) loadAcessos(host, saved)\n      return\n    }\n    let ok = OPEN\n    try { if (sessionStorage.getItem('deckVesteUnlocked') === '1') ok = true } catch (e) {}\n    try { if ((location.search || '').indexOf('k=' + PASS) > -1) ok = true } catch (e) {}\n    if (ok) phase = 'deck'\n    track('open')\n    sync(d2, root)\n  },\n  updated(d2, root) { sync(d2, root) }\n}\n"}}}}}}}},{"_id":"6aaac5b70ea1ff2bdef8a389","component":"data2-core-types@Component","system":"698a0c028a310c894be98bc8","params":{"extends":"data2-core-primitives@Block","component":"kickoff-tryon-guia","package":"veste-app","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n:host{display:block;width:100%;height:100%}\n.wrap{\n  --paper:#F5F4F0; --ink:#15161A; --muted:#6A6E77; --accent:#96570F; --linha:rgba(21,22,26,.13);\n  background:var(--paper); color:var(--ink); font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue',Helvetica,Arial,sans-serif;\n  width:100%; min-height:100%; overflow-y:auto; padding:clamp(24px,4vw,64px);\n  box-sizing:border-box;\n}\n*{box-sizing:border-box}\nh1{font-size:clamp(24px,3vw,36px);font-weight:600;margin:0 0 6px;letter-spacing:-.01em}\nh2{font-size:clamp(17px,2vw,22px);font-weight:600;margin:36px 0 12px;color:var(--accent)}\n.meta{font-size:13px;color:var(--muted);margin-bottom:18px}\n.badge{display:inline-block;background:var(--accent);color:#fff;font-size:11px;letter-spacing:.08em;\n  text-transform:uppercase;padding:4px 10px;border-radius:999px;margin-bottom:14px}\np{font-size:14.5px;line-height:1.65;color:var(--ink);margin:0 0 10px;max-width:78ch}\np.muted{color:var(--muted)}\nhr{border:none;border-top:1px solid var(--linha);margin:22px 0}\nul{margin:0 0 10px;padding-left:20px}\nli{font-size:14px;line-height:1.65;margin-bottom:8px;max-width:74ch}\nli b{font-weight:600}\n.risk{background:#FBE9E4;border-left:3px solid #A33427;padding:10px 14px;border-radius:6px;margin:10px 0}\n.ok{background:#E8F0EA;border-left:3px solid #2C6B4A;padding:10px 14px;border-radius:6px;margin:10px 0}\ncode{background:rgba(21,22,26,.06);padding:1px 6px;border-radius:4px;font-size:12.5px}\n.foot{margin-top:44px;padding-top:16px;border-top:1px solid var(--linha);font-size:12px;color:var(--muted)}\n`,\n  render(d2) {\n    return `<div class=\"wrap\">\n      <div class=\"badge\">Sprint · Grupo Veste</div>\n      <h1>Kickoff Sprint · Provador Virtual com IA</h1>\n      <div class=\"meta\">16/09/2026 · 14:00–16:00 · gui</div>\n      <p><b>Objetivo do kickoff:</b> alinhar as partes antes de iniciar a Sprint (2–4 semanas, 4 sessões Data²↔Veste) que constrói o provador virtual com IA para as 5 marcas do grupo. Guia de uso ao vivo — preencher decisões durante a call.</p>\n      <p class=\"muted\">Proposta de referência: <code>proposta-veste.veste-app.next.data2.app</code> (senha <code>veste2026</code>).</p>\n\n      <div class=\"risk\"><b>Marca piloto do Dia 1: John John</b> (confirmado por gui, 2026-09-16). Hoje não existe nenhuma prova ao vivo em site nenhum da Veste — é a primeira vez. O catálogo da John John (VTEX) tem request criado mas ainda não validado tecnicamente — só o da Le Lis está testado hoje. Isso é ação técnica bloqueante antes do Dia 1.</div>\n\n      <hr/>\n      <h2>Status técnico real hoje</h2>\n      <ul>\n        <li><b>Catálogo por marca:</b> só Le Lis está de fato prototipado e testado, contra a VTEX Intelligent Search real (<code>lelis.com.br/.../intelligent-search/product_search</code>). John John, Bo.Bô e Dudalina têm requests criados mas não confirmados. Individual não tem integração nenhuma ainda.</li>\n        <li><b>Sessão de busca:</b> existe uma chamada <code>CREATE SESSION</code> para <code>service.smarthint.co</code> (SmartHint) — provedor terceiro separado da VTEX; precisa confirmar se é o caminho oficial.</li>\n        <li><b>Geração de imagem:</b> motor nano-banana já plugado, copiado do engine validado (Dudalina try-on, Roue etc).</li>\n        <li><b>Clothing-Swap / Shoes-Swap:</b> componentes clonados do engine validado — ainda não adaptados/testados com catálogo real da Veste.</li>\n        <li><b>Nada de embed, evento host↔widget, ou jornada de cliente foi definido ainda</b> — núcleo do bloco Tech de hoje.</li>\n      </ul>\n\n      <hr/>\n      <h2>Abertura · 14:00–14:10 (10 min)</h2>\n      <ul>\n        <li>Apresentações — quem está na sala de cada lado, papel de cada um</li>\n        <li>Reconfirmar o que a Sprint entrega e o que fica pra depois (fora de escopo: tamanho, ERP/OMS/estoque, app nativo, loja física)</li>\n        <li>Reconfirmar condições travadas: R$ 0 de sprint, 30 dias de imagem liberada, teto de 2.000 provas, D1/D15/D30</li>\n      </ul>\n\n      <h2>Bloco 1 · Negócio — 14:10–14:45 (35 min)</h2>\n      <ul>\n        <li>John John confirmada como marca piloto — catálogo dela precisa ser validado antes do Dia 1</li>\n        <li>Individual fica fora do piloto, ou entra depois? Precisa virar decisão explícita</li>\n        <li><b>Baseline de conversão</b> — número de hoje da John John, quem do lado Veste confirma no Dia 1</li>\n        <li>Confirmar as 3 métricas: conversão de visitantes (o número que a POC prova), clique em Comprar pós-prova, troca/devolução (leitura só pós-janela, não fecha em 30 dias)</li>\n        <li>Quem aprova uso/consentimento de imagem do cliente (LGPD)</li>\n        <li>Donos de cada lado — contato de negócio e de produto/plataforma</li>\n        <li>Critério de sucesso combinado <b>antes</b> de rodar</li>\n      </ul>\n\n      <h2>Bloco 2 · Marca &amp; UX — 14:45–15:20 (35 min)</h2>\n      <ul>\n        <li>Onde o provador entra na jornada — PDP, home ou landing de campanha?</li>\n        <li>Fluxo: upload de foto → escolha da peça → resultado → Meu Look → Minhas Provas (galeria por e-mail)</li>\n        <li>Estética John John — widget herda o visual do site, ou casca única Data²+Veste?</li>\n        <li>Como comunicar o limite da prova na UI — não promete tamanho/caimento</li>\n        <li>Onde aparece o opt-in de imagem no fluxo</li>\n        <li>Quem no time de marca aprova os textos da jornada</li>\n      </ul>\n\n      <h2>Bloco 3 · Tech — 15:20–15:50 (30 min)</h2>\n      <ul>\n        <li>Contrato de catálogo da John John — mesma VTEX Intelligent Search da Le Lis? SmartHint entra em algum ponto?</li>\n        <li>Formato do embed — script tag, web component, iframe? Alinhar com o time de front da John John</li>\n        <li><b>Eventos host → embed:</b> SKU/produto da PDP atual, sessão/usuário logado, marca/contexto</li>\n        <li><b>Eventos embed → host:</b> \"prova concluída\", \"clique em Comprar\" (navega ou só reporta?), erro/falha de geração</li>\n        <li>Autenticação/CORS da API de catálogo pública — chave, rate limit, allowlist?</li>\n        <li>Contato técnico de plataforma da John John — quem publica o embed</li>\n        <li>Onde fica o tracking Data² vs. o que a Veste já tem (GA/GTM) — evitar dado duplicado na leitura do Dia 30</li>\n      </ul>\n\n      <h2>Encerramento · 15:50–16:00 (10 min)</h2>\n      <ul>\n        <li>Resumo das decisões de cada bloco (preencher ao vivo)</li>\n        <li>Datas de calendário fixadas: Dia 1 / Dia 15 / Dia 30</li>\n        <li>Quem faz o quê até a próxima sessão, com prazo</li>\n        <li>Próxima sessão da Sprint agendada</li>\n      </ul>\n\n      <div class=\"foot\">Doc completo (com comentários e histórico): guia no Claude Docs, linkado na conversa com o gui.</div>\n    </div>`\n  }\n}"}}}}}}}},{"_id":"6aac12eab0831151b3b065b7","component":"data2-core-types@Component","system":"698a0c028a310c894be98bc8","params":{"extends":"data2-core-primitives@Block","component":"provador-standalone","package":"veste-app","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n@import url('https://fonts.googleapis.com/css2?family=Exo+2:wght@400;500;600;700&display=swap');\n:host{display:block;width:100%;height:100%}\n.wrap{\n  --paper:#FFFFFF; --ink:#000000; --muted:#6b6b6b; --accent:#96570F; --accent-soft:#C89A4A;\n  --linha:#e2e2e2; --card:#FFFFFF; --danger:#A33427;\n  width:100%;height:100%;overflow-y:auto;background:var(--paper);color:var(--ink);\n  font-family:'Exo 2',-apple-system,BlinkMacSystemFont,'Helvetica Neue',Helvetica,Arial,sans-serif;\n  box-sizing:border-box;\n}\n*{box-sizing:border-box}\n.hdr{position:sticky;top:0;z-index:10;display:flex;align-items:center;gap:14px;\n  padding:16px clamp(16px,4vw,40px);background:rgba(245,244,240,.92);backdrop-filter:blur(6px);\n  border-bottom:1px solid var(--linha)}\n.hdr .back{border:1px solid var(--linha);background:#fff;border-radius:999px;width:34px;height:34px;\n  display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:16px;flex:none}\n.hdr .brand{font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted)}\n.hdr .brand b{color:var(--ink);font-weight:600}\n.hdr .steps{margin-left:auto;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}\n.hdr .steps b{color:var(--accent)}\n.hdr .closebtn{border:1px solid var(--linha);background:#fff;border-radius:999px;width:34px;height:34px;\n  display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:20px;line-height:1;flex:none;color:var(--muted)}\n.hdr .closebtn:hover{color:var(--ink);border-color:var(--ink)}\n.body{padding:clamp(18px,4vw,40px);max-width:1100px;margin:0 auto}\n.disclaimer{font-size:11.5px;color:var(--muted);line-height:1.5;max-width:60ch;margin:0 0 22px}\n\n/* search */\n.searchbar{display:flex;gap:10px;margin-bottom:26px}\n.searchbar input{flex:1;padding:14px 16px;border:1px solid var(--linha);border-radius:12px;\n  font-size:15px;background:#fff;color:var(--ink)}\n.searchbar input:focus{outline:2px solid var(--accent);outline-offset:1px}\n.searchbar button{padding:0 22px;border:0;border-radius:2px;background:#080707;color:#fff;\n  font-size:14px;font-weight:500;letter-spacing:normal;text-transform:uppercase;cursor:pointer}\n.searchbar button:disabled{opacity:.5;cursor:default}\n.searchbar button:active,.cta:active,.addbag:active,.checkout:active,.chip:active,.iconbtn:active{transform:scale(.96)}\nbutton,.chip,.iconbtn,.card,.cta{transition:transform .12s ease,box-shadow .12s ease,border-color .12s ease}\n.screen-enter{animation:screenIn .38s cubic-bezier(.2,.7,.2,1)}\n@keyframes screenIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}\n.uploadzone.drag{border-color:var(--accent);background:#FBF3E8;transform:scale(1.01)}\n.hint{font-size:12.5px;color:var(--muted);margin:-14px 0 22px}\n.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:16px}\n.card{background:var(--card);border:1px solid var(--linha);border-radius:14px;overflow:hidden;\n  cursor:pointer;transition:transform .15s,box-shadow .15s;display:flex;flex-direction:column}\n.card:hover{transform:translateY(-2px);box-shadow:0 10px 24px rgba(21,22,26,.08)}\n.card .ph{width:100%;aspect-ratio:3/4;background:#eee;background-size:cover;background-position:center}\n.card .info{padding:10px 12px 14px}\n.card .nm{font-size:13px;line-height:1.35;margin-bottom:6px;min-height:34px;font-weight:400;color:#000}\n.card .pr{font-size:13px;color:#000;font-weight:700}\n.empty{padding:60px 0;text-align:center;color:var(--muted);font-size:14px}\n.spin{display:inline-block;width:16px;height:16px;border:2px solid rgba(0,0,0,.15);\n  border-top-color:var(--ink);border-radius:50%;animation:sp .7s linear infinite;vertical-align:-3px}\n@keyframes sp{to{transform:rotate(360deg)}}\n\n/* product */\n.pgrid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,4vw,48px)}\n@media(max-width:720px){.pgrid{grid-template-columns:1fr}}\n.pimg{width:100%;aspect-ratio:3/4;border-radius:16px;background:#eee;background-size:cover;background-position:center}\n.pname{font-size:clamp(20px,2.4vw,26px);font-weight:400;margin:4px 0 6px;line-height:1.25;color:#000}\n.pbrand{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:#666;margin-bottom:14px;font-weight:400}\n.pprice{font-size:22px;color:#000;font-weight:700;margin-bottom:2px}\n.pinstall{font-size:11px;color:#333;font-weight:700;margin-bottom:22px}\n.ptitlerow{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}\n.shareicon{flex:none;border:1px solid var(--linha);background:#fff;border-radius:999px;width:34px;height:34px;\n  display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;color:var(--muted)}\n.sizeguide{font-size:12.5px;color:var(--ink);text-decoration:underline;cursor:pointer;margin:14px 0 0;display:inline-block}\n.accordion{margin-top:26px;border-top:1px solid var(--linha)}\n.acc-item{border-bottom:1px solid var(--linha)}\n.acc-head{display:flex;justify-content:space-between;align-items:center;padding:14px 0;cursor:pointer;\n  font-size:11px;letter-spacing:.16em;text-transform:uppercase;font-weight:600}\n.acc-body{padding:0 0 16px;font-size:13.5px;line-height:1.65;color:var(--muted);display:none}\n.acc-item.open .acc-body{display:block}\n.acc-item.open .acc-chev{transform:rotate(180deg)}\n.acc-chev{transition:transform .2s}\n.optlabel{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);margin:18px 0 8px}\n.opts{display:flex;flex-wrap:wrap;gap:8px}\n.chip{padding:8px 16px;border-radius:999px;border:1px solid var(--linha);background:#fff;\n  font-size:13px;cursor:pointer}\n.chip.on{background:var(--ink);color:#fff;border-color:var(--ink)}\n.cta{margin-top:30px;width:100%;padding:16px;border:0;border-radius:2px;\n  background:var(--danger);color:#fff;font-size:14px;letter-spacing:normal;text-transform:uppercase;\n  font-weight:500;cursor:pointer}\n.cta:hover{filter:brightness(1.05)}\n\n/* upload */\n.uploadzone{border:2px dashed var(--linha);border-radius:18px;padding:clamp(40px,8vw,80px) 20px;\n  text-align:center;background:#fff;cursor:pointer;transition:border-color .15s}\n.uploadzone:hover{border-color:var(--accent)}\n.uploadzone .ic{font-size:34px;margin-bottom:14px}\n.uploadzone .t{font-size:16px;font-weight:600;margin-bottom:6px}\n.uploadzone .s{font-size:13px;color:var(--muted)}\n.instr{margin-top:22px;padding:16px 18px;background:#fff;border:1px solid var(--linha);border-radius:12px;\n  font-size:13px;color:var(--muted);line-height:1.6}\n.instr b{color:var(--ink)}\n\n/* result */\n.rgrid{display:grid;grid-template-columns:1.1fr 1fr;gap:22px}\n@media(max-width:820px){.rgrid{grid-template-columns:1fr}}\n.rimg{width:100%;aspect-ratio:3/4;border-radius:16px;background:#e5e5e5;background-size:cover;\n  background-position:center;position:relative;overflow:hidden}\n.rimg .load{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;\n  justify-content:center;gap:12px;background:rgba(245,244,240,.9);font-size:13px;color:var(--muted)}\n.actrow{display:flex;gap:10px;margin-top:12px;flex-wrap:wrap}\n.iconbtn{flex:1;min-width:76px;padding:10px 8px;border:1px solid var(--linha);border-radius:10px;\n  background:#fff;font-size:11.5px;cursor:pointer;text-align:center}\n.panel{background:#fff;border:1px solid var(--linha);border-radius:16px;padding:20px;display:flex;\n  flex-direction:column;gap:16px}\n.addbag{padding:14px;border:0;border-radius:2px;background:#080707;color:#fff;font-size:14px;\n  letter-spacing:normal;text-transform:uppercase;font-weight:500;cursor:pointer}\n.sug{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:6px}\n.sugcard{border:2px solid var(--linha);border-radius:10px;padding:10px;font-size:11.5px;color:var(--muted);\n  text-align:center;cursor:pointer}\n.sugcard.on{border-color:#080707}\n.sugcard .sugcheck{position:absolute;top:6px;right:6px;width:20px;height:20px;border-radius:999px;\n  background:#080707;color:#fff;display:none;align-items:center;justify-content:center;font-size:12px}\n.sugcard.on .sugcheck{display:flex}\n.gallery{display:flex;gap:10px;overflow-x:auto;margin-top:26px;padding-bottom:6px}\n.gitem{flex:none;width:74px;height:98px;border-radius:10px;background:#eee;background-size:cover;\n  background-position:center;border:2px solid transparent;cursor:pointer}\n.gitem.on{border-color:var(--accent)}\n.checkout{margin-top:18px;width:100%;padding:14px;border:1px solid #080707;border-radius:2px;background:#fff;\n  color:#080707;font-size:14px;font-weight:500;letter-spacing:normal;text-transform:uppercase;cursor:pointer}\n.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);background:var(--ink);color:#fff;\n  padding:12px 20px;border-radius:999px;font-size:13px;z-index:50;box-shadow:0 10px 30px rgba(0,0,0,.25)}\n`,\n\n  render(d2) {\n    const s = d2.state\n    const screen = s.screen || 'search'\n    const step = { search: 1, product: 2, upload: 3, result: 4 }[screen]\n\n    const header = `<div class=\"hdr\">\n      ${screen !== 'search' ? `<div class=\"back\" data-act=\"back\">&larr;</div>` : ''}\n      <div class=\"brand\"><b>John John</b> · Provador Virtual</div>\n      <div class=\"steps\">Passo <b>${step}</b> de 4 — Busca · Produto · Foto · Resultado</div>\n      <div class=\"closebtn\" data-act=\"close\" title=\"Fechar provador\">&times;</div>\n    </div>`\n\n    let inner = ''\n    if (screen === 'search') inner = renderSearch(d2)\n    else if (screen === 'product') inner = renderProduct(d2)\n    else if (screen === 'upload') inner = renderUpload(d2)\n    else inner = renderResult(d2)\n\n    const toast = s.toast ? `<div class=\"toast\">${esc(s.toast)}</div>` : ''\n    return `<div class=\"wrap\">${header}<div class=\"body\"><div class=\"screen-enter\" data-key=\"${screen}\">${inner}</div></div></div>${toast}`\n  },\n\n  mounted(d2) {\n    d2.state.screen = d2.state.screen || 'search'\n\n    // ---- PowerCord embed bridge — real Veste<->Data2 protocol ----\n    // Veste -> Data2: tryon-initialize(customerId), tryon-open(productId, skuId?)\n    // Data2 -> Veste: tryon-add-to-cart([skuID,...]), tryon-checkout(), tryon-sizeBay(productId), close-tryon\n    // Veste -> Data2: cart-state({cartItems})\n    d2.state.cart = d2.state.cart || []\n    try {\n      window.__powercordEmit = (eventName, data) => {\n        window.parent.postMessage({ eventName, data }, '*')\n      }\n      const fetchProductById = async (productId) => {\n        // jj-product does an EXACT id lookup (VTEX legacy Catalog System).\n        // jj-search's Intelligent Search fq=productId is a silent no-op —\n        // it always falls back to a generic ranked list, ignoring the id.\n        const res = await fetch('https://veste-app.data2apis.com/rush/listener/jj-product?productId=' + encodeURIComponent(productId))\n        const json = await res.json()\n        const products = (json && json.data && json.data.products) || []\n        return products[0] || null\n      }\n      const openProduct = async (productId, skuId) => {\n        if (!productId) { d2.state.screen = 'search'; return }\n        const product = await fetchProductById(productId)\n        if (!product) { flashToast(d2, 'Produto não encontrado (id ' + productId + ').'); return }\n        const colors = variationValues(product, 'Cor')\n        const sizes = variationValues(product, 'Tamanho')\n        let preselColor = colors[0] || '', preselSize = sizes[0] || ''\n        if (skuId) {\n          const item = (product.items || []).find((it) => it.itemId === skuId)\n          if (item) {\n            const c = (item.variations || []).find((v) => v.name === 'Cor')\n            const s = (item.variations || []).find((v) => v.name === 'Tamanho')\n            if (c && c.values && c.values[0]) preselColor = c.values[0]\n            if (s && s.values && s.values[0]) preselSize = s.values[0]\n          }\n        }\n        d2.setState({\n          screen: 'product',\n          product,\n          color: preselColor,\n          size: preselSize,\n          lookExtra: null,\n          suggestions: [],\n          userPhoto: '',\n          resultUrl: '',\n        })\n      }\n      window.addEventListener('message', (e) => {\n        const msg = e.data\n        if (!msg || typeof msg !== 'object' || !msg.eventName) return\n        console.log('[provador][powercord] received from host:', msg.eventName, msg.data)\n        if (msg.eventName === 'tryon-initialize') {\n          const customerId = (typeof msg.data === 'string' ? msg.data : msg.data && msg.data.customerId) || ('anon-' + Math.random().toString(36).slice(2, 10))\n          d2.state.customerId = customerId\n        }\n        if (msg.eventName === 'tryon-open') {\n          const productId = msg.data && msg.data.productId\n          const skuId = msg.data && msg.data.skuId\n          openProduct(productId, skuId)\n        }\n        if (msg.eventName === 'cart-state') {\n          const items = Array.isArray(msg.data) ? msg.data : (msg.data && msg.data.cartItems) || []\n          d2.state.cart = items\n        }\n      })\n      // Guest handshake: tells the host's PowerCord instance we're alive.\n      // This is the PowerCord library's own handshake (bare string), separate\n      // from the tryon-initialize BUSINESS event above.\n      window.parent.postMessage('handshake', '*')\n    } catch (err) {\n      console.warn('[provador][powercord] bridge init failed', err)\n    }\n\n    d2.on('.back', 'click', () => {\n      const order = ['search', 'product', 'upload', 'result']\n      const i = order.indexOf(d2.state.screen || 'search')\n      const next = order[Math.max(0, i - 1)]\n      d2.state.screen = next\n      if (i === 0) window.__powercordEmit && window.__powercordEmit('close-tryon', {})\n    })\n    d2.on('.closebtn', 'click', () => {\n      window.__powercordEmit && window.__powercordEmit('close-tryon', {})\n    })\n\n    // ---- search ----\n    d2.on('.searchbar input', 'keydown', (e) => { if (e.key === 'Enter') runSearch(d2) })\n    d2.on('.go', 'click', () => runSearch(d2))\n    d2.on('.card', 'click', (e, el) => {\n      const idx = Number(el.dataset.idx)\n      const product = (d2.state.results || [])[idx]\n      if (!product) return\n      const colors = variationValues(product, 'Cor')\n      const sizes = variationValues(product, 'Tamanho')\n      d2.setState({\n        screen: 'product',\n        product,\n        color: colors[0] || '',\n        size: sizes[0] || '',\n        lookExtra: null,\n        suggestions: [],\n      })\n    })\n\n    // ---- product ----\n    d2.on('.chip', 'click', (e, el) => {\n      const kind = el.dataset.kind\n      const val = el.dataset.val\n      if (kind === 'color') d2.state.color = val\n      if (kind === 'size') d2.state.size = val\n    })\n    d2.on('.cta', 'click', () => { d2.state.screen = 'upload' })\n    d2.on('.act-sizeguide', 'click', () => {\n      const p = d2.state.product\n      window.__powercordEmit && window.__powercordEmit('tryon-sizeBay', p && p.productId)\n    })\n    d2.on('.acc-head', 'click', (e, el) => {\n      const item = el.closest('.acc-item')\n      const key = item && item.dataset.acc\n      d2.state.openAcc = d2.state.openAcc === key ? '' : key\n    })\n\n    // ---- upload ----\n    const doUpload = async (file) => {\n      if (!file) return\n      d2.state.uploading = true\n      d2.state.uploadError = ''\n      try {\n        const out = await d2.drive(d2.params.uploadDrive).upload([file])\n        const url = out && out[0] && out[0].fileUrl\n        if (!url) throw new Error('upload sem retorno')\n        d2.state.userPhoto = url\n        d2.state.uploading = false\n        generate(d2)\n      } catch (err) {\n        d2.state.uploading = false\n        d2.state.uploadError = 'Não deu pra subir a foto. Tenta de novo — ' + (err && err.message ? err.message : 'erro')\n      }\n    }\n    d2.on('.uploadzone', 'click', () => { d2.$('.filepick')?.click() })\n    d2.on('.filepick', 'change', (e, el) => { doUpload(el.files && el.files[0]) })\n    d2.on('.uploadzone', 'dragover', (e, el) => { e.preventDefault(); el.classList.add('drag') })\n    d2.on('.uploadzone', 'dragleave', (e, el) => { el.classList.remove('drag') })\n    d2.on('.uploadzone', 'drop', (e, el) => {\n      e.preventDefault(); el.classList.remove('drag')\n      const file = e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files[0]\n      doUpload(file)\n    })\n\n    // ---- result actions ----\n    d2.on('.act-refazer', 'click', () => generate(d2))\n    d2.on('.act-trocar', 'click', () => { d2.state.userPhoto = ''; d2.state.resultUrl = ''; d2.state.screen = 'upload' })\n    d2.on('.act-share', 'click', () => flashToast(d2, 'Share fica pra versão embed — aqui é só o protótipo.'))\n    d2.on('.act-feedback', 'click', () => flashToast(d2, 'Obrigado! Feedback registrado (mock).'))\n    d2.on('.addbag', 'click', () => {\n      const p = d2.state.product\n      const skuId = resolveSkuId(p, d2.state.color, d2.state.size)\n      if (!skuId) { flashToast(d2, 'Selecione cor e tamanho antes de adicionar à sacola.'); return }\n      d2.state.cart = [...(d2.state.cart || []), skuId]\n      window.__powercordEmit && window.__powercordEmit('tryon-add-to-cart', [skuId])\n      flashToast(d2, 'Adicionado à sacola.')\n    })\n    d2.on('.checkout', 'click', () => {\n      if (!(d2.state.cart || []).length) { flashToast(d2, 'Sacola vazia — adicione uma peça antes do checkout.'); return }\n      window.__powercordEmit && window.__powercordEmit('tryon-checkout', {})\n    })\n    d2.on('.gitem', 'click', (e, el) => {\n      const idx = Number(el.dataset.idx)\n      const item = (d2.state.gallery || [])[idx]\n      if (item) d2.state.resultUrl = item.url\n    })\n    d2.on('.sugcard-click', 'click', (e, el) => {\n      const idx = Number(el.dataset.idx)\n      const item = (d2.state.suggestions || [])[idx]\n      if (!item) return\n      const colors = variationValues(item, 'Cor')\n      const sizes = variationValues(item, 'Tamanho')\n      d2.setState({\n        product: item,\n        color: colors[0] || '',\n        size: sizes[0] || '',\n        lookExtra: null,\n        suggestions: [],\n      })\n      generate(d2)\n    })\n  },\n}\n\nfunction renderSearch(d2) {\n  const s = d2.state\n  const results = s.results || []\n  let list\n  if (s.loadingSearch) {\n    list = `<div class=\"empty\"><span class=\"spin\"></span>&nbsp; buscando no catálogo John John…</div>`\n  } else if (s.searchError) {\n    list = `<div class=\"empty\">${esc(s.searchError)}</div>`\n  } else if (!results.length) {\n    list = `<div class=\"empty\">${s.searched ? 'Nada encontrado — tenta outro termo.' : 'Busque uma peça pra começar (ex: \"blusa\", \"saia\", \"vestido\").'}</div>`\n  } else {\n    list = `<div class=\"grid\">${results.map((p, i) => {\n      const img = (p.items && p.items[0] && p.items[0].images && p.items[0].images[0] && p.items[0].images[0].imageUrl) || ''\n      const price = p.priceRange && p.priceRange.sellingPrice ? d2.fmt.currency(p.priceRange.sellingPrice.lowPrice, 'BRL', { locale: 'pt-BR' }) : ''\n      return `<div class=\"card\" data-idx=\"${i}\" data-key=\"${esc(p.productId || i)}\">\n        <div class=\"ph\" style=\"background-image:url('${esc(img)}')\"></div>\n        <div class=\"info\"><div class=\"nm\">${esc(p.productName)}</div><div class=\"pr\">${price}</div></div>\n      </div>`\n    }).join('')}</div>`\n  }\n  return `<div class=\"disclaimer\">Catálogo real da John John (VTEX Intelligent Search). O provador mostra como a peça fica em você — não substitui a tabela de medidas.</div>\n    <div class=\"searchbar\">\n      <input type=\"text\" placeholder=\"Buscar produto…\" value=\"${esc(d2.state.query || '')}\" data-bind=\"query\"/>\n      <button class=\"go\" ${d2.state.loadingSearch ? 'disabled' : ''}>Buscar</button>\n    </div>\n    ${list}`\n}\n\nfunction renderProduct(d2) {\n  const p = d2.state.product\n  if (!p) return `<div class=\"empty\">Nenhum produto selecionado.</div>`\n  const img = (p.items && p.items[0] && p.items[0].images && p.items[0].images[0] && p.items[0].images[0].imageUrl) || ''\n  const price = p.priceRange && p.priceRange.sellingPrice ? d2.fmt.currency(p.priceRange.sellingPrice.lowPrice, 'BRL', { locale: 'pt-BR' }) : ''\n  const colors = variationValues(p, 'Cor')\n  const sizes = variationValues(p, 'Tamanho')\n  const installments = p.priceRange && p.priceRange.sellingPrice ? d2.fmt.currency(p.priceRange.sellingPrice.lowPrice / 6, 'BRL', { locale: 'pt-BR' }) : ''\n  const desc = htmlToText(p.description)\n  const open = d2.state.openAcc || ''\n  return `<div class=\"pgrid\">\n    <div class=\"pimg\" style=\"background-image:url('${esc(img)}')\"></div>\n    <div>\n      <div class=\"ptitlerow\">\n        <div>\n          <div class=\"pbrand\">${esc(p.brand || 'John John')}</div>\n          <div class=\"pname\">${esc(p.productName)}</div>\n        </div>\n        <div class=\"shareicon act-share\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"18\" cy=\"5\" r=\"3\"/><circle cx=\"6\" cy=\"12\" r=\"3\"/><circle cx=\"18\" cy=\"19\" r=\"3\"/><line x1=\"8.6\" y1=\"10.6\" x2=\"15.4\" y2=\"6.4\"/><line x1=\"8.6\" y1=\"13.4\" x2=\"15.4\" y2=\"17.6\"/></svg></div>\n      </div>\n      <div class=\"pprice\">${price}</div>\n      <div class=\"pinstall\">${installments ? `6x de ${installments} sem juros` : ''}</div>\n      ${colors.length ? `<div class=\"optlabel\">Cores</div><div class=\"opts\">${colors.map(c =>\n        `<div class=\"chip ${c === d2.state.color ? 'on' : ''}\" data-kind=\"color\" data-val=\"${esc(c)}\">${esc(c)}</div>`).join('')}</div>` : ''}\n      ${sizes.length ? `<div class=\"optlabel\">Medidas</div><div class=\"opts\">${sizes.map(sz =>\n        `<div class=\"chip ${sz === d2.state.size ? 'on' : ''}\" data-kind=\"size\" data-val=\"${esc(sz)}\">${esc(sz)}</div>`).join('')}</div>\n        <div class=\"sizeguide act-sizeguide\">Tabela de medidas</div>` : ''}\n      <button class=\"cta\">Provar</button>\n      <div class=\"accordion\">\n        <div class=\"acc-item ${open === 'desc' ? 'open' : ''}\" data-acc=\"desc\">\n          <div class=\"acc-head\">Descrição<span class=\"acc-chev\">&#9660;</span></div>\n          <div class=\"acc-body\">${esc(desc) || 'Sem descrição disponível para este produto.'}</div>\n        </div>\n        <div class=\"acc-item ${open === 'size' ? 'open' : ''}\" data-acc=\"size\">\n          <div class=\"acc-head\">Encontre o seu tamanho<span class=\"acc-chev\">&#9660;</span></div>\n          <div class=\"acc-body\">Guia de medidas não disponível neste protótipo — em produção, viria da mesma API de catálogo da John John.</div>\n        </div>\n      </div>\n    </div>\n  </div>`\n}\n\nfunction renderUpload(d2) {\n  const s = d2.state\n  return `<div class=\"uploadzone\">\n      <input class=\"filepick\" type=\"file\" accept=\"image/*\" style=\"display:none\"/>\n      ${s.uploading\n        ? `<div class=\"ic\"><span class=\"spin\"></span></div><div class=\"t\">Subindo sua foto…</div>`\n        : `<div class=\"ic\">📷</div><div class=\"t\">Suba uma imagem</div><div class=\"s\">Clique pra escolher uma foto sua</div>`}\n    </div>\n    ${s.uploadError ? `<div class=\"empty\">${esc(s.uploadError)}</div>` : ''}\n    <div class=\"instr\"><b>Instruções:</b> foto de corpo inteiro, de frente, com boa iluminação e fundo neutro.\n      Isso melhora o resultado da prova — mas lembre-se: a prova mostra como a peça fica em você, não é medida de tamanho.</div>`\n}\n\nfunction renderResult(d2) {\n  const s = d2.state\n  const p = s.product || {}\n  const price = p.priceRange && p.priceRange.sellingPrice ? d2.fmt.currency(p.priceRange.sellingPrice.lowPrice, 'BRL', { locale: 'pt-BR' }) : ''\n  const colors = variationValues(p, 'Cor')\n  const sizes = variationValues(p, 'Tamanho')\n  const gallery = s.gallery || []\n\n  const img = s.resultUrl || s.userPhoto || ''\n  const loading = s.generating\n    ? `<div class=\"load\"><span class=\"spin\"></span>Analisando a peça e gerando sua prova…</div>` : ''\n  const err = s.genError ? `<div class=\"empty\">${esc(s.genError)}</div>` : ''\n\n  return `<div class=\"rgrid\">\n    <div>\n      <div class=\"rimg\" style=\"background-image:url('${esc(img)}')\">${loading}</div>\n      ${err}\n      <div class=\"actrow\">\n        <div class=\"iconbtn act-refazer\">refazer</div>\n        <div class=\"iconbtn act-trocar\">trocar imagem</div>\n        <div class=\"iconbtn act-feedback\">feedback</div>\n        <div class=\"iconbtn act-share\">share</div>\n      </div>\n      ${gallery.length ? `<div class=\"gallery\">${gallery.map((g, i) =>\n        `<div class=\"gitem ${g.url === s.resultUrl ? 'on' : ''}\" data-idx=\"${i}\" data-key=\"${i}\"\n          style=\"background-image:url('${esc(g.url)}')\" title=\"${esc(g.name)}\"></div>`).join('')}</div>` : ''}\n    </div>\n    <div class=\"panel\">\n      <div>\n        <div class=\"pbrand\">${esc(p.brand || 'John John')}</div>\n        <div class=\"pname\" style=\"font-size:19px\">${esc(p.productName || '')}</div>\n        <div class=\"pprice\">${price}</div>\n      </div>\n      <button class=\"addbag\">Adicionar à sacola</button>\n      ${sizes.length ? `<div><div class=\"optlabel\">Medidas</div><div class=\"opts\">${sizes.map(sz =>\n        `<div class=\"chip ${sz === s.size ? 'on' : ''}\" data-kind=\"size\" data-val=\"${esc(sz)}\">${esc(sz)}</div>`).join('')}</div></div>` : ''}\n      ${colors.length ? `<div><div class=\"optlabel\">Cores</div><div class=\"opts\">${colors.map(c =>\n        `<div class=\"chip ${c === s.color ? 'on' : ''}\" data-kind=\"color\" data-val=\"${esc(c)}\">${esc(c)}</div>`).join('')}</div></div>` : ''}\n      ${renderSuggestions(s)}\n      <button class=\"checkout\">Checkout</button>\n    </div>\n  </div>`\n}\n\nfunction renderSuggestions(s) {\n  if (s.suggestLoading) {\n    return `<div><div class=\"optlabel\">Sugestão complementar de look</div>\n      <div class=\"empty\" style=\"padding:20px 0\"><span class=\"spin\"></span></div></div>`\n  }\n  const picks = (s.suggestions || []).slice(0, 4)\n  if (!picks.length) return ''\n  const extraId = s.lookExtra && s.lookExtra.productId\n  return `<div>\n    <div class=\"optlabel\">Sugestão complementar de look</div>\n    <div class=\"sug\">${picks.map((p, i) => {\n      const img = firstImage(p)\n      const on = p.productId === extraId\n      return `<div class=\"sugcard sugcard-click ${on ? 'on' : ''}\" data-idx=\"${i}\" data-key=\"${esc(p.productId)}\" style=\"padding:0;overflow:hidden;text-align:left;position:relative\">\n        <div class=\"sugcheck\">&#10003;</div>\n        <div style=\"width:100%;aspect-ratio:1;background:#eee;background-image:url('${esc(img)}');background-size:cover;background-position:center\"></div>\n        <div style=\"padding:8px\">${esc(p.productName)}</div>\n      </div>`\n    }).join('')}</div>\n  </div>`\n}\n\nfunction firstImage(p) {\n  return (p && p.items && p.items[0] && p.items[0].images && p.items[0].images[0] && p.items[0].images[0].imageUrl) || ''\n}\n\nfunction allImages(p) {\n  const imgs = (p && p.items && p.items[0] && p.items[0].images) || []\n  return imgs.map((i) => i.imageUrl).filter(Boolean).slice(0, 8)\n}\n\nfunction guessComplementQuery(p) {\n  const text = ((p.categories || []).join(' ') + ' ' + (p.productName || '')).toLowerCase()\n  if (/cal(ç|c)a|saia|short/.test(text)) return 'camisa'\n  if (/vestido/.test(text)) return 'jaqueta'\n  if (/camis|blusa|regata|cropped|casaco|jaqueta|blazer|malha|su[eé]ter|cardigan|top/.test(text)) return 'calça'\n  return 'acessórios'\n}\n\nasync function loadSuggestions(d2) {\n  const p = d2.state.product\n  if (!p) return\n  d2.state.suggestLoading = true\n  try {\n    const base = d2.rush(d2.params.searchApi).url()\n    const q = guessComplementQuery(p)\n    const res = await fetch(base + '?search=' + encodeURIComponent(q))\n    const json = await res.json()\n    const products = (json && json.data && json.data.products) || []\n    const filtered = products.filter((x) => x.productId !== p.productId).slice(0, 4)\n    d2.setState({ suggestions: filtered, suggestLoading: false })\n  } catch (err) {\n    d2.setState({ suggestions: [], suggestLoading: false })\n  }\n}\n\nfunction resolveSkuId(product, color, size) {\n  if (!product) return null\n  const items = product.items || []\n  const match = items.find((it) => {\n    const vals = {}\n    ;(it.variations || []).forEach((v) => { vals[v.name] = (v.values || [])[0] })\n    const colorOk = !color || vals['Cor'] === color\n    const sizeOk = !size || vals['Tamanho'] === size || vals['Tamanho do Produto'] === size\n    return colorOk && sizeOk\n  })\n  return (match && match.itemId) || (items[0] && items[0].itemId) || null\n}\n\nfunction variationValues(product, name) {\n  const aliases = name === 'Tamanho' ? ['Tamanho', 'Tamanho do Produto'] : [name]\n  const set = new Set()\n  ;(product.items || []).forEach((it) => {\n    (it.variations || []).forEach((v) => { if (aliases.indexOf(v.name) > -1) (v.values || []).forEach((val) => set.add(val)) })\n  })\n  return Array.from(set)\n}\n\nasync function runSearch(d2) {\n  const input = d2.$('.searchbar input')\n  const q = (input && input.value || '').trim()\n  if (!q) return\n  d2.setState({ loadingSearch: true, searchError: '', query: q, searched: true })\n  try {\n    const base = d2.rush(d2.params.searchApi).url()\n    const res = await fetch(base + '?search=' + encodeURIComponent(q))\n    if (!res.ok) throw new Error('HTTP ' + res.status)\n    const json = await res.json()\n    const products = (json && json.data && json.data.products) || []\n    d2.setState({ results: products, loadingSearch: false })\n  } catch (err) {\n    d2.setState({ loadingSearch: false, searchError: 'Busca falhou: ' + (err && err.message ? err.message : 'erro') })\n  }\n}\n\nasync function analyzeGarment(d2, imgUrls, productName) {\n  try {\n    const base = d2.rush(d2.params.analyzeApi).url()\n    const res = await fetch(base, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ imageUrls: imgUrls, productName }),\n    })\n    const json = await res.json()\n    const result = (json && json.data) || json\n    if (!result || !result.garment_type || !result.body_zone) return null\n    const idx = Number(result.best_image_index)\n    const chosenUrl = (Number.isInteger(idx) && imgUrls[idx]) ? imgUrls[idx] : imgUrls[0]\n    return { ...result, imageUrl: chosenUrl }\n  } catch (err) {\n    return null\n  }\n}\n\nfunction zoneOf(a) { return (a && a.body_zone) || 'garment area' }\nfunction labelOf(a) { return (a && a.garment_type) || 'garment' }\nfunction othersOf(a) {\n  const v = a && a.other_items_in_photo ? String(a.other_items_in_photo).trim() : ''\n  return (!v || /^none$/i.test(v)) ? '' : v\n}\n\nfunction buildTryOnPrompt(analysis, extraAnalysis) {\n  const zone = zoneOf(analysis)\n  const label = labelOf(analysis)\n  const others = othersOf(analysis)\n  const hasExtra = !!extraAnalysis\n  const exZone = zoneOf(extraAnalysis)\n  const exLabel = labelOf(extraAnalysis)\n  const exOthers = othersOf(extraAnalysis)\n\n  const scopeSection = `\n# PRODUCT SCOPE — Image 2\nThe product being sold in Image 2 is specifically: ${label}, covering the body zone: ${zone}.${others ? ` Image 2 also shows the model wearing other items that are NOT the product: ${others} — this is catalog styling only, IGNORE it completely and never transfer it onto Image 1.` : ''}\nONLY replace the ${zone} of the Image 1 subject with this garment. If the Image 1 subject wears anything outside the ${zone} (e.g. a top, jacket, shoes, accessories not covered by \"${zone}\"), KEEP IT EXACTLY AS IN IMAGE 1 — unchanged, not removed, not altered. Do NOT dress the subject in a full new outfit — change only this one garment.\nCRITICAL — do not confuse PHOTO FRAMING with GARMENT LENGTH: Image 2 may be a close, cropped photograph (e.g. framed from the waist up, or a tight torso shot) that simply cuts off before showing the garment's actual hem. That photographic crop is NOT evidence the garment is cropped/short. Never shorten, crop, or turn the garment into a cropped/crop-top style just because the reference photo's frame ends there — reproduce the garment's real cut (length, hem) as a full-length, non-cropped product photo, and only shorten it if the garment is unambiguously and visibly a cropped design in an uncropped, full-torso reference photo.`\n\n  const extraSection = hasExtra ? `\n\n# ADDITIONAL GARMENT — Image 3\nThe product shown in Image 3 is: ${exLabel}, covering the body zone: ${exZone}.${exOthers ? ` It also shows other styling items that are NOT the product: ${exOthers} — ignore those too.` : ''} Apply the same reference-boundary rules as Image 2: extract ONLY the garment itself, ignore the identity, body, and pose of whoever wears it in Image 3. Combine it with the Image 2 garment on the Image 1 subject as one complete look — each garment covering only its own body zone (${zone} from Image 2, ${exZone} from Image 3), without either one hiding or distorting the other.` : ''\n\n  const removePhrase = hasExtra ? `the ${label} (in the ${zone}) and the ${exLabel} (in the ${exZone})` : `the ${label} (in the ${zone})`\n  const replacePhrase = hasExtra ? `the exact products identified above` : `the exact garment from Image 2`\n\n  return `Replace ${hasExtra ? 'two specific garments' : 'one specific garment'} on the person in Image 1, using Image 2${hasExtra ? ' and Image 3' : ''} as product reference${hasExtra ? 's' : ''}.\n${scopeSection}${extraSection}\n\n# SUBJECT — Image 1\nImage 1 shows a real customer. This is the ONLY person who may appear in the result. Preserve their face, identity, skin tone, body proportions, pose, hands, hair, background, lighting and framing EXACTLY as in Image 1 — same aspect ratio, same field of view, same camera distance, same crop. Do not zoom in, crop, or recompose the scene. Every part of the subject visible in Image 1 (head, face, hands, feet) must remain fully visible and in the same position in the result. A head, face, or limb cut off by the output frame is a FAILURE.\n\n# IMAGE 2${hasExtra ? ' / IMAGE 3' : ''} — REFERENCE BOUNDARIES\nImage 2${hasExtra ? ' and Image 3 are' : ' is a'} catalog product photo${hasExtra ? 's' : ''} showing DIFFERENT people (store models). ${hasExtra ? 'They exist' : 'It exists'} ONLY as a reference for each garment's color, pattern, fabric, and structural details (collar, closure, pockets, hem, cuffs, sleeve length) — within the body zone identified above, nothing more. The model(s) shown must NOT appear in the result in any way — not their face, body, pose, skin tone, or background. Never adopt the framing, crop, or lighting of the reference photo(s). Do not blend or morph the identity of the person in Image 1 with any reference model — the output subject is Image 1's person, full stop.\n\n# STEPS\n1. Completely remove ${removePhrase} currently worn by the subject in Image 1 — no color, texture, or fabric from the original garment(s) may bleed into the replacement. Everything outside these zones stays untouched.\n2. Replace with ${replacePhrase} — matching color, pattern, texture, and structural details precisely.\n3. Render every replaced garment in its natural default worn state: long sleeves at full length to the wrist (never rolled, pushed up, or shortened), buttons/closures in a natural resting position, collars flat. Ignore any styling choices from the catalog photo(s) — those are catalog styling, not the garment's design.\n4. Drape each garment naturally over the subject's actual body shape and pose from Image 1 — do not reshape, slim, or resize the subject's body to match the reference model(s).\n\n# SELF-CHECK before finalizing — answer NO to all of these, or the result is wrong\n- Does any part of a reference model (face, body, skin tone) appear in the result?\n- Is the subject's face, body, pose, or background changed from Image 1?\n- Is the output cropped, zoomed, or reframed compared to Image 1?\n- Does any replaced garment still show color or texture from the subject's original clothing?\n- Are the sleeves rolled, pushed up, or shortened on a long-sleeve garment?\n- Did anything OUTSIDE the identified body zone(s) get changed from Image 1 (e.g. a top, jacket, or shoes that are not part of the product)?\n\nResult must be a single seamless photorealistic photograph of the Image 1 subject wearing ${hasExtra ? 'both identified products' : 'the identified product'}, with everything else identical to Image 1.`\n}\n\nasync function generate(d2) {\n  const s = d2.state\n  const p = s.product\n  const candidateImgs = allImages(p)\n  if (!s.userPhoto || !candidateImgs.length) return\n  const extra = s.lookExtra\n  const extraCandidateImgs = extra ? allImages(extra) : []\n  d2.setState({ screen: 'result', generating: true, genError: '', resultUrl: '' })\n  try {\n    const analysis = await analyzeGarment(d2, candidateImgs, p.productName)\n    const extraAnalysis = extraCandidateImgs.length ? await analyzeGarment(d2, extraCandidateImgs, extra.productName) : null\n    const garmentImg = (analysis && analysis.imageUrl) || candidateImgs[0]\n    const extraImg = extraAnalysis ? extraAnalysis.imageUrl : ''\n    const prompt = buildTryOnPrompt(analysis, extraAnalysis)\n    const images = [s.userPhoto, garmentImg]\n    if (extraImg) images.push(extraImg)\n    const a = d2.assistant(d2.params.drawAssistant)\n    const out = await a.draw({ prompt, images, options: { quantity: 1 } })\n    const url = out && out.data && out.data[0] && out.data[0].url\n    if (!url) throw new Error('sem imagem retornada')\n    const name = p.productName + (extra ? ' + ' + extra.productName : '')\n    const gallery = [{ url, name, garment: garmentImg }, ...(s.gallery || [])].slice(0, 8)\n    d2.setState({ resultUrl: url, generating: false, gallery })\n    if (!d2.state.suggestions || !d2.state.suggestions.length) loadSuggestions(d2)\n  } catch (err) {\n    d2.setState({ generating: false, genError: 'Geração falhou: ' + (err && err.message ? err.message : 'erro') })\n  }\n}\n\nfunction flashToast(d2, msg) {\n  d2.state.toast = msg\n  clearTimeout(flashToast._t)\n  flashToast._t = setTimeout(() => { d2.state.toast = '' }, 2600)\n}\n\nfunction htmlToText(html) {\n  if (!html) return ''\n  const div = document.createElement('div')\n  div.innerHTML = String(html)\n  return (div.textContent || '').replace(/\\s+/g, ' ').trim()\n}\n\nfunction esc(s) {\n  return String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n}\n"}},"searchApi":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"searchApi"}}}},"drawAssistant":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"drawAssistant"}}}},"uploadDrive":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"uploadDrive"}}}},"analyzeApi":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"analyzeApi"}}}}}}}}}},{"_id":"6ab3d7501a04d8166dcff3c7","component":"data2-core-types@Component","system":"698a0c028a310c894be98bc8","params":{"extends":"data2-core-primitives@Block","component":"tryon-test-lab","package":"veste-app","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n:host{display:block;width:100%;height:100%}\n.wrap{\n  --paper:#F7F7F5; --ink:#0a0a0a; --muted:#6b6b6b; --linha:#e2e2e2; --card:#fff;\n  --ok:#1f7a3d; --bad:#b3261e;\n  width:100%;height:100%;overflow-y:auto;background:var(--paper);color:var(--ink);\n  font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue',Helvetica,Arial,sans-serif;\n  box-sizing:border-box;\n}\n*{box-sizing:border-box}\n.body{padding:clamp(16px,3vw,36px);max-width:1200px;margin:0 auto}\n.hdr{display:flex;align-items:baseline;gap:10px;margin-bottom:4px}\n.hdr h1{font-size:18px;font-weight:700;margin:0}\n.hdr span{font-size:12px;color:var(--muted)}\n.sub{font-size:12.5px;color:var(--muted);margin-bottom:24px;line-height:1.5;max-width:70ch}\n.section{background:var(--card);border:1px solid var(--linha);border-radius:12px;padding:18px;margin-bottom:16px}\n.section h2{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin:0 0 12px;font-weight:700}\n\n.photorow{display:flex;gap:16px;align-items:center;flex-wrap:wrap}\n.photothumb{width:88px;height:112px;border-radius:8px;background:#eee;background-size:cover;background-position:center;border:1px solid var(--linha);flex:none}\n.uploadzone{border:2px dashed var(--linha);border-radius:10px;padding:20px;text-align:center;cursor:pointer;\n  font-size:13px;color:var(--muted);flex:1;min-width:200px}\n.uploadzone:hover{border-color:#999}\n.uploadzone.drag{border-color:var(--ink);background:#f2f2f2}\n.smalllink{font-size:12px;color:var(--ink);text-decoration:underline;cursor:pointer}\n\n.searchbar{display:flex;gap:8px;margin-bottom:14px}\n.searchbar input{flex:1;padding:10px 12px;border:1px solid var(--linha);border-radius:8px;font-size:14px}\n.searchbar button{padding:0 18px;border:0;border-radius:8px;background:var(--ink);color:#fff;font-size:13px;cursor:pointer}\n.searchbar button:disabled{opacity:.5}\n.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:10px}\n.gcard{position:relative;border:2px solid var(--linha);border-radius:10px;overflow:hidden;cursor:pointer;background:#fff}\n.gcard.selected{border-color:var(--ink)}\n.gcard.disabled{opacity:.35;cursor:not-allowed}\n.gcard .ph{width:100%;aspect-ratio:3/4;background:#eee;background-size:cover;background-position:center}\n.gcard .nm{font-size:10.5px;padding:6px 8px;line-height:1.3;min-height:30px}\n.gcard .catpill{position:absolute;top:6px;left:6px;background:rgba(0,0,0,.65);color:#fff;font-size:9px;\n  letter-spacing:.05em;text-transform:uppercase;padding:2px 6px;border-radius:999px}\n.gcard .check{position:absolute;top:6px;right:6px;width:20px;height:20px;border-radius:999px;background:var(--ink);\n  color:#fff;display:none;align-items:center;justify-content:center;font-size:12px}\n.gcard.selected .check{display:flex}\n.empty{padding:30px 0;text-align:center;color:var(--muted);font-size:13px}\n.spin{display:inline-block;width:14px;height:14px;border:2px solid rgba(0,0,0,.15);border-top-color:var(--ink);\n  border-radius:50%;animation:sp .7s linear infinite;vertical-align:-2px}\n@keyframes sp{to{transform:rotate(360deg)}}\n\n.selrow{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:14px}\n.selchip{display:flex;align-items:center;gap:8px;border:1px solid var(--linha);border-radius:999px;padding:4px 12px 4px 4px;font-size:12.5px}\n.selchip img{width:26px;height:26px;border-radius:999px;object-fit:cover}\n.selchip .x{cursor:pointer;color:var(--muted);font-weight:700}\n.testbtn{padding:12px 22px;border:0;border-radius:8px;background:var(--ink);color:#fff;font-size:13.5px;\n  font-weight:600;cursor:pointer}\n.testbtn:disabled{opacity:.4;cursor:default}\n\n.resultgrid{display:grid;grid-template-columns:340px 1fr;gap:22px}\n@media(max-width:700px){.resultgrid{grid-template-columns:1fr}}\n.rimg{width:100%;aspect-ratio:3/4;border-radius:10px;background:#eee;background-size:cover;background-position:center;\n  position:relative;overflow:hidden}\n.rimg .load{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:8px;\n  background:rgba(247,247,245,.9);font-size:12.5px;color:var(--muted)}\n.verdictrow{display:flex;gap:10px;margin-top:14px}\n.vbtn{flex:1;padding:12px;border-radius:8px;border:1.5px solid var(--linha);background:#fff;font-size:13.5px;\n  font-weight:600;cursor:pointer}\n.vbtn.ok{border-color:var(--ok);color:var(--ok)}\n.vbtn.bad{border-color:var(--bad);color:var(--bad)}\n.notebox{margin-top:10px}\n.notebox textarea{width:100%;min-height:70px;border:1px solid var(--linha);border-radius:8px;padding:10px;font-size:13px;\n  font-family:inherit;resize:vertical}\n.notebox button{margin-top:8px;padding:9px 16px;border:0;border-radius:8px;background:var(--bad);color:#fff;\n  font-size:13px;cursor:pointer}\n.debugbox{margin-top:16px;font-size:11.5px;color:var(--muted);background:#fafafa;border:1px solid var(--linha);\n  border-radius:8px;padding:10px;line-height:1.6;white-space:pre-wrap}\n.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);background:var(--ink);color:#fff;\n  padding:12px 20px;border-radius:999px;font-size:13px;z-index:50;box-shadow:0 10px 30px rgba(0,0,0,.25)}\n`,\n\n  render(d2) {\n    const s = d2.state\n    const photoRow = `<div class=\"photorow\">\n      ${s.testPhoto ? `<div class=\"photothumb\" style=\"background-image:url('${esc(s.testPhoto)}')\"></div>` : ''}\n      <div class=\"uploadzone ${s.dragging ? 'drag' : ''}\">\n        <input class=\"filepick\" type=\"file\" accept=\"image/*\" style=\"display:none\"/>\n        ${s.uploading ? `<span class=\"spin\"></span> subindo…` : (s.testPhoto ? 'Trocar a foto de teste' : 'Clique ou arraste uma foto de teste aqui')}\n      </div>\n    </div>\n    ${s.uploadError ? `<div class=\"empty\">${esc(s.uploadError)}</div>` : ''}`\n\n    let searchBlock\n    if (s.loadingSearch) {\n      searchBlock = `<div class=\"empty\"><span class=\"spin\"></span> buscando…</div>`\n    } else if (s.searchError) {\n      searchBlock = `<div class=\"empty\">${esc(s.searchError)}</div>`\n    } else if (!(s.results || []).length) {\n      searchBlock = `<div class=\"empty\">${s.searched ? 'Nada encontrado.' : 'Busque uma peça (ex: \"blusa\", \"calça\").'}</div>`\n    } else {\n      const sel = s.selected || []\n      searchBlock = `<div class=\"grid\">${s.results.map((p, i) => {\n        const img = firstImage(p)\n        const cat = classify(p)\n        const isSel = sel.some((x) => x.productId === p.productId)\n        const disabled = !isSel && !canAdd(sel, p)\n        return `<div class=\"gcard ${isSel ? 'selected' : ''} ${disabled ? 'disabled' : ''}\" data-idx=\"${i}\" data-key=\"${esc(p.productId || i)}\">\n          <div class=\"catpill\">${cat}</div>\n          <div class=\"check\">&#10003;</div>\n          <div class=\"ph\" style=\"background-image:url('${esc(img)}')\"></div>\n          <div class=\"nm\">${esc(p.productName)}</div>\n        </div>`\n      }).join('')}</div>`\n    }\n\n    const sel = s.selected || []\n    const selRow = sel.length ? `<div class=\"selrow\">${sel.map((p, i) =>\n      `<div class=\"selchip\"><img src=\"${esc(firstImage(p))}\"/>${esc(p.productName)}<span class=\"x\" data-idx=\"${i}\">&times;</span></div>`\n    ).join('')}\n      <button class=\"testbtn\" ${(!s.testPhoto || !sel.length || s.testing) ? 'disabled' : ''}>${s.testing ? 'Testando…' : 'Testar combinação'}</button>\n    </div>` : `<div class=\"sub\">Selecione 1 peça, ou 2 compatíveis (blusa + calça), pra testar.</div>`\n\n    let resultBlock = ''\n    if (s.testing || s.resultUrl || s.genError) {\n      const loading = s.testing ? `<div class=\"load\"><span class=\"spin\"></span>&nbsp;Analisando e gerando…</div>` : ''\n      const img = s.resultUrl || s.testPhoto || ''\n      const err = s.genError ? `<div class=\"empty\">${esc(s.genError)}</div>` : ''\n      const verdict = (s.resultUrl && !s.testing) ? `<div class=\"verdictrow\">\n          <button class=\"vbtn ok act-ok\">✅ Sucesso</button>\n          <button class=\"vbtn bad act-bad\">❌ Problema</button>\n        </div>\n        ${s.showNote ? `<div class=\"notebox\">\n          <textarea placeholder=\"O que saiu errado? (opcional, mas ajuda muito)\">${esc(s.noteDraft || '')}</textarea>\n          <button class=\"act-sendbad\">Registrar problema</button>\n        </div>` : ''}\n        ${s.reported ? `<div class=\"sub\" style=\"color:var(--ok);margin-top:8px\">Registrado — obrigado!</div>` : ''}` : ''\n      const debug = (s.lastAnalyses && s.lastAnalyses.length) ? `<div class=\"debugbox\">${s.lastAnalyses.map((a, i) =>\n        `#${i + 1}: ${esc(a.garment_type)} · zona: ${esc(a.body_zone)} · outros na foto: ${esc(a.other_items_in_photo || 'none')}\\nimagem usada: ${esc(a.imageUrl)}`\n      ).join('\\n\\n')}</div>` : ''\n      resultBlock = `<div class=\"section\"><h2>Resultado</h2>\n        <div class=\"resultgrid\">\n          <div class=\"rimg\" style=\"background-image:url('${esc(img)}')\">${loading}</div>\n          <div>${err}${verdict}${debug}</div>\n        </div>\n      </div>`\n    }\n\n    const toast = s.toast ? `<div class=\"toast\">${esc(s.toast)}</div>` : ''\n\n    return `<div class=\"wrap\"><div class=\"body\">\n      <div class=\"hdr\"><h1>Provador · Test Lab</h1><span>uso interno — não é a experiência do cliente</span></div>\n      <div class=\"sub\">Suba uma foto de teste, escolha 1 ou 2 peças compatíveis (blusa + calça), gere a prova e reporte se ficou bom ou não. Todo problema reportado fica salvo pra gente melhorar o pipeline.</div>\n      <div class=\"section\"><h2>1 · Foto de teste</h2>${photoRow}</div>\n      <div class=\"section\"><h2>2 · Escolher peça(s)</h2>\n        <div class=\"searchbar\">\n          <input type=\"text\" placeholder=\"Buscar produto…\" value=\"${esc(s.query || '')}\"/>\n          <button class=\"go\" ${s.loadingSearch ? 'disabled' : ''}>Buscar</button>\n        </div>\n        ${searchBlock}\n        <div style=\"margin-top:14px\">${selRow}</div>\n      </div>\n      ${resultBlock}\n    </div></div>${toast}`\n  },\n\n  mounted(d2) {\n    d2.on('.searchbar input', 'keydown', (e) => { if (e.key === 'Enter') runSearch(d2) })\n    d2.on('.go', 'click', () => runSearch(d2))\n\n    d2.on('.uploadzone', 'click', () => { d2.$('.filepick')?.click() })\n    d2.on('.filepick', 'change', (e, el) => { doUpload(d2, el.files && el.files[0]) })\n    d2.on('.uploadzone', 'dragover', (e, el) => { e.preventDefault(); d2.state.dragging = true })\n    d2.on('.uploadzone', 'dragleave', () => { d2.state.dragging = false })\n    d2.on('.uploadzone', 'drop', (e, el) => {\n      e.preventDefault(); d2.state.dragging = false\n      const file = e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files[0]\n      doUpload(d2, file)\n    })\n\n    d2.on('.gcard', 'click', (e, el) => {\n      if (el.classList.contains('disabled')) return\n      const idx = Number(el.dataset.idx)\n      const p = (d2.state.results || [])[idx]\n      if (!p) return\n      const sel = d2.state.selected || []\n      const already = sel.findIndex((x) => x.productId === p.productId)\n      if (already > -1) {\n        d2.state.selected = sel.filter((_, i) => i !== already)\n      } else if (canAdd(sel, p)) {\n        d2.state.selected = [...sel, p]\n      } else {\n        flashToast(d2, sel.length >= 2 ? 'Já tem 2 peças — remova uma pra trocar.' : 'Só dá pra combinar peças compatíveis (blusa + calça).')\n      }\n    })\n    d2.on('.selchip .x', 'click', (e, el) => {\n      const idx = Number(el.dataset.idx)\n      d2.state.selected = (d2.state.selected || []).filter((_, i) => i !== idx)\n    })\n\n    d2.on('.testbtn', 'click', () => runTest(d2))\n    d2.on('.act-ok', 'click', () => report(d2, 'sucesso', ''))\n    d2.on('.act-bad', 'click', () => { d2.state.showNote = true })\n    d2.on('.act-sendbad', 'click', (e, el) => {\n      const ta = el.parentElement.querySelector('textarea')\n      report(d2, 'problema', ta ? ta.value : '')\n    })\n  },\n}\n\nfunction firstImage(p) {\n  return (p && p.items && p.items[0] && p.items[0].images && p.items[0].images[0] && p.items[0].images[0].imageUrl) || ''\n}\n\nfunction allImages(p) {\n  const imgs = (p && p.items && p.items[0] && p.items[0].images) || []\n  return imgs.map((i) => i.imageUrl).filter(Boolean).slice(0, 8)\n}\n\nfunction classify(p) {\n  const text = ((p.categories || []).join(' ') + ' ' + (p.productName || '')).toLowerCase()\n  if (/vestido/.test(text)) return 'vestido'\n  if (/cal(ç|c)a|saia|short|bermuda/.test(text)) return 'bottom'\n  if (/camis|blusa|regata|cropped|malha|su[eé]ter|cardigan/.test(text)) return 'top'\n  if (/jaqueta|casaco|blazer/.test(text)) return 'outerwear'\n  return 'other'\n}\n\nfunction canAdd(selected, candidate) {\n  if (selected.length === 0) return true\n  if (selected.length >= 2) return false\n  const a = classify(selected[0])\n  const b = classify(candidate)\n  const pair = [a, b].sort().join('+')\n  return pair === 'bottom+top'\n}\n\nasync function runSearch(d2) {\n  const input = d2.$('.searchbar input')\n  const q = (input && input.value || '').trim()\n  if (!q) return\n  d2.setState({ loadingSearch: true, searchError: '', query: q, searched: true })\n  try {\n    const base = d2.rush(d2.params.searchApi).url()\n    const res = await fetch(base + '?search=' + encodeURIComponent(q))\n    if (!res.ok) throw new Error('HTTP ' + res.status)\n    const json = await res.json()\n    const products = (json && json.data && json.data.products) || []\n    d2.setState({ results: products, loadingSearch: false })\n  } catch (err) {\n    d2.setState({ loadingSearch: false, searchError: 'Busca falhou: ' + (err && err.message ? err.message : 'erro') })\n  }\n}\n\nasync function doUpload(d2, file) {\n  if (!file) return\n  d2.state.uploading = true\n  d2.state.uploadError = ''\n  try {\n    const out = await d2.drive(d2.params.uploadDrive).upload([file])\n    const url = out && out[0] && out[0].fileUrl\n    if (!url) throw new Error('upload sem retorno')\n    d2.setState({ testPhoto: url, uploading: false })\n  } catch (err) {\n    d2.setState({ uploading: false, uploadError: 'Falha no upload: ' + (err && err.message ? err.message : 'erro') })\n  }\n}\n\nasync function analyzeGarment(d2, imgUrls, productName) {\n  try {\n    const base = d2.rush(d2.params.analyzeApi).url()\n    const res = await fetch(base, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ imageUrls: imgUrls, productName }),\n    })\n    const json = await res.json()\n    const result = (json && json.data) || json\n    if (!result || !result.garment_type || !result.body_zone) return null\n    const idx = Number(result.best_image_index)\n    const chosenUrl = (Number.isInteger(idx) && imgUrls[idx]) ? imgUrls[idx] : imgUrls[0]\n    return { ...result, imageUrl: chosenUrl }\n  } catch (err) {\n    return null\n  }\n}\n\nfunction zoneOf(a) { return (a && a.body_zone) || 'garment area' }\nfunction labelOf(a) { return (a && a.garment_type) || 'garment' }\nfunction othersOf(a) {\n  const v = a && a.other_items_in_photo ? String(a.other_items_in_photo).trim() : ''\n  return (!v || /^none$/i.test(v)) ? '' : v\n}\n\nfunction buildTryOnPrompt(analysis, extraAnalysis) {\n  const zone = zoneOf(analysis)\n  const label = labelOf(analysis)\n  const others = othersOf(analysis)\n  const hasExtra = !!extraAnalysis\n  const exZone = zoneOf(extraAnalysis)\n  const exLabel = labelOf(extraAnalysis)\n  const exOthers = othersOf(extraAnalysis)\n\n  const scopeSection = `\n# PRODUCT SCOPE — Image 2\nThe product being sold in Image 2 is specifically: ${label}, covering the body zone: ${zone}.${others ? ` Image 2 also shows the model wearing other items that are NOT the product: ${others} — this is catalog styling only, IGNORE it completely and never transfer it onto Image 1.` : ''}\nONLY replace the ${zone} of the Image 1 subject with this garment. If the Image 1 subject wears anything outside the ${zone} (e.g. a top, jacket, shoes, accessories not covered by \"${zone}\"), KEEP IT EXACTLY AS IN IMAGE 1 — unchanged, not removed, not altered. Do NOT dress the subject in a full new outfit — change only this one garment.\nCRITICAL — do not confuse PHOTO FRAMING with GARMENT LENGTH: Image 2 may be a close, cropped photograph (e.g. framed from the waist up, or a tight torso shot) that simply cuts off before showing the garment's actual hem. That photographic crop is NOT evidence the garment is cropped/short. Never shorten, crop, or turn the garment into a cropped/crop-top style just because the reference photo's frame ends there — reproduce the garment's real cut (length, hem) as a full-length, non-cropped product photo, and only shorten it if the garment is unambiguously and visibly a cropped design in an uncropped, full-torso reference photo.`\n\n  const extraSection = hasExtra ? `\n\n# ADDITIONAL GARMENT — Image 3\nThe product shown in Image 3 is: ${exLabel}, covering the body zone: ${exZone}.${exOthers ? ` It also shows other styling items that are NOT the product: ${exOthers} — ignore those too.` : ''} Apply the same reference-boundary rules as Image 2: extract ONLY the garment itself, ignore the identity, body, and pose of whoever wears it in Image 3. Combine it with the Image 2 garment on the Image 1 subject as one complete look — each garment covering only its own body zone (${zone} from Image 2, ${exZone} from Image 3), without either one hiding or distorting the other.` : ''\n\n  const removePhrase = hasExtra ? `the ${label} (in the ${zone}) and the ${exLabel} (in the ${exZone})` : `the ${label} (in the ${zone})`\n  const replacePhrase = hasExtra ? `the exact products identified above` : `the exact garment from Image 2`\n\n  return `Replace ${hasExtra ? 'two specific garments' : 'one specific garment'} on the person in Image 1, using Image 2${hasExtra ? ' and Image 3' : ''} as product reference${hasExtra ? 's' : ''}.\n${scopeSection}${extraSection}\n\n# SUBJECT — Image 1\nImage 1 shows a real customer. This is the ONLY person who may appear in the result. Preserve their face, identity, skin tone, body proportions, pose, hands, hair, background, lighting and framing EXACTLY as in Image 1 — same aspect ratio, same field of view, same camera distance, same crop. Do not zoom in, crop, or recompose the scene. Every part of the subject visible in Image 1 (head, face, hands, feet) must remain fully visible and in the same position in the result. A head, face, or limb cut off by the output frame is a FAILURE.\n\n# IMAGE 2${hasExtra ? ' / IMAGE 3' : ''} — REFERENCE BOUNDARIES\nImage 2${hasExtra ? ' and Image 3 are' : ' is a'} catalog product photo${hasExtra ? 's' : ''} showing DIFFERENT people (store models). ${hasExtra ? 'They exist' : 'It exists'} ONLY as a reference for each garment's color, pattern, fabric, and structural details (collar, closure, pockets, hem, cuffs, sleeve length) — within the body zone identified above, nothing more. The model(s) shown must NOT appear in the result in any way — not their face, body, pose, skin tone, or background. Never adopt the framing, crop, or lighting of the reference photo(s). Do not blend or morph the identity of the person in Image 1 with any reference model — the output subject is Image 1's person, full stop.\n\n# STEPS\n1. Completely remove ${removePhrase} currently worn by the subject in Image 1 — no color, texture, or fabric from the original garment(s) may bleed into the replacement. Everything outside these zones stays untouched.\n2. Replace with ${replacePhrase} — matching color, pattern, texture, and structural details precisely.\n3. Render every replaced garment in its natural default worn state: long sleeves at full length to the wrist (never rolled, pushed up, or shortened), buttons/closures in a natural resting position, collars flat. Ignore any styling choices from the catalog photo(s) — those are catalog styling, not the garment's design.\n4. Drape each garment naturally over the subject's actual body shape and pose from Image 1 — do not reshape, slim, or resize the subject's body to match the reference model(s).\n\n# SELF-CHECK before finalizing — answer NO to all of these, or the result is wrong\n- Does any part of a reference model (face, body, skin tone) appear in the result?\n- Is the subject's face, body, pose, or background changed from Image 1?\n- Is the output cropped, zoomed, or reframed compared to Image 1?\n- Does any replaced garment still show color or texture from the subject's original clothing?\n- Are the sleeves rolled, pushed up, or shortened on a long-sleeve garment?\n- Did anything OUTSIDE the identified body zone(s) get changed from Image 1 (e.g. a top, jacket, or shoes that are not part of the product)?\n\nResult must be a single seamless photorealistic photograph of the Image 1 subject wearing ${hasExtra ? 'both identified products' : 'the identified product'}, with everything else identical to Image 1.`\n}\n\nasync function runTest(d2) {\n  const s = d2.state\n  const sel = s.selected || []\n  if (!s.testPhoto || !sel.length) return\n  d2.setState({ testing: true, resultUrl: '', genError: '', reported: false, showNote: false, noteDraft: '' })\n  try {\n    const analyses = []\n    for (const p of sel) {\n      const imgs = allImages(p)\n      const a = await analyzeGarment(d2, imgs, p.productName)\n      analyses.push(a || { garment_type: p.productName, body_zone: 'garment area', other_items_in_photo: '', imageUrl: imgs[0] })\n    }\n    const prompt = buildTryOnPrompt(analyses[0], analyses[1] || null)\n    const images = [s.testPhoto, ...analyses.map((a) => a.imageUrl)]\n    const assistant = d2.assistant(d2.params.drawAssistant)\n    const out = await assistant.draw({ prompt, images, options: { quantity: 1 } })\n    const url = out && out.data && out.data[0] && out.data[0].url\n    if (!url) throw new Error('sem imagem retornada')\n    d2.setState({ resultUrl: url, testing: false, lastAnalyses: analyses })\n  } catch (err) {\n    d2.setState({ testing: false, genError: 'Falhou: ' + (err && err.message ? err.message : 'erro') })\n  }\n}\n\nasync function hostGeneratedImage(d2, dataUri) {\n  if (!dataUri || !dataUri.startsWith('data:')) return dataUri\n  try {\n    const [meta, b64] = dataUri.split(',')\n    const bin = atob(b64)\n    const bytes = new Uint8Array(bin.length)\n    for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i)\n    const type = (meta.match(/data:(.*?);/) || [])[1] || 'image/png'\n    const file = new File([bytes], `tryon-${Date.now()}.png`, { type })\n    const out = await d2.drive(d2.params.uploadDrive).upload([file])\n    return (out && out[0] && out[0].fileUrl) || dataUri\n  } catch (err) {\n    return dataUri\n  }\n}\n\nasync function report(d2, verdict, note) {\n  const s = d2.state\n  const sel = s.selected || []\n  try {\n    const hostedResultUrl = await hostGeneratedImage(d2, s.resultUrl)\n    await d2.data('feedbackDs').create({\n      verdict,\n      note: note || '',\n      productNames: sel.map((p) => p.productName).join(' + '),\n      productIds: sel.map((p) => p.productId).join(','),\n      categories: sel.map(classify).join('+'),\n      userPhotoUrl: s.testPhoto,\n      resultImageUrl: hostedResultUrl,\n      referenceImagesUsed: (s.lastAnalyses || []).map((a) => a.imageUrl).join(', '),\n      analysisJson: JSON.stringify(s.lastAnalyses || []),\n      testedAt: new Date().toISOString(),\n    })\n    d2.setState({ reported: true, showNote: false })\n    flashToast(d2, verdict === 'sucesso' ? 'Sucesso registrado!' : 'Problema registrado — obrigado!')\n  } catch (err) {\n    flashToast(d2, 'Falha ao registrar: ' + (err && err.message ? err.message : 'erro'))\n  }\n}\n\nfunction flashToast(d2, msg) {\n  d2.state.toast = msg\n  clearTimeout(flashToast._t)\n  flashToast._t = setTimeout(() => { d2.state.toast = '' }, 2600)\n}\n\nfunction esc(s) {\n  return String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n}\n"}},"searchApi":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"searchApi"}}}},"analyzeApi":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"analyzeApi"}}}},"drawAssistant":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"drawAssistant"}}}},"uploadDrive":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"uploadDrive"}}}},"feedbackDs":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"feedbackDs"}}}}}}}}}}]}},{"reference":"ExternalComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"_id":"5f060d9b1ca96def42f3c40a","displayName":"Builder AuthStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"credentials":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"verifier":{"component":"data2-core-types@DataSetReference","params":{"reference":"UsersDataSet"}},"sessionShared":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},"email":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"nR6Q9d7qdaPtZhJ28Q8Dy"},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"yPCJBTKo8q1Mw0B_3Kpwl"},"component":"data2-core-types@ArtboardReference"}}},"session":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"name"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"sessionMetadata":{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},{"params":{"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"active"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.status"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is active user"}]},"component":"data2-core-logical-operators@And","displayName":"is active and has _id"}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $user"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-primitives@String","params":{"content":"@data2.app"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.email"}}}}},"component":"data2-core-functions@Includes","displayName":"isData2User"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}},"component":"data2-core-flow@Step"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.d2_app"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"management"}}]},"component":"data2-core-functions@Includes","displayName":"isData2App Exception"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}},"component":"data2-core-flow@Step"},{"params":{"resultName":{"component":"data2-core-primitives@String","params":{"content":"has_access"}},"action":{"params":{"compare":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}}},{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}}}]},"component":"data2-core-logical-operators@Or"},"else":{"params":{"actions":[{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $metadata.system"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":"filter","args":[{"_id":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records.length"}}}}},"component":"data2-core-logical-operators@Not","displayName":"systems not found"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check system found"},{"params":{"actions":[{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"organization":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"cursor.current.organization._id"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"}]},"component":"data2-core-flow@Parallel"}]},"component":"data2-core-flow@Series","displayName":"common setup"},{"params":{"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"},"else":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"compare":{"params":{"components":{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"mapper":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"system"}}],"body":{"params":{"expression":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.visibility"}}}},"defaultCase":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"cases":[{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"public"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"billing-owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}},{"component":"data2-core-primitives@String","params":{"content":"member"}}]},"component":"data2-core-functions@Includes","displayName":"has role with access"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"collaborator"}}},"component":"data2-core-comparison-operators@Equal","displayName":"is collaborator"}]},"component":"data2-core-logical-operators@And","displayName":"is org member and collaborator"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is collaborator"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is collaborator and has system access"}]},"component":"data2-core-logical-operators@Or"}}},{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"private"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}}]},"component":"data2-core-functions@Includes","displayName":"is owner/admin"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is owner/admin"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is member and has system access"}]},"component":"data2-core-logical-operators@Or","displayName":"is owner/admin or has system access"}}}]},"component":"data2-core-flow@Switch"}}}},"component":"data2-core-functions@ArrayMap"}},"component":"data2-core-logical-operators@And","displayName":"has org member for all systems in request"}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"}},"component":"data2-core-flow@If"}},"component":"data2-core-flow@Step"},{"params":{"then":{"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"else":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"},"compare":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"has_access"}}}}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"sessionExpiresIn":{"component":"data2-core-primitives@Number","params":{"content":604800}},"sessionRenewal":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"identityProviders":[{"provider":{"component":"data2-core-primitives@String","params":{"content":"GOOGLE"}},"clientId":{"component":"data2-core-primitives@String","params":{"content":"55470861603-22pvfc1t49lp8cjnbfk71s5ct9hp1q1v.apps.googleusercontent.com"}}}]},"reference":"Data2BuilderAuthentication","updatedAt":"2026-08-06T19:31:23.557Z"},{"_id":"5f060ee51ca96def42f3fbd1","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"UsersTableDataSource"}},"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}}},"reference":"UsersDataSet","updatedAt":"2026-03-04T21:16:40.291Z"},{"_id":"68f938cf5fb002e33752a43d","displayName":"InternalApplicationsAuthenticationStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}}},"verifier":{"disabled":false,"component":"data2-core-types@DataSetReference","params":{"reference":"InternalApplicationsVerifierDataSet"}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"secret"}},"credentials":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}],"session":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}]},"reference":"InternalApplicationsAuthenticationStrategy","updatedAt":"2025-10-22T20:08:54.442Z","createdAt":"2025-10-22T20:04:31.198Z"},{"component":"data2-core@DataSet","reference":"SessionsDataSet","params":{"requiresConfirmation":false,"pk":"key","datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"data2sessionsdatasource"}}}},{"reference":"UsersTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@ServerSessionsDataSource","reference":"data2sessionsdatasource","params":{}},{"_id":"5f1600b70528b92601890f75","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ServiceComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ServiceComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:20.208Z","createdAt":"2020-07-20T20:38:15.436Z"},{"_id":"5f1602190528b92601890f7d","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":40000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentInstancesTableDataSource"}},"sort":{"_id":1},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:07.089Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"5f16017f0528b92601890f7a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"FileComponentInstancesDataSet","updatedAt":"2023-08-03T16:08:18.193Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"5f1601990528b92601890f7b","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ApplicationsTableDataSource"}},"pk":"_id","autoEdit":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"params":{"column":"_id"},"component":"data2-core-types@DataSetColumnReference"}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"ApplicationsDataSet","updatedAt":"2022-12-13T21:51:13.995Z","createdAt":"2020-07-20T20:42:01.657Z"},{"_id":"5f16172a0528b92601890f85","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":10000}}},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"DataComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"DataComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:12.831Z","createdAt":"2020-07-20T22:14:02.097Z"},{"_id":"60ddc1bbda3861ca65407c5a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"pagination":{"size":1},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"}},"reference":"OneFileComponentInstancesDataSet","updatedAt":"2022-02-09T19:44:38.036Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"63ee3d38b8c9838c62fb05fb","displayName":"DriveFileComponentInstancesDataSet","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core@Drive"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"DriveFileComponentInstancesDataSet","updatedAt":"2025-12-04T21:58:32.367Z","createdAt":"2023-02-16T14:27:07.797Z"},{"reference":"ServiceComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6ab3d161d3ad49514dda6f7a","component":"data2-rush@HTTPListener","reference":"jj-analyze-garment","system":"698a0c028a310c894be98bc8","params":{},"deleteMetadata":{}},{"_id":"6aac23a7cd0c40d8d9cd5b76","component":"data2-rush@HTTPListener","reference":"jj-search","system":"698a0c028a310c894be98bc8","params":{},"deleteMetadata":{}}]}},{"reference":"ComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6aac12f4cdfa61215a0c2796","component":"data2-core-primitives@Artboard","system":"698a0c028a310c894be98bc8","displayName":"Provador Standalone — Le Lis","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Provador Standalone — Le Lis"}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1200,"height":900}},"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0}}},"reference":"-04NAO7zQoSL0irfofo8J","deleteMetadata":{}},{"_id":"1951f2c3524dc8adb63bb7d4","parent":"6aac12f4cdfa61215a0c2796","component":"veste-app@provador-standalone","system":"698a0c028a310c894be98bc8","displayName":"provador-standalone","params":{"searchApi":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"jj-search"}},"drawAssistant":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"QCIyTA5AG7Pw3a9gBMVo-"}},"uploadDrive":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"RclleMA_LrWgrRPpd-qbr"}},"super":{"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0,"freeTransform":true,"left":true,"right":true,"top":true,"bottom":true}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1200,"height":900}}},"analyzeApi":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"jj-analyze-garment"}}},"reference":"MuYgCLsk9qI_DIYfGRxll","deleteMetadata":{}}]}},{"_id":"5fc4faeec8da12be8bf3d08a","component":"data2-core@Data2TableDataSource","system":"5e3b796d6228227ca637d0f4","params":{"paginate":{"default":1000},"super":{},"table":"fileComponentInstances","schema":[{"component":"data2-core-types@Field","params":{"key":"component","title":"Component","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"system","title":"System","component":"data2-core-primitives@ObjectId"}},{"component":"data2-core-types@Field","params":{"key":"displayName","title":"Display Name","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"params","title":"Params","component":"data2-core-primitives@Object"}},{"component":"data2-core-types@Field","params":{"key":"reference","title":"Reference","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"fileId"}},"title":"File ID","component":"data2-core-primitives@ObjectId"},"break":true}],"hooks":{"before":{"all":[{"hook":"softDelete"}],"find":[{"hook":"useCache","options":{"additionalGroupKeys":["$and.0.system","$and.1.system"],"skipCache":true}}],"create":[{"hook":"timestamp","options":{"fields":["createdAt","updatedAt"]}}],"update":[{"hook":"timestamp","options":{"fields":["updatedAt"]}}],"patch":[{"hook":"timestamp","options":{"fields":["updatedAt"]}}]},"after":{"all":[{"hook":"fileUrl","options":{"downloadField":"params.fileUrl","uploadField":"params.uploadFileUrl","enhanceSchema":false}}],"find":[{"hook":"useCache","options":{"additionalGroupKeys":["$and.0.system","$and.1.system"],"skipCache":true}}],"create":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}],"update":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}],"patch":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}],"remove":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}]}},"multi":["create"],"useEstimatedDocumentCount":true},"reference":"FileComponentInstancesTableDataSource","updatedAt":"2022-12-19T20:42:51.837Z","createdAt":"2020-11-30T13:59:52.294Z"},{"reference":"ApplicationsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6ab3e1746ccf35a3331fcfcb","displayName":"Provador Embed Test","reference":"vtndEzzqhrktPfji0GlgO","params":{"domain":{"component":"data2-core-primitives@String","params":{"content":"provador"}},"entryPoint":{"component":"data2-core-types@ComponentInstanceReference","params":{"component":"data2-core-primitives@Artboard","reference":"-04NAO7zQoSL0irfofo8J"}}},"system":"698a0c028a310c894be98bc8","component":"data2-core-primitives@Application"}]}},{"reference":"DataComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"698b150ab4ad7a8f26e9fb99","component":"data2-core-ai@Assistant","system":"698a0c028a310c894be98bc8","params":{"model":"cerebras"},"reference":"QCIyTA5AG7Pw3a9gBMVo-"}]}},{"reference":"BundlesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}}],"processesParams":{}}}}