feat: substitui seleção de sequência por checklist da análise do Scanner na aba Editar vídeo
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
06e4d13e86
commit
5f3c7f6a24
+14
-16
@@ -90,31 +90,29 @@
|
|||||||
<section class="card scanner-analysis-card" id="scannerAnalysisCard">
|
<section class="card scanner-analysis-card" id="scannerAnalysisCard">
|
||||||
<div class="card-head"><h2>Análise do Scanner</h2><span class="step-chip" id="scannerAnalysisStatus">Não carregada</span></div>
|
<div class="card-head"><h2>Análise do Scanner</h2><span class="step-chip" id="scannerAnalysisStatus">Não carregada</span></div>
|
||||||
<p class="field-help" id="scannerAnalysisInfo">Carregue a análise mais recente do Scanner antes de gerar o plano de edição.</p>
|
<p class="field-help" id="scannerAnalysisInfo">Carregue a análise mais recente do Scanner antes de gerar o plano de edição.</p>
|
||||||
|
<ul class="scanner-analysis-checks" id="scannerAnalysisChecks" aria-label="Componentes carregados da análise">
|
||||||
|
<li id="scannerCheckTranscription" data-state="pending"><span class="check-dot" aria-hidden="true"></span><span>Transcrição</span><em>Aguardando</em></li>
|
||||||
|
<li id="scannerCheckDiarization" data-state="pending"><span class="check-dot" aria-hidden="true"></span><span>Detecção de falantes</span><em>Aguardando</em></li>
|
||||||
|
<li id="scannerCheckVoiceFeatures" data-state="pending"><span class="check-dot" aria-hidden="true"></span><span>Métrica de voz</span><em>Aguardando</em></li>
|
||||||
|
</ul>
|
||||||
<button id="btnLoadScannerAnalysis" class="button button-primary" onclick="silenceLoadScannerAnalysis()" type="button">Carregar análise do Scanner</button>
|
<button id="btnLoadScannerAnalysis" class="button button-primary" onclick="silenceLoadScannerAnalysis()" type="button">Carregar análise do Scanner</button>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="step editar-video-legado" id="step1" data-state="ready">
|
<section class="step" id="step1" data-state="locked">
|
||||||
<div class="step-head">
|
<div class="step-head">
|
||||||
<span class="step-number" aria-hidden="true">1</span>
|
<span class="step-number" aria-hidden="true">1</span>
|
||||||
<div class="step-title">
|
<div class="step-title">
|
||||||
<h2>Escolher o vídeo</h2>
|
<h2>Selecionar o tipo de vídeo</h2>
|
||||||
<p>Lista as timelines do projeto e lê o primeiro clipe da escolhida.</p>
|
<p>Escolha o perfil cadastrado que orientará a edição e as instruções para a IA.</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="step-chip" id="step1Chip">Comece aqui</span>
|
<span class="step-chip" id="step1Chip">Aguardando análise</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="step-body">
|
<div class="step-body">
|
||||||
<button id="btnDetectClip" class="button button-primary" onclick="silenceListSequences()" type="button">Carregar sequências</button>
|
<label class="field-label" for="silenceTipoVideoSelect">Tipo de vídeo</label>
|
||||||
<div class="sequence-picker" id="silenceSequencePicker" hidden>
|
<select id="silenceTipoVideoSelect" class="select-field" onchange="silenceSelecionarTipoVideo()" disabled>
|
||||||
<label class="field-label" for="silenceSequenceSelect">Escolha a timeline</label>
|
<option value="">Selecione um tipo cadastrado</option>
|
||||||
<select id="silenceSequenceSelect" class="select-field" onchange="silenceSelectSequence()"></select>
|
</select>
|
||||||
<p class="field-help" id="silenceSequenceListInfo"></p>
|
<p class="field-help" id="silenceTipoVideoInfo">Os tipos disponíveis são carregados do cadastro de Tipos de vídeo.</p>
|
||||||
</div>
|
|
||||||
<dl class="kv" id="silenceClipCard" hidden>
|
|
||||||
<div><dt>Sequência</dt><dd id="clipSequenceName">—</dd></div>
|
|
||||||
<div><dt>Arquivo</dt><dd id="clipFileName">—</dd></div>
|
|
||||||
<div><dt>Caminho</dt><dd class="kv-path" id="clipMediaPath">—</dd></div>
|
|
||||||
</dl>
|
|
||||||
<p class="field-help" id="silenceClipInfo">Abra o projeto no Premiere e carregue as timelines.</p>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
+110
-12
@@ -265,7 +265,7 @@ function switchTab(name) {
|
|||||||
btn.setAttribute("aria-selected", String(active));
|
btn.setAttribute("aria-selected", String(active));
|
||||||
});
|
});
|
||||||
if (name === "models") renderModelList();
|
if (name === "models") renderModelList();
|
||||||
if (name === "silence") { syncTranscribeModelSelect(); syncLanguageInfo(); }
|
if (name === "silence") { syncTranscribeModelSelect(); syncLanguageInfo(); renderizarTiposDeVideoParaEdicao(); }
|
||||||
if (name === "settings") renderEditorPersonalities();
|
if (name === "settings") renderEditorPersonalities();
|
||||||
if (name === "scanner") { renderScannerTranscriptionOptions(); loadScannerProfile(); renderScannerHuggingFaceStatus(); scannerListarAnalisesExistentes(); }
|
if (name === "scanner") { renderScannerTranscriptionOptions(); loadScannerProfile(); renderScannerHuggingFaceStatus(); scannerListarAnalisesExistentes(); }
|
||||||
if (name === "refinar") refinarAoAbrir();
|
if (name === "refinar") refinarAoAbrir();
|
||||||
@@ -2112,10 +2112,71 @@ var silenceState = {
|
|||||||
transcribeModel: null,
|
transcribeModel: null,
|
||||||
cachedTranscriptPath: null,
|
cachedTranscriptPath: null,
|
||||||
jsonOutputPath: null,
|
jsonOutputPath: null,
|
||||||
|
tipoVideoId: null,
|
||||||
|
tipoVideo: null,
|
||||||
speakers: [],
|
speakers: [],
|
||||||
speakerTurns: [],
|
speakerTurns: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function atualizarCheckDaAnalise(id, disponivel, textoDisponibilidade) {
|
||||||
|
var item = document.getElementById(id);
|
||||||
|
if (!item) return;
|
||||||
|
item.setAttribute("data-state", disponivel ? "done" : "missing");
|
||||||
|
var estado = item.querySelector("em");
|
||||||
|
if (estado) estado.textContent = textoDisponibilidade || (disponivel ? "Carregado" : "Não disponível");
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderizarTiposDeVideoParaEdicao() {
|
||||||
|
var seletor = document.getElementById("silenceTipoVideoSelect");
|
||||||
|
if (!seletor) return;
|
||||||
|
var selecionado = silenceState.tipoVideoId || "";
|
||||||
|
seletor.innerHTML = '<option value="">Selecione um tipo cadastrado</option>';
|
||||||
|
tiposVideoLer().filter(function (tipo) { return tipo.ativo !== false; }).forEach(function (tipo) {
|
||||||
|
var opcao = document.createElement("option");
|
||||||
|
opcao.value = tipo.id;
|
||||||
|
opcao.textContent = tipo.nome;
|
||||||
|
opcao.selected = tipo.id === selecionado;
|
||||||
|
seletor.appendChild(opcao);
|
||||||
|
});
|
||||||
|
seletor.disabled = !silenceState.sequenceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
function silenceSelecionarTipoVideo() {
|
||||||
|
var seletor = document.getElementById("silenceTipoVideoSelect");
|
||||||
|
var tipo = tiposVideoLer().filter(function (item) { return item.id === seletor.value; })[0] || null;
|
||||||
|
silenceState.tipoVideoId = tipo ? tipo.id : null;
|
||||||
|
silenceState.tipoVideo = tipo;
|
||||||
|
if (!tipo) {
|
||||||
|
document.getElementById("silenceTipoVideoInfo").textContent = "Selecione um tipo cadastrado para continuar.";
|
||||||
|
setStep(1, "ready", "Selecione um tipo");
|
||||||
|
document.getElementById("btnBuildPlan").disabled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.getElementById("silenceTipoVideoInfo").textContent = tipo.nome + " · instruções serão incluídas no JSON para a IA.";
|
||||||
|
setStep(1, "done", "Selecionado");
|
||||||
|
document.getElementById("btnBuildPlan").disabled = false;
|
||||||
|
silenceLog("Tipo de vídeo selecionado: " + tipo.nome + ".", "ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
function tipoVideoResumoParaJson(tipo) {
|
||||||
|
if (!tipo) return null;
|
||||||
|
return {
|
||||||
|
id: tipo.id,
|
||||||
|
nome: tipo.nome,
|
||||||
|
categoria: tipo.categoria,
|
||||||
|
objetivo: { principal: tipo.objetivo, secundario: tipo.objetivo_secundario, publico: tipo.publico, mensagem: tipo.mensagem },
|
||||||
|
narrativa: { tipo: tipo.tipo_narrativa, foco: tipo.foco_narrativo, storytelling: tipo.storytelling, estrutura: tipo.estrutura },
|
||||||
|
emocao: { objetivo: tipo.emocao, intensidade: tipo.intensidade, tom: tipo.tom, construcao: tipo.construcao_emocao },
|
||||||
|
formato: { canais: tipo.canais, proporcao: tipo.proporcao, duracao_minima_segundos: tipo.duracao_minima, duracao_maxima_segundos: tipo.duracao_maxima_segundos, ritmo: tipo.ritmo },
|
||||||
|
prioridades: tipo.prioridades,
|
||||||
|
elementos_de_edicao: { broll: tipo.usa_broll, legendas: tipo.usa_legendas, textos: tipo.usa_textos, graficos: tipo.usa_graficos, zoom: tipo.usa_zoom, cortes: tipo.cortes, orientacao_de_broll: tipo.broll, textos_e_legendas: tipo.texto },
|
||||||
|
audio: { musica: tipo.usa_musica, intensidade_da_musica: tipo.intensidade_musica, prioridade_da_voz: tipo.prioridade_voz, tratamento: tipo.som },
|
||||||
|
regras_de_edicao: tipo.diretriz,
|
||||||
|
restricoes: tipo.restricoes,
|
||||||
|
criterios_de_qualidade: tipo.qualidade
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function silenceLocalizarUltimoRelatorioDoScanner() {
|
function silenceLocalizarUltimoRelatorioDoScanner() {
|
||||||
var raiz = scannerOutputRoot();
|
var raiz = scannerOutputRoot();
|
||||||
var candidatos = [];
|
var candidatos = [];
|
||||||
@@ -2188,6 +2249,20 @@ function silenceLocalizarAudioParaFalantes(pasta) {
|
|||||||
return encontrados[0] || null;
|
return encontrados[0] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function silenceLocalizarMidiaNoRelatorio(caminhoDoRelatorio, dadosDoRelatorio) {
|
||||||
|
var arquivosDeAudio = dadosDoRelatorio.artefatos && dadosDoRelatorio.artefatos.audio || [];
|
||||||
|
for (var indice = 0; indice < arquivosDeAudio.length; indice++) {
|
||||||
|
try {
|
||||||
|
var dadosDoAudio = JSON.parse(fs.readFileSync(path.join(path.dirname(caminhoDoRelatorio), arquivosDeAudio[indice]), "utf-8"));
|
||||||
|
var clipes = dadosDoAudio.faixa && dadosDoAudio.faixa.clipes || [];
|
||||||
|
for (var indiceDoClipe = 0; indiceDoClipe < clipes.length; indiceDoClipe++) {
|
||||||
|
if (clipes[indiceDoClipe].sourceFile) return clipes[indiceDoClipe].sourceFile;
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function silenceLoadScannerAnalysis() {
|
function silenceLoadScannerAnalysis() {
|
||||||
var status = document.getElementById("scannerAnalysisStatus");
|
var status = document.getElementById("scannerAnalysisStatus");
|
||||||
var info = document.getElementById("scannerAnalysisInfo");
|
var info = document.getElementById("scannerAnalysisInfo");
|
||||||
@@ -2207,12 +2282,14 @@ function silenceLoadScannerAnalysis() {
|
|||||||
var sequencia = dadosDoRelatorio.sequencia || {};
|
var sequencia = dadosDoRelatorio.sequencia || {};
|
||||||
silenceState.sequenceId = sequencia.id || null;
|
silenceState.sequenceId = sequencia.id || null;
|
||||||
silenceState.sequenceName = sequencia.nome || path.basename(caminhoDoRelatorio);
|
silenceState.sequenceName = sequencia.nome || path.basename(caminhoDoRelatorio);
|
||||||
silenceState.mediaPath = null;
|
silenceState.mediaPath = silenceLocalizarMidiaNoRelatorio(caminhoDoRelatorio, dadosDoRelatorio);
|
||||||
silenceState.fileBaseName = path.basename(path.dirname(caminhoDoRelatorio));
|
silenceState.fileBaseName = path.basename(path.dirname(caminhoDoRelatorio));
|
||||||
silenceState.outputDir = path.dirname(caminhoDoRelatorio);
|
silenceState.outputDir = path.dirname(caminhoDoRelatorio);
|
||||||
silenceState.audioCachePath = silenceLocalizarAudioParaFalantes(silenceState.outputDir);
|
silenceState.audioCachePath = silenceLocalizarAudioParaFalantes(silenceState.outputDir);
|
||||||
silenceState.transcriptPath = path.join(silenceState.outputDir, "transcricao-do-scanner.json");
|
silenceState.transcriptPath = path.join(silenceState.outputDir, "transcricao-do-scanner.json");
|
||||||
silenceState.cachedTranscriptPath = null;
|
silenceState.cachedTranscriptPath = null;
|
||||||
|
silenceState.tipoVideoId = null;
|
||||||
|
silenceState.tipoVideo = null;
|
||||||
fs.writeFileSync(silenceState.transcriptPath, JSON.stringify(
|
fs.writeFileSync(silenceState.transcriptPath, JSON.stringify(
|
||||||
silenceConverterRelatorioDoScannerParaTranscricao(caminhoDoRelatorio, dadosDoRelatorio), null, 2), "utf-8");
|
silenceConverterRelatorioDoScannerParaTranscricao(caminhoDoRelatorio, dadosDoRelatorio), null, 2), "utf-8");
|
||||||
var transcricao = JSON.parse(fs.readFileSync(silenceState.transcriptPath, "utf-8"));
|
var transcricao = JSON.parse(fs.readFileSync(silenceState.transcriptPath, "utf-8"));
|
||||||
@@ -2221,6 +2298,12 @@ function silenceLoadScannerAnalysis() {
|
|||||||
if (!statusDoBanco || !statusDoBanco.audio) throw new Error("A análise não foi encontrada no banco de dados.");
|
if (!statusDoBanco || !statusDoBanco.audio) throw new Error("A análise não foi encontrada no banco de dados.");
|
||||||
var audioDoBanco = statusDoBanco.audio;
|
var audioDoBanco = statusDoBanco.audio;
|
||||||
var falantes = audioDoBanco.falantes || [];
|
var falantes = audioDoBanco.falantes || [];
|
||||||
|
var temTranscricao = quantidade > 0;
|
||||||
|
var temDiarizacao = !!audioDoBanco.diarizacao_disponivel || falantes.length > 0;
|
||||||
|
var temMetricasDeVoz = !!audioDoBanco.metricas_de_voz_disponiveis;
|
||||||
|
atualizarCheckDaAnalise("scannerCheckTranscription", temTranscricao, temTranscricao ? "Carregado" : "Não encontrada");
|
||||||
|
atualizarCheckDaAnalise("scannerCheckDiarization", temDiarizacao, temDiarizacao ? "Carregado" : "Não realizada");
|
||||||
|
atualizarCheckDaAnalise("scannerCheckVoiceFeatures", temMetricasDeVoz, temMetricasDeVoz ? "Carregado" : "Não realizada");
|
||||||
var turnos = transcricao.segments.filter(function (segmento) { return segmento.falante; }).map(function (segmento) {
|
var turnos = transcricao.segments.filter(function (segmento) { return segmento.falante; }).map(function (segmento) {
|
||||||
return { speaker: segmento.falante, start: segmento.start, end: segmento.end };
|
return { speaker: segmento.falante, start: segmento.start, end: segmento.end };
|
||||||
});
|
});
|
||||||
@@ -2231,17 +2314,19 @@ function silenceLoadScannerAnalysis() {
|
|||||||
(audioDoBanco.metricas_de_voz_disponiveis ? "métricas disponíveis" : "métricas não realizadas") + " · " +
|
(audioDoBanco.metricas_de_voz_disponiveis ? "métricas disponíveis" : "métricas não realizadas") + " · " +
|
||||||
(audioDoBanco.diarizacao_disponivel ? falantes.length + " falante(s)" : "diarização não realizada");
|
(audioDoBanco.diarizacao_disponivel ? falantes.length + " falante(s)" : "diarização não realizada");
|
||||||
setStep(3, "ready", "Pronto");
|
setStep(3, "ready", "Pronto");
|
||||||
setStep(4, "ready", "Pronto");
|
setStep(1, "ready", "Selecione um tipo");
|
||||||
|
setStep(4, "locked", "Selecione o tipo");
|
||||||
setStep(5, "locked", "Bloqueado");
|
setStep(5, "locked", "Bloqueado");
|
||||||
document.getElementById("btnBuildPlan").disabled = false;
|
renderizarTiposDeVideoParaEdicao();
|
||||||
document.getElementById("btnDiarize").disabled = true;
|
document.getElementById("btnBuildPlan").disabled = true;
|
||||||
document.getElementById("btnVoiceFeatures").disabled = true;
|
document.getElementById("btnDiarize").disabled = false;
|
||||||
document.getElementById("silenceDiarizeInfo").textContent = audioDoBanco.diarizacao_disponivel
|
document.getElementById("btnVoiceFeatures").disabled = false;
|
||||||
|
document.getElementById("silenceDiarizeInfo").textContent = temDiarizacao
|
||||||
? falantes.length + " falante(s) disponíveis no banco de dados."
|
? falantes.length + " falante(s) disponíveis no banco de dados."
|
||||||
: "Diarização não realizada nesta análise do Scanner.";
|
: "Diarização não realizada nesta análise do Scanner. Use Refazer se necessário.";
|
||||||
document.getElementById("silenceVoiceFeaturesInfo").textContent = audioDoBanco.metricas_de_voz_disponiveis
|
document.getElementById("silenceVoiceFeaturesInfo").textContent = temMetricasDeVoz
|
||||||
? audioDoBanco.falas_com_metricas + " trecho(s) com métricas de voz no banco."
|
? (audioDoBanco.falas_com_metricas || 0) + " trecho(s) com métricas de voz no banco."
|
||||||
: "Métricas de voz não realizadas nesta análise do Scanner.";
|
: "Métricas de voz não realizadas nesta análise do Scanner. Use Refazer se necessário.";
|
||||||
silenceLog("Análise do Scanner carregada: " + quantidade + " trecho(s).", "ok");
|
silenceLog("Análise do Scanner carregada: " + quantidade + " trecho(s).", "ok");
|
||||||
showToast("ok", "Análise do Scanner carregada.");
|
showToast("ok", "Análise do Scanner carregada.");
|
||||||
} catch (erro) {
|
} catch (erro) {
|
||||||
@@ -2812,6 +2897,7 @@ function silenceDiarizeSpeakers(onFinished) {
|
|||||||
: "Falantes detectados.";
|
: "Falantes detectados.";
|
||||||
silenceLog(msg, "ok");
|
silenceLog(msg, "ok");
|
||||||
info.textContent = msg;
|
info.textContent = msg;
|
||||||
|
atualizarCheckDaAnalise("scannerCheckDiarization", true, "Carregado");
|
||||||
setStep(3, "done", "Enriquecido");
|
setStep(3, "done", "Enriquecido");
|
||||||
taskEnd(true, msg);
|
taskEnd(true, msg);
|
||||||
syncTranscriptToCache();
|
syncTranscriptToCache();
|
||||||
@@ -3065,6 +3151,7 @@ function silenceComputeVoiceFeatures() {
|
|||||||
var msg = "Pitch, energia, velocidade e pausas calculados por trecho.";
|
var msg = "Pitch, energia, velocidade e pausas calculados por trecho.";
|
||||||
silenceLog(msg, "ok");
|
silenceLog(msg, "ok");
|
||||||
info.textContent = msg;
|
info.textContent = msg;
|
||||||
|
atualizarCheckDaAnalise("scannerCheckVoiceFeatures", true, "Carregado");
|
||||||
setStep(3, "done", "Enriquecido");
|
setStep(3, "done", "Enriquecido");
|
||||||
taskEnd(true, msg);
|
taskEnd(true, msg);
|
||||||
syncTranscriptToCache();
|
syncTranscriptToCache();
|
||||||
@@ -3077,6 +3164,11 @@ function silenceComputeVoiceFeatures() {
|
|||||||
// externo analisar. Quem decide os cortes é a IA, não este painel.
|
// externo analisar. Quem decide os cortes é a IA, não este painel.
|
||||||
function silenceGenerateJson() {
|
function silenceGenerateJson() {
|
||||||
if (!silenceState.transcriptPath) return;
|
if (!silenceState.transcriptPath) return;
|
||||||
|
if (!silenceState.tipoVideo) {
|
||||||
|
showToast("err", "Selecione o tipo de vídeo antes de gerar o JSON.");
|
||||||
|
setStep(1, "ready", "Selecione um tipo");
|
||||||
|
return;
|
||||||
|
}
|
||||||
setBusy("btnBuildPlan", true);
|
setBusy("btnBuildPlan", true);
|
||||||
setStep(4, "running", "Gerando…");
|
setStep(4, "running", "Gerando…");
|
||||||
silenceLog("Gerando arquivo JSON para a IA…");
|
silenceLog("Gerando arquivo JSON para a IA…");
|
||||||
@@ -3095,6 +3187,11 @@ function silenceGenerateJson() {
|
|||||||
legendas: carregarConfiguracaoDeLegendas(),
|
legendas: carregarConfiguracaoDeLegendas(),
|
||||||
});
|
});
|
||||||
transcript.speaker_configuration = speakerConfigurationForJson();
|
transcript.speaker_configuration = speakerConfigurationForJson();
|
||||||
|
transcript.tipo_de_video = {
|
||||||
|
id: silenceState.tipoVideo.id,
|
||||||
|
nome: silenceState.tipoVideo.nome,
|
||||||
|
instrucoes: tipoVideoResumoParaJson(silenceState.tipoVideo),
|
||||||
|
};
|
||||||
|
|
||||||
ensureDir(silenceState.outputDir);
|
ensureDir(silenceState.outputDir);
|
||||||
var out = path.join(silenceState.outputDir, "dados-para-ia.json");
|
var out = path.join(silenceState.outputDir, "dados-para-ia.json");
|
||||||
@@ -3878,11 +3975,12 @@ function downloadModel(model, btn, approxMB) {
|
|||||||
syncLanguageInfo();
|
syncLanguageInfo();
|
||||||
renderEditorPersonalities();
|
renderEditorPersonalities();
|
||||||
restaurarConfiguracaoDeLegendas();
|
restaurarConfiguracaoDeLegendas();
|
||||||
|
renderizarTiposDeVideoParaEdicao();
|
||||||
|
|
||||||
// A aba Editar vídeo começa com a análise já produzida pelo Scanner.
|
// A aba Editar vídeo começa com a análise já produzida pelo Scanner.
|
||||||
setStep(1, "locked", "Scanner");
|
setStep(1, "locked", "Scanner");
|
||||||
setStep(2, "locked", "Scanner");
|
setStep(2, "locked", "Scanner");
|
||||||
setStep(3, "ready", "Aguardando análise");
|
setStep(3, "locked", "Aguardando análise");
|
||||||
setStep(4, "locked", "Aguardando análise");
|
setStep(4, "locked", "Aguardando análise");
|
||||||
setStep(5, "locked", "Aguardando plano");
|
setStep(5, "locked", "Aguardando plano");
|
||||||
|
|
||||||
|
|||||||
@@ -179,6 +179,16 @@ h1, h2, h3 { margin: 0; }
|
|||||||
.editorial-plan-json { width: 100%; min-height: 150px; resize: vertical; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; line-height: 1.45; color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 9px; }
|
.editorial-plan-json { width: 100%; min-height: 150px; resize: vertical; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; line-height: 1.45; color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 9px; }
|
||||||
.editar-video-legado { display: none; }
|
.editar-video-legado { display: none; }
|
||||||
.scanner-analysis-card { margin-bottom: 12px; }
|
.scanner-analysis-card { margin-bottom: 12px; }
|
||||||
|
.scanner-analysis-checks { display: grid; gap: 6px; margin: 10px 0 12px; padding: 0; list-style: none; }
|
||||||
|
.scanner-analysis-checks li { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface-deep); color: var(--text-secondary); }
|
||||||
|
.scanner-analysis-checks li em { margin-left: auto; color: var(--text-muted); font-size: 9px; font-style: normal; }
|
||||||
|
.scanner-analysis-checks li[data-state="done"] { border-color: rgba(112, 217, 135, .3); color: var(--text); }
|
||||||
|
.scanner-analysis-checks li[data-state="done"] .check-dot { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); color: #10240f; font-size: 10px; font-weight: 800; }
|
||||||
|
.scanner-analysis-checks li[data-state="done"] .check-dot::after { content: "✓"; }
|
||||||
|
.scanner-analysis-checks li[data-state="missing"] { border-color: rgba(233, 184, 93, .3); }
|
||||||
|
.scanner-analysis-checks li[data-state="missing"] .check-dot { background: var(--amber); }
|
||||||
|
.scanner-analysis-checks li[data-state="done"] em { color: var(--green); }
|
||||||
|
.scanner-analysis-checks li[data-state="missing"] em { color: var(--amber); }
|
||||||
|
|
||||||
/* --------------------- Painel de progresso (task dock) ------------------- */
|
/* --------------------- Painel de progresso (task dock) ------------------- */
|
||||||
.task-dock {
|
.task-dock {
|
||||||
|
|||||||
Reference in New Issue
Block a user