sagadeck 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +305 -0
- package/SKILL.md +148 -0
- package/bin/sagadeck.js +511 -0
- package/docs/ANDAMENTO.md +1255 -0
- package/docs/EXPERIENCIAS.md +39 -0
- package/docs/PLANO-EXPERIENCIAS.md +39 -0
- package/docs/PLANO-TESTE-AULAS-TECNICAS.md +44 -0
- package/docs/PLANO-TESTE-DESINFORMACAO.md +38 -0
- package/docs/REFERENCIA.md +1131 -0
- package/package.json +59 -0
- package/src/adaptive-layouts.js +18 -0
- package/src/ai/art-direction.js +8 -0
- package/src/ai/commands.js +130 -0
- package/src/ai/context.js +245 -0
- package/src/ai/deck-ai.js +1135 -0
- package/src/ai/directions.js +74 -0
- package/src/ai/document-materials.js +49 -0
- package/src/ai/document-visuals.js +215 -0
- package/src/ai/evaluation.js +31 -0
- package/src/ai/ground.js +55 -0
- package/src/ai/llm.js +292 -0
- package/src/ai/quality.js +51 -0
- package/src/ai/relay.js +45 -0
- package/src/ai/staged-generation.js +24 -0
- package/src/ai/transform.js +858 -0
- package/src/ai/usage.js +17 -0
- package/src/ai/variety.js +80 -0
- package/src/ai/video-frames.js +24 -0
- package/src/ai/video-generation.js +126 -0
- package/src/ai/web-operation.js +31 -0
- package/src/algo-catalog.js +153 -0
- package/src/algo-trace.js +139 -0
- package/src/api-client.js +514 -0
- package/src/api-collections.js +14 -0
- package/src/api-demo.js +222 -0
- package/src/aspect.js +40 -0
- package/src/build.js +323 -0
- package/src/carousel.js +56 -0
- package/src/chrome.js +65 -0
- package/src/code-highlight.js +68 -0
- package/src/code-lab-browser.js +22 -0
- package/src/code-lab.js +3 -0
- package/src/code-language.js +52 -0
- package/src/csv.js +74 -0
- package/src/decision-lab.js +20 -0
- package/src/deck-file.js +119 -0
- package/src/diagram/napkin-examples.js +13 -0
- package/src/diagram/napkin.js +539 -0
- package/src/docx.js +128 -0
- package/src/dynamics/git-sim.js +200 -0
- package/src/dynamics/layouts.js +112 -0
- package/src/elements.js +554 -0
- package/src/experiences.js +124 -0
- package/src/exploration.js +31 -0
- package/src/export/browser.js +53 -0
- package/src/export/estudo.js +67 -0
- package/src/export/pptx.js +475 -0
- package/src/export/roteiro.js +40 -0
- package/src/export/shots.js +182 -0
- package/src/figures/charts.js +383 -0
- package/src/figures/diagrams.js +117 -0
- package/src/figures/icons.js +166 -0
- package/src/figures/material-pictos.js +20 -0
- package/src/figures/pictos.js +255 -0
- package/src/figures/points.js +106 -0
- package/src/figures/qr.js +29 -0
- package/src/figures/ufmap.js +48 -0
- package/src/fiscal/autofix.js +377 -0
- package/src/fiscal/normalize.js +115 -0
- package/src/graph-lab.js +24 -0
- package/src/hologram.js +30 -0
- package/src/identity.js +86 -0
- package/src/import/crop.js +59 -0
- package/src/import/index.js +132 -0
- package/src/import/legacy-word.js +42 -0
- package/src/import/merge.js +45 -0
- package/src/import/office.js +123 -0
- package/src/import/omml.js +69 -0
- package/src/import/pdf-render.js +56 -0
- package/src/import/pptx.js +701 -0
- package/src/import/xml.js +42 -0
- package/src/infographic.js +401 -0
- package/src/layouts.js +723 -0
- package/src/lessons.js +171 -0
- package/src/library.js +399 -0
- package/src/markup.js +116 -0
- package/src/master.js +214 -0
- package/src/mcp/server.js +371 -0
- package/src/meeting.js +42 -0
- package/src/motion.js +56 -0
- package/src/package.js +116 -0
- package/src/playground.js +19 -0
- package/src/portal-scene.js +20 -0
- package/src/preferences.js +61 -0
- package/src/protect.js +51 -0
- package/src/purpose.js +24 -0
- package/src/pytrace.js +1092 -0
- package/src/research/duckduckgo.js +73 -0
- package/src/research/research.js +202 -0
- package/src/research/svg-image.js +17 -0
- package/src/research/visuals.js +52 -0
- package/src/runtime/api-collection-ui.js +5 -0
- package/src/runtime/api-collections.js +28 -0
- package/src/runtime/api-core.js +530 -0
- package/src/runtime/api-ui.js +966 -0
- package/src/runtime/base.css +1774 -0
- package/src/runtime/calc.js +139 -0
- package/src/runtime/code-lab.js +371 -0
- package/src/runtime/decision-lab.js +49 -0
- package/src/runtime/diagram.js +341 -0
- package/src/runtime/fit.js +268 -0
- package/src/runtime/fonts/caveat.css +2 -0
- package/src/runtime/fonts/comic-neue.css +3 -0
- package/src/runtime/fonts/fredoka.css +2 -0
- package/src/runtime/fonts/index.json +10 -0
- package/src/runtime/fonts/inter.css +2 -0
- package/src/runtime/fonts/patrick-hand.css +2 -0
- package/src/runtime/fonts/plus-jakarta-sans.css +2 -0
- package/src/runtime/fonts/press-start-2p.css +2 -0
- package/src/runtime/fonts/vt323.css +2 -0
- package/src/runtime/formula.js +148 -0
- package/src/runtime/graph-lab.js +72 -0
- package/src/runtime/meeting.css +7 -0
- package/src/runtime/meeting.js +10 -0
- package/src/runtime/motion.js +15 -0
- package/src/runtime/playground.js +11 -0
- package/src/runtime/points.js +19 -0
- package/src/runtime/portal-scene.css +6 -0
- package/src/runtime/portal-scene.js +22 -0
- package/src/runtime/runtime.js +827 -0
- package/src/runtime/science.js +89 -0
- package/src/runtime/skins/aluminio.css +31 -0
- package/src/runtime/skins/arcade.css +25 -0
- package/src/runtime/skins/aurora.css +17 -0
- package/src/runtime/skins/bauhaus.css +19 -0
- package/src/runtime/skins/editorial.css +19 -0
- package/src/runtime/skins/jornal.css +17 -0
- package/src/runtime/skins/manual-noite.css +14 -0
- package/src/runtime/skins/manual.css +14 -0
- package/src/runtime/skins/noite.css +21 -0
- package/src/runtime/skins/oceano.css +17 -0
- package/src/runtime/skins/pop.css +23 -0
- package/src/runtime/skins/prata.css +18 -0
- package/src/runtime/skins/prisma.css +28 -0
- package/src/runtime/skins/rabisco.css +18 -0
- package/src/runtime/skins/relevo.css +33 -0
- package/src/runtime/skins/sinal.css +16 -0
- package/src/runtime/skins/terminal.css +23 -0
- package/src/runtime/vendor/KATEX-LICENSE.txt +21 -0
- package/src/runtime/vendor/MERMAID-LICENSE.txt +21 -0
- package/src/runtime/vendor/PLOTLY-LICENSE.txt +21 -0
- package/src/runtime/vendor/katex.css +1 -0
- package/src/runtime/vendor/mermaid.min.js +3636 -0
- package/src/runtime/vendor/plotly.min.js +3620 -0
- package/src/runtime/video-player.js +35 -0
- package/src/science.js +162 -0
- package/src/studio/ai-response.js +36 -0
- package/src/studio/api-routes.js +152 -0
- package/src/studio/assets/contexto/leia-me.md +12 -0
- package/src/studio/assets/contexto/vendas.csv +7 -0
- package/src/studio/assets/imagens/colecao-arquitetura.png +0 -0
- package/src/studio/assets/imagens/colecao-cor.png +0 -0
- package/src/studio/assets/imagens/colecao-equipe.png +0 -0
- package/src/studio/assets/imagens/lavanda-cover.jpg +0 -0
- package/src/studio/code-routes.js +32 -0
- package/src/studio/command-approval.js +48 -0
- package/src/studio/demo-decks.js +98 -0
- package/src/studio/direction-routes.js +29 -0
- package/src/studio/errors.js +65 -0
- package/src/studio/exploration-demo.js +17 -0
- package/src/studio/exporting.js +105 -0
- package/src/studio/generation-report.js +10 -0
- package/src/studio/instance.js +48 -0
- package/src/studio/layout-samples.js +152 -0
- package/src/studio/project.js +371 -0
- package/src/studio/public/api-collections.js +28 -0
- package/src/studio/public/app.js +5265 -0
- package/src/studio/public/art-preview.js +10 -0
- package/src/studio/public/calc-fields.js +11 -0
- package/src/studio/public/chat-progress.js +47 -0
- package/src/studio/public/developer-fields.js +22 -0
- package/src/studio/public/explorer.js +443 -0
- package/src/studio/public/history.js +58 -0
- package/src/studio/public/index.html +867 -0
- package/src/studio/public/inspector.js +270 -0
- package/src/studio/public/lab-fields.js +5 -0
- package/src/studio/public/library.css +275 -0
- package/src/studio/public/library.html +55 -0
- package/src/studio/public/library.js +471 -0
- package/src/studio/public/merge-decks.js +155 -0
- package/src/studio/public/review-ui.js +100 -0
- package/src/studio/public/screenshot-editor.js +140 -0
- package/src/studio/public/share-ui.js +72 -0
- package/src/studio/public/slide-clipboard.js +23 -0
- package/src/studio/public/slide-form.js +1263 -0
- package/src/studio/public/studio-awareness.js +154 -0
- package/src/studio/public/studio-next.css +303 -0
- package/src/studio/public/style.css +1262 -0
- package/src/studio/public/ui-icons.js +2 -0
- package/src/studio/public/viewers.js +372 -0
- package/src/studio/public/visual-editor.js +326 -0
- package/src/studio/public/workspace.js +18 -0
- package/src/studio/public-files.js +1 -0
- package/src/studio/request-helpers.js +41 -0
- package/src/studio/server.js +1583 -0
- package/src/studio/share-routes.js +146 -0
- package/src/studio/slide-copy-routes.js +26 -0
- package/src/studio/slide-copy.js +30 -0
- package/src/studio/snapshot.js +160 -0
- package/src/studio/style-routes.js +103 -0
- package/src/studio/template-collections.js +97 -0
- package/src/studio/versions.js +95 -0
- package/src/studio/video-download.js +29 -0
- package/src/studio/visual-keys.js +52 -0
- package/src/studio/workspaces.js +39 -0
- package/src/table.js +93 -0
- package/src/templates/scaffold.js +372 -0
- package/src/themes.js +604 -0
- package/src/trace-view.js +450 -0
- package/src/uid.js +19 -0
- package/src/video-player.js +40 -0
- package/src/visual-edits.js +99 -0
- package/src/ws.js +134 -0
- package/templates/cenario/Texto no cen/303/241rio.yaml" +171 -0
- package/templates/cenario/imagens/cidade.svg +30 -0
- package/templates/cenario/imagens/pessoa.svg +15 -0
- package/templates/cenario-e-ciencia.yaml +47 -0
- package/templates/ensaio-api.yaml +160 -0
- package/templates/exemplo-alegre.yaml +75 -0
- package/templates/exemplo-keynote.yaml +90 -0
- package/templates/exemplo-napkin.yaml +139 -0
- package/templates/exemplo.yaml +228 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/* Inspetor de propriedades (como o Object Inspector do Delphi / o painel da direita do Figma).
|
|
2
|
+
Mostra só o que faz sentido para o que está selecionado no slide; Slide e Apresentação ficam sempre à vista.
|
|
3
|
+
Categorias recolhíveis (o que fica aberto é lembrado neste navegador). Toda mudança grava no deck. */
|
|
4
|
+
(function () {
|
|
5
|
+
let host, ctx, pending = false;
|
|
6
|
+
const KEY = "sagadeck.inspectorOpen";
|
|
7
|
+
const openCats = (() => { try { return JSON.parse(localStorage.getItem(KEY) || "{}"); } catch { return {}; } })();
|
|
8
|
+
const saveOpen = () => { try { localStorage.setItem(KEY, JSON.stringify(openCats)); } catch {} };
|
|
9
|
+
const esc = (v) => String(v ?? "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
10
|
+
const ic = (name) => `<i class="ic" data-ic="${name}"></i>`;
|
|
11
|
+
|
|
12
|
+
// ---------- o que existe para cada tipo de objeto ----------
|
|
13
|
+
const is = {
|
|
14
|
+
text: (els) => els.every((n) => n.classList.contains("t")),
|
|
15
|
+
shape: (els) => els.every((n) => n.classList.contains("shape")),
|
|
16
|
+
drawn: (els) => els.every((n) => n.querySelector(":scope > .shape-svg")),
|
|
17
|
+
image: (els) => els.every((n) => n.classList.contains("fig-img") || n.querySelector(":scope > img")),
|
|
18
|
+
};
|
|
19
|
+
const WEIGHTS = [["", "Do tema"], ["400", "Normal"], ["500", "Médio"], ["600", "Semibold"], ["700", "Negrito"], ["800", "Extra"]];
|
|
20
|
+
const ALIGNS = [["", "Do layout"], ["left", "Esquerda"], ["center", "Centro"], ["right", "Direita"], ["justify", "Justificado"]];
|
|
21
|
+
const SHADOWS = [["", "Nenhuma"], ["suave", "Suave"], ["forte", "Forte"]];
|
|
22
|
+
const ANIMS = [["", "Do tema"], ["fade", "Aparecer"], ["pop", "Pular"], ["left", "Da esquerda"], ["right", "Da direita"], ["down", "De cima"], ["zoom", "Zoom"], ["none", "Sem animação"]];
|
|
23
|
+
|
|
24
|
+
function objectCats(els) {
|
|
25
|
+
const cats = [{ id: "obj-pos", title: "Posição e tamanho", rows: [
|
|
26
|
+
{ k: "dx", label: "Mover na horizontal", type: "num", unit: "px" },
|
|
27
|
+
{ k: "dy", label: "Mover na vertical", type: "num", unit: "px" },
|
|
28
|
+
{ k: "w", label: "Largura", type: "num", unit: "px", min: 20 },
|
|
29
|
+
{ k: "h", label: "Altura", type: "num", unit: "px", min: 20 },
|
|
30
|
+
{ k: "rotate", label: "Rotação", type: "num", unit: "°", min: -360, max: 360 },
|
|
31
|
+
{ k: "z", label: "Camada (frente/trás)", type: "num", step: 1 },
|
|
32
|
+
] }];
|
|
33
|
+
if (is.text(els)) cats.push({ id: "obj-text", title: "Texto", rows: [
|
|
34
|
+
{ k: "size", label: "Tamanho", type: "num", unit: "px", min: 10, max: 500 },
|
|
35
|
+
{ k: "color", label: "Cor", type: "color" },
|
|
36
|
+
{ k: "weight", label: "Peso", type: "select", options: WEIGHTS, num: true },
|
|
37
|
+
{ k: "italic", label: "Itálico", type: "bool" },
|
|
38
|
+
{ k: "align", label: "Alinhamento", type: "select", options: ALIGNS },
|
|
39
|
+
{ k: "lineHeight", label: "Entrelinha", type: "num", unit: "×", step: 0.05, min: 0.7, max: 3 },
|
|
40
|
+
{ k: "letterSpacing", label: "Espaço entre letras", type: "num", unit: "em", step: 0.01, min: -0.1, max: 0.5 },
|
|
41
|
+
{ k: "uppercase", label: "Tudo maiúsculo", type: "bool" },
|
|
42
|
+
] });
|
|
43
|
+
if (is.shape(els)) cats.push({ id: "obj-shape", title: "Preenchimento e contorno", rows: [
|
|
44
|
+
{ k: "fill", label: "Preenchimento", type: "color" },
|
|
45
|
+
{ k: "stroke", label: "Contorno", type: "color" },
|
|
46
|
+
{ k: "strokeWidth", label: "Espessura do contorno", type: "num", unit: "px", min: 0, max: 40 },
|
|
47
|
+
...(is.drawn(els) ? [] : [{ k: "radius", label: "Cantos arredondados", type: "num", unit: "px", min: 0 }]),
|
|
48
|
+
] });
|
|
49
|
+
const look = [
|
|
50
|
+
{ k: "opacity", label: "Opacidade", type: "range", unit: "%", scale: 100 },
|
|
51
|
+
{ k: "shadow", label: "Sombra", type: "select", options: SHADOWS },
|
|
52
|
+
];
|
|
53
|
+
if (is.image(els)) cats.push({ id: "obj-img", title: "Imagem", rows: [
|
|
54
|
+
{ k: "__replace", label: "Arquivo", type: "action", text: "Trocar imagem" },
|
|
55
|
+
{ k: "fit", label: "Encaixe", type: "select", options: [["", "Do slide"], ["cover", "Preencher (corta as bordas)"], ["contain", "Inteira"]] },
|
|
56
|
+
{ k: "focus", label: "Ponto de foco", type: "select", hint: "Ao preencher, a parte da foto que nunca é cortada", options: [["", "Centro"], ["top", "Em cima"], ["bottom", "Embaixo"], ["left", "Esquerda"], ["right", "Direita"], ["top left", "Em cima, à esquerda"], ["top right", "Em cima, à direita"], ["bottom left", "Embaixo, à esquerda"], ["bottom right", "Embaixo, à direita"]] },
|
|
57
|
+
] });
|
|
58
|
+
if (is.image(els)) look.push({ k: "radius", label: "Cantos arredondados", type: "num", unit: "px", min: 0 }, { k: "stroke", label: "Borda", type: "color" }, { k: "strokeWidth", label: "Espessura da borda", type: "num", unit: "px", min: 0, max: 40 });
|
|
59
|
+
cats.push({ id: "obj-look", title: "Aparência", rows: look });
|
|
60
|
+
cats.push({ id: "obj-anim", title: "Animação", rows: [
|
|
61
|
+
{ k: "step", label: "Aparece no clique", type: "num", step: 1, min: 1, hint: "vazio = já aparece ao entrar no slide" },
|
|
62
|
+
{ k: "anim", label: "Entrada", type: "select", options: ANIMS },
|
|
63
|
+
] });
|
|
64
|
+
cats.push({ id: "obj-adv", title: "Avançado", rows: [
|
|
65
|
+
{ k: "hidden", label: "Oculto", type: "bool" },
|
|
66
|
+
{ k: "locked", label: "Travado", type: "bool", hint: "O clique no slide atravessa; selecione pela lista de objetos" },
|
|
67
|
+
{ k: "__key", label: "Identificador", type: "readonly" },
|
|
68
|
+
{ k: "__clear", label: "Ajustes deste objeto", type: "action", text: "Limpar tudo" },
|
|
69
|
+
] });
|
|
70
|
+
return cats;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function slideCats() {
|
|
74
|
+
const S = ctx.state, slide = S.deck?.slides?.[S.currentSlideIndex] || {};
|
|
75
|
+
const opt = (sel) => [...(document.getElementById(sel)?.options || [])].map((o) => [o.value, o.textContent]);
|
|
76
|
+
return [{ id: "slide", title: `Slide ${S.currentSlideIndex + 1}`, target: "slide", rows: [
|
|
77
|
+
{ k: "layout", label: "Layout", type: "select", options: ctx.layouts(), noEmpty: true },
|
|
78
|
+
{ k: "tone", label: "Tom", type: "select", options: [["", "Do layout"], ...opt("tone-select")] },
|
|
79
|
+
{ k: "deco", label: "Textura", type: "select", options: [["", "Do tema"], ...opt("deco-select")] },
|
|
80
|
+
{ k: "density", label: "Densidade", type: "select", options: [["", "Padrão"], ["compact", "Compacta"], ["dense", "Mais conteúdo"]] },
|
|
81
|
+
{ k: "time", label: "Tempo", type: "num", unit: "min", step: 0.5, min: 0 },
|
|
82
|
+
{ k: "transition", label: "Transição", type: "select", options: [["", "Esmaecer"], ["cut", "Corte seco"]] },
|
|
83
|
+
{ k: "maxWords", label: "Limite de palavras", type: "num", min: 10, max: 600, step: 10, hint: "vazio = o da apresentação" },
|
|
84
|
+
{ k: "footer", label: "Rodapé", type: "select", options: [["", "Automático"], ["true", "Mostrar"], ["false", "Esconder"]], bool3: true },
|
|
85
|
+
{ k: "theme", label: "Tema só neste slide", type: "select", options: [["", "O da apresentação"], ...ctx.themes()] },
|
|
86
|
+
{ k: "palette", label: "Paleta só neste slide", type: "select", options: [["", "A da apresentação"], ...ctx.palettes()] },
|
|
87
|
+
{ k: "bg", label: "Cor de fundo", type: "color" },
|
|
88
|
+
] }, { id: "deck", title: "Apresentação", target: "deck", rows: [
|
|
89
|
+
{ k: "aspect", label: "Proporção do slide", type: "select", hint: "16:9, 4:3, retrato… ou personalizada (L:A). Ao trocar, os layouts se ajustam sozinhos e o que tem posição livre é reescalado.", options: ctx.aspects?.() || [["", "16:9"]] },
|
|
90
|
+
{ k: "purpose", label: "Uso do material", type: "select", hint: "Para apresentar: letra grande, pouco texto, para não dar sono. Para estudar depois: o material vai ser enviado e usado como fonte de estudo, então cabe bastante texto no slide.", options: [["", "Para apresentar: letra grande, pouco texto"], ...ctx.purposes()] },
|
|
91
|
+
{ k: "maxWords", label: "Limite de palavras por slide", type: "num", min: 10, max: 600, step: 10, hint: "vazio = o do tipo de material" },
|
|
92
|
+
{ k: "theme", label: "Tema", type: "select", options: ctx.themes(), noEmpty: true },
|
|
93
|
+
{ k: "palette", label: "Paleta", type: "select", options: [["", "A do tema"], ...ctx.palettes()] },
|
|
94
|
+
{ k: "markStyle", label: "Estilo do ==destaque==", type: "select", options: [["", "Marca-texto"], ["sublinhado", "Sublinhado"], ["cor", "Só cor"], ["negrito", "Negrito colorido"], ["nenhum", "Sem destaque"]] },
|
|
95
|
+
{ k: "motion", label: "Animações", type: "select", options: [["", "Suaves"], ["none", "Sem animação"], ["expressive", "Expressivas"]] },
|
|
96
|
+
{ k: "duration", label: "Duração", type: "num", unit: "min", min: 1, max: 600 },
|
|
97
|
+
{ k: "author", label: "Autor", type: "text" },
|
|
98
|
+
{ k: "date", label: "Data", type: "text", placeholder: "AAAA-MM-DD" },
|
|
99
|
+
{ k: "fit.minCodePt", label: "Mínimo do código ao encolher", type: "num", unit: "pt", min: 6, max: 24, hint: "vazio = o das Preferências" },
|
|
100
|
+
{ k: "fit.minTextPt", label: "Mínimo do texto ao encolher", type: "num", unit: "pt", min: 6, max: 30 },
|
|
101
|
+
{ k: "fit.wrapCode", label: "Quebrar linhas longas de código", type: "select", options: [["", "O das Preferências"], ["true", "Sim"], ["false", "Não"]], bool3: true },
|
|
102
|
+
] }];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ---------- valores ----------
|
|
106
|
+
const getPath = (o, k) => k.split(".").reduce((v, p) => (v == null ? undefined : v[p]), o);
|
|
107
|
+
// "fit.minCodePt" = o.fit.minCodePt; undefined apaga (e tira o objeto fit se ficou vazio)
|
|
108
|
+
function setPath(o, k, v) {
|
|
109
|
+
const [a, b] = k.split(".");
|
|
110
|
+
if (!b) { if (v === undefined) delete o[a]; else o[a] = v; return; }
|
|
111
|
+
if (v === undefined) { if (o[a]) { delete o[a][b]; if (!Object.keys(o[a]).length) delete o[a]; } return; }
|
|
112
|
+
o[a] = { ...(o[a] && typeof o[a] === "object" ? o[a] : {}), [b]: v };
|
|
113
|
+
}
|
|
114
|
+
const idOf = (catId, k) => `ip-${catId}-${k}`.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
115
|
+
function objValue(els, k) {
|
|
116
|
+
if (k === "__key") return els.map((n) => n.dataset.vkey).join(", ");
|
|
117
|
+
if (k === "locked") { const v = els.map((n) => n.hasAttribute("data-locked")); return v.every((x) => x === v[0]) ? (v[0] || undefined) : "__varios"; }
|
|
118
|
+
const vals = els.map((n) => window.SagaVisual.edits(n)[k]);
|
|
119
|
+
return vals.every((v) => JSON.stringify(v) === JSON.stringify(vals[0])) ? vals[0] : "__varios";
|
|
120
|
+
}
|
|
121
|
+
function parse(row, raw, el) {
|
|
122
|
+
if (row.type === "bool") return el.checked ? true : undefined;
|
|
123
|
+
if (raw === "" || raw == null) return undefined;
|
|
124
|
+
if (row.bool3) return raw === "true";
|
|
125
|
+
if (row.type === "num" || row.type === "range" || row.num) { let n = Number(raw); if (!Number.isFinite(n)) return undefined; if (row.scale) n /= row.scale; return n; }
|
|
126
|
+
if (row.type === "color") return raw;
|
|
127
|
+
return String(raw);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function control(row, value, catId) {
|
|
131
|
+
const id = idOf(catId, row.k);
|
|
132
|
+
const many = value === "__varios", v = many ? undefined : value;
|
|
133
|
+
const shown = row.scale && v != null ? Math.round(v * row.scale) : v;
|
|
134
|
+
const attrs = `id="${id}" data-k="${esc(row.k)}" aria-label="${esc(row.label)}"`;
|
|
135
|
+
switch (row.type) {
|
|
136
|
+
case "bool": return `<input type="checkbox" ${attrs}${v ? " checked" : ""}${many ? ' class="ip-many"' : ""}>`;
|
|
137
|
+
case "select": return `<select ${attrs}>${row.options.map(([ov, ol]) => `<option value="${esc(ov)}"${String(shown ?? "") === String(ov) ? " selected" : ""}>${esc(ol)}</option>`).join("")}${many ? '<option value="__varios" selected>vários</option>' : ""}</select>`;
|
|
138
|
+
case "color": return `<span class="ip-color"><input type="color" ${attrs} value="${/^#[0-9a-f]{6}$/i.test(v || "") ? v : "#888888"}"><span class="ip-hex">${many ? "vários" : v ? esc(v) : "padrão"}</span></span>`;
|
|
139
|
+
case "range": return `<span class="ip-range"><input type="range" min="0" max="100" step="1" ${attrs} value="${shown ?? 100}"><span class="ip-unit">${many ? "vários" : `${shown ?? 100}%`}</span></span>`;
|
|
140
|
+
case "readonly": return `<span class="ip-ro" title="${esc(v)}">${esc(v)}</span>`;
|
|
141
|
+
case "action": return `<button type="button" class="ip-action" ${attrs}>${esc(row.text)}</button>`;
|
|
142
|
+
case "text": return `<input type="text" ${attrs} value="${esc(shown ?? "")}" placeholder="${esc(row.placeholder || "")}">`;
|
|
143
|
+
default: return `<span class="ip-num"><input type="number" ${attrs} value="${shown ?? ""}" placeholder="${many ? "vários" : esc(row.hint ? "—" : "")}"${row.min != null ? ` min="${row.min}"` : ""}${row.max != null ? ` max="${row.max}"` : ""} step="${row.step ?? 1}">${row.unit ? `<span class="ip-unit">${esc(row.unit)}</span>` : ""}</span>`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function catHTML(cat, valueOf) {
|
|
148
|
+
const isOpen = openCats[cat.id] !== false;
|
|
149
|
+
const rows = cat.rows.map((row) => {
|
|
150
|
+
const value = valueOf(row.k);
|
|
151
|
+
const set = value !== undefined && value !== "__varios" && row.type !== "readonly" && row.type !== "action";
|
|
152
|
+
return `<div class="ip-row" data-row="${esc(row.k)}"${row.hint ? ` title="${esc(row.hint)}"` : ""}><label class="ip-l" for="${idOf(cat.id, row.k)}">${esc(row.label)}</label><div class="ip-v">${control(row, value, cat.id)}</div><button type="button" class="ip-reset" data-reset="${esc(row.k)}" title="Voltar ao padrão" aria-label="Voltar ${esc(row.label)} ao padrão"${set ? "" : " hidden"}>${ic("rotate-ccw")}</button></div>`;
|
|
153
|
+
}).join("");
|
|
154
|
+
return `<details class="ip-cat" data-cat="${cat.id}"${isOpen ? " open" : ""}><summary>${esc(cat.title)}</summary><div class="ip-rows">${rows}</div></details>`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// lista de objetos do slide (camadas): selecionar mesmo o que está travado ou escondido, mostrar/ocultar, travar
|
|
158
|
+
const kindOf = (n) => is.text([n]) ? ["Texto", "type"] : is.image([n]) ? ["Imagem", "image"] : is.shape([n]) ? ["Forma", "square"] : n.classList.contains("tbx") ? ["Texto do original", "type"] : n.classList.contains("drw") ? ["Desenho", "shapes"] : ["Objeto", "shapes"];
|
|
159
|
+
function layersHTML(els) {
|
|
160
|
+
const objs = window.SagaVisual?.objects?.() || [];
|
|
161
|
+
if (!objs.length) return "";
|
|
162
|
+
const rows = objs.map((n, i) => {
|
|
163
|
+
const [kind, icon] = kindOf(n);
|
|
164
|
+
const name = n.textContent.replace(/\s+/g, " ").trim().slice(0, 48) || kind;
|
|
165
|
+
const hidden = !!window.SagaVisual.edits(n).hidden, lk = n.hasAttribute("data-locked");
|
|
166
|
+
return `<div class="ip-layer${els.includes(n) ? " sel" : ""}${hidden ? " off" : ""}" data-layer="${i}" title="${esc(kind)}">${ic(icon)}<span class="ip-layer-name">${esc(name)}</span>`
|
|
167
|
+
+ `<button type="button" data-layer-eye aria-label="${hidden ? "Mostrar" : "Ocultar"}" title="${hidden ? "Mostrar" : "Ocultar"}">${ic(hidden ? "eye-off" : "eye")}</button>`
|
|
168
|
+
+ `<button type="button" data-layer-lock class="${lk ? "on" : ""}" aria-label="${lk ? "Destravar" : "Travar"}" title="${lk ? "Destravar" : "Travar (o clique no slide atravessa)"}">${ic(lk ? "lock" : "lock-open")}</button></div>`;
|
|
169
|
+
}).join("");
|
|
170
|
+
return `<section class="ip-sec" data-sec="layers"><details class="ip-cat" data-cat="layers"${openCats.layers !== false ? " open" : ""}><summary>Objetos do slide (${objs.length})</summary><div class="ip-layers">${rows}</div></details></section>`;
|
|
171
|
+
}
|
|
172
|
+
function bindLayers() {
|
|
173
|
+
const objs = window.SagaVisual?.objects?.() || [];
|
|
174
|
+
host.querySelectorAll(".ip-layer").forEach((row) => {
|
|
175
|
+
const n = objs[+row.dataset.layer];
|
|
176
|
+
if (!n) return;
|
|
177
|
+
row.onclick = (e) => { if (!e.target.closest("button")) window.SagaVisual.select([n]); };
|
|
178
|
+
row.querySelector("[data-layer-eye]").onclick = () => window.SagaVisual.setPropOn([n], "hidden", window.SagaVisual.edits(n).hidden ? null : true);
|
|
179
|
+
row.querySelector("[data-layer-lock]").onclick = () => window.SagaVisual.setPropOn([n], "locked", n.hasAttribute("data-locked") ? false : true);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function render() {
|
|
184
|
+
if (!host || !ctx?.state?.deck) return;
|
|
185
|
+
if (host.contains(document.activeElement) && document.activeElement.matches("input[type=number], input[type=text]")) { pending = true; return; } // digitando: não redesenha
|
|
186
|
+
pending = false;
|
|
187
|
+
const els = window.SagaVisual?.selection() || [];
|
|
188
|
+
const S = ctx.state, slide = S.deck.slides[S.currentSlideIndex] || {};
|
|
189
|
+
let html = "";
|
|
190
|
+
if (els.length) {
|
|
191
|
+
const kind = is.text(els) ? "Texto" : is.shape(els) ? "Forma" : is.image(els) ? "Imagem" : "Objeto";
|
|
192
|
+
const name = els.length > 1 ? `${els.length} objetos` : `${kind}${els[0].textContent.trim() ? `: “${els[0].textContent.trim().slice(0, 28)}”` : ""}`;
|
|
193
|
+
html += `<section class="ip-sec" data-sec="obj"><h4>${ic(kind === "Texto" ? "type" : kind === "Forma" ? "square" : kind === "Imagem" ? "image" : "shapes")}<span>${esc(name)}</span></h4>${objectCats(els).map((c) => catHTML(c, (k) => objValue(els, k))).join("")}</section>`;
|
|
194
|
+
}
|
|
195
|
+
html += layersHTML(els);
|
|
196
|
+
// o conteúdo do slide (itens do carrossel, fotos, destaques do screenshot, dados do gráfico…) mora no Formatar
|
|
197
|
+
html += `<button type="button" class="ip-content" data-open-content>${ic("pencil")}<span>Editar o conteúdo do slide</span></button>`;
|
|
198
|
+
const [sc, dc] = slideCats();
|
|
199
|
+
html += `<section class="ip-sec" data-sec="slide">${catHTML(sc, (k) => { const v = getPath(slide, k); return v === undefined ? undefined : typeof v === "boolean" ? String(v) : v; })}</section>`;
|
|
200
|
+
html += `<section class="ip-sec" data-sec="deck">${catHTML(dc, (k) => { const v = getPath(S.deck, k); return v === undefined ? undefined : typeof v === "boolean" ? String(v) : v; })}</section>`;
|
|
201
|
+
host.innerHTML = html;
|
|
202
|
+
ctx.hydrate(host);
|
|
203
|
+
bind(els);
|
|
204
|
+
bindLayers();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function rowOf(k, secId) {
|
|
208
|
+
const cats = secId === "obj" ? objectCats(window.SagaVisual.selection()) : slideCats();
|
|
209
|
+
for (const c of cats) { const r = c.rows.find((x) => x.k === k); if (r && (secId === "obj" || c.target === secId)) return r; }
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function apply(sec, row, value) {
|
|
214
|
+
if (sec === "obj") {
|
|
215
|
+
if (row.k === "__clear") { window.SagaVisual.clearEdits(); return; }
|
|
216
|
+
if (row.k === "__replace") { window.SagaVisual.replaceImage(); return; }
|
|
217
|
+
if (row.k === "locked") { window.SagaVisual.setProp("locked", value ? true : false); return; } // decoração do original vem travada: destravar grava false
|
|
218
|
+
window.SagaVisual.setProp(row.k, value ?? null); // grava, com Desfazer, em todos os selecionados
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const S = ctx.state;
|
|
222
|
+
if (sec === "slide") {
|
|
223
|
+
const slide = S.deck.slides[S.currentSlideIndex];
|
|
224
|
+
if (row.k === "layout") return ctx.changeLayout(value);
|
|
225
|
+
if (row.k === "theme" || row.k === "palette") return value === undefined ? ctx.applyLook(row.k, slide[row.k], "reset") : ctx.applyLook(row.k, value, "slide");
|
|
226
|
+
setPath(slide, row.k, row.k === "bg" && value ? value.replace("#", "") : value);
|
|
227
|
+
} else {
|
|
228
|
+
if (row.k === "aspect") {
|
|
229
|
+
const v = value === "__custom" ? window.prompt("Proporção personalizada (largura:altura), ex.: 5:4 ou 1200:900", "5:4") : value;
|
|
230
|
+
if (v == null) return render();
|
|
231
|
+
return ctx.changeAspect(v || "16:9");
|
|
232
|
+
}
|
|
233
|
+
if (row.k === "theme") return ctx.applyLook("theme", value, "all");
|
|
234
|
+
if (row.k === "palette") return ctx.applyLook("palette", value ?? "tema", "all");
|
|
235
|
+
setPath(S.deck, row.k, value);
|
|
236
|
+
}
|
|
237
|
+
ctx.commit();
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function bind() {
|
|
241
|
+
host.querySelector("[data-open-content]")?.addEventListener("click", () => ctx.openContent?.());
|
|
242
|
+
// grava já no clique (o evento toggle chega depois, e um recarregamento logo em seguida o perderia)
|
|
243
|
+
host.querySelectorAll("details.ip-cat").forEach((d) => {
|
|
244
|
+
d.querySelector(":scope > summary").addEventListener("click", () => { openCats[d.dataset.cat] = !d.open; saveOpen(); });
|
|
245
|
+
d.addEventListener("toggle", () => { openCats[d.dataset.cat] = d.open; saveOpen(); });
|
|
246
|
+
});
|
|
247
|
+
host.querySelectorAll("[data-k]").forEach((el) => {
|
|
248
|
+
const sec = el.closest(".ip-sec").dataset.sec, row = rowOf(el.dataset.k, sec);
|
|
249
|
+
if (!row) return;
|
|
250
|
+
if (row.type === "action") { el.onclick = () => apply(sec, row); return; }
|
|
251
|
+
if (row.type === "range") el.addEventListener("input", () => { el.nextElementSibling.textContent = `${el.value}%`; });
|
|
252
|
+
el.addEventListener("change", () => { if (el.value === "__varios") return; apply(sec, row, parse(row, el.value, el)); });
|
|
253
|
+
if (el.matches("input[type=number], input[type=text]")) {
|
|
254
|
+
el.addEventListener("keydown", (e) => { if (e.key === "Enter") { e.preventDefault(); el.blur(); } });
|
|
255
|
+
el.addEventListener("blur", () => { if (pending) setTimeout(render, 0); });
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
host.querySelectorAll("[data-reset]").forEach((b) => {
|
|
259
|
+
const sec = b.closest(".ip-sec").dataset.sec, row = rowOf(b.dataset.reset, sec);
|
|
260
|
+
b.onclick = () => row && apply(sec, row, undefined);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function setup(container, context) {
|
|
265
|
+
host = container; ctx = context;
|
|
266
|
+
window.SagaVisual?.onSelect((els, why) => { ctx.onSelection?.(els, why); render(); });
|
|
267
|
+
render();
|
|
268
|
+
}
|
|
269
|
+
window.SagaInspector = { setup, refresh: render };
|
|
270
|
+
})();
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Formulários dos laboratórios interativos.
|
|
2
|
+
window.SagaLabFields = {
|
|
3
|
+
codelab: (f, obj) => [f.text('title','Título'),f.select('engine','Execução',[['trace','Python de aula · passo a passo offline'],['python','Python nativo · pacotes reais'],['javascript','JavaScript nativo · Node.js']],{empty:false,default:'trace'}),f.area('program','Programa',{mono:true,rows:14}),f.text('call','Chamada / entrada',{mono:true}),f.area('explanation','Desafio para a turma'),f.num('maxSteps','Máximo de passos')],
|
|
4
|
+
graphlab: (f, obj) => [f.text('title','Título'),f.list('nodes','Nós',obj([f.text('id','Id único'),f.text('label','Nome'),f.text('icon','Ícone Lucide'),f.num('x','Posição horizontal'),f.num('y','Posição vertical')]),{newItem:()=>({id:'novo',label:'Novo nó',icon:'map-pin'})}),f.list('edges','Ligações',obj([f.text('from','Origem (id)'),f.text('to','Destino (id)'),f.num('weight','Custo'),f.text('label','Nome da ligação')]),{newItem:()=>({from:'',to:'',weight:1})}),f.bool('directed','Ligações com direção'),f.text('start','Origem inicial'),f.text('goal','Destino inicial'),f.area('explanation','Convite ao experimento')]
|
|
5
|
+
};
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/* O estúdio usa uma superfície independente dos temas de apresentação. */
|
|
2
|
+
:root { color-scheme: light; --canvas-bg: #f7f6f2; --chrome: #fff; --chrome-2: #f1f0eb; --text: #23232b; --text-2: #61616b; --text-3: #7f7f89; --ui-line: #e7e6e0; --ui-line-strong: #d8d7d0; --brand: #634ce9; --brand-fill: #634ce9; --brand-fill-hover: #5039d1; --on-brand: white; --hover: #efeee9; --selected: #eae7fb; --err: #ba3944; --toast-bg: #25242d; --toast-text: white; --shadow-1: 0 2px 8px #25232c08; --shadow-2: 0 12px 28px #25232c16; --shadow-3: 0 18px 64px #18172026; }
|
|
3
|
+
:root[data-theme=dark] { color-scheme: dark; --canvas-bg: #19191e; --chrome: #212127; --chrome-2: #29292f; --text: #f3f2f6; --text-2: #b8b6c3; --text-3: #95929f; --ui-line: #333239; --ui-line-strong: #47454f; --brand: #ac9aff; --brand-fill: #7861ef; --brand-fill-hover: #8d76ff; --hover: #2c2a34; --selected: #39304f; }
|
|
4
|
+
* { box-sizing: border-box; }
|
|
5
|
+
body { margin: 0; font-family: 'Segoe UI', Arial, sans-serif; color: var(--text); -webkit-font-smoothing: antialiased; }
|
|
6
|
+
button, input, select, textarea { font: inherit; }
|
|
7
|
+
button, a { -webkit-tap-highlight-color: transparent; }
|
|
8
|
+
button { cursor: pointer; }
|
|
9
|
+
button:disabled { opacity: .55; cursor: wait; }
|
|
10
|
+
a { color: inherit; }
|
|
11
|
+
[hidden] { display: none !important; }
|
|
12
|
+
:focus-visible { outline: 3px solid var(--brand); outline-offset: 4px; }
|
|
13
|
+
.ic { display: inline-flex; width: 18px; height: 18px; flex: none; vertical-align: middle; }
|
|
14
|
+
.ic svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
|
|
15
|
+
body.lib { display: grid; grid-template-columns: 218px minmax(0, 1fr); grid-template-rows: 84px minmax(0, 1fr); height: 100vh; height: 100dvh; overflow: hidden; background: var(--canvas-bg); font-size: 14px; }
|
|
16
|
+
.skip-link { position: fixed; top: -80px; left: 20px; z-index: 100; padding: 12px; background: var(--chrome); border-radius: 8px; }
|
|
17
|
+
.skip-link:focus { top: 15px; }
|
|
18
|
+
.lib-brand { display: flex; align-items: center; gap: 11px; padding: 0 24px; border-right: 1px solid var(--ui-line); text-decoration: none; font-size: 23px; font-weight: 720; letter-spacing: -.8px; }
|
|
19
|
+
.brand-light { font-weight: 420; }
|
|
20
|
+
.lib-brand small { display: block; margin-top: 3px; color: var(--text-3); font-size: 8px; font-weight: 650; letter-spacing: 2px; }
|
|
21
|
+
.lib-logo { width: 33px; height: 37px; flex: none; display: grid; place-items: center; color: var(--brand); }
|
|
22
|
+
.lib-logo svg { width: 100%; height: 100%; } /* logotipo: um deck (dois slides) com o "apresentar" no da frente */
|
|
23
|
+
.lib-top { display: flex; align-items: center; gap: 13px; padding: 0 38px; border-bottom: 1px solid var(--ui-line); }
|
|
24
|
+
.breadcrumb { display: flex; gap: 12px; color: var(--text-3); font-size: 12px; white-space: nowrap; }
|
|
25
|
+
.breadcrumb b { font-weight: 500; color: var(--text-2); }
|
|
26
|
+
.breadcrumb span { color: var(--ui-line-strong); }
|
|
27
|
+
.spacer { flex: 1; }
|
|
28
|
+
.lib-search { display: flex; align-items: center; gap: 9px; width: 228px; height: 37px; color: var(--text-3); padding: 0 11px; background: transparent; border: 1px solid var(--ui-line); border-radius: 8px; }
|
|
29
|
+
.lib-search input { background: none; color: var(--text); border: 0; outline: 0; width: 100%; min-width: 0; font-size: 11px; }
|
|
30
|
+
.lib-search kbd { border: 1px solid var(--ui-line); border-radius: 3px; font-size: 10px; padding: 0 4px; }
|
|
31
|
+
.lib-btn { display: inline-flex; justify-content: center; align-items: center; gap: 8px; min-height: 38px; padding: 0 15px; border-radius: 8px; border: 1px solid transparent; font-size: 12px; font-weight: 600; text-decoration: none; transition: background .15s, transform .15s; }
|
|
32
|
+
.lib-btn.primary { background: var(--brand-fill); color: var(--on-brand); box-shadow: 0 3px 8px #634ce916; }
|
|
33
|
+
.lib-btn.primary:hover { background: var(--brand-fill-hover); transform: translateY(-1px); }
|
|
34
|
+
.lib-btn.ghost { background: transparent; border-color: var(--ui-line-strong); color: var(--text); }
|
|
35
|
+
.lib-btn.ghost:hover { background: var(--hover); }
|
|
36
|
+
.lib-btn.danger { color: var(--err); }
|
|
37
|
+
.lib-btn.large { min-height: 44px; padding: 0 18px; }
|
|
38
|
+
.lib-icon-btn { width: 34px; height: 34px; border-radius: 8px; display: grid; place-items: center; color: var(--text-3); background: none; border: 0; cursor: pointer; }
|
|
39
|
+
.lib-icon-btn:hover { background: var(--hover); }
|
|
40
|
+
.lib-user { display: flex; align-items: center; gap: 8px; font-size: 12px; }
|
|
41
|
+
.lib-avatar { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--selected); color: var(--brand); text-transform: uppercase; font-weight: 700; }
|
|
42
|
+
.lib-body { display: contents; }
|
|
43
|
+
.lib-side { min-height: 0; display: flex; flex-direction: column; padding: 14px 14px 18px; border-right: 1px solid var(--ui-line); overflow-y: auto; }
|
|
44
|
+
#side { display: flex; flex-direction: column; gap: 5px; flex: 1; min-height: 360px; }
|
|
45
|
+
.nav { display: flex; align-items: center; gap: 10px; min-height: 40px; flex: none; padding: 0 13px; border-radius: 8px; color: var(--text-2); width: 100%; text-align: left; background: none; border: 0; font-size: 12px; }
|
|
46
|
+
.nav:hover { background: var(--hover); }
|
|
47
|
+
.nav.active { background: var(--selected); color: var(--brand); font-weight: 600; }
|
|
48
|
+
.nav .count { margin-left: auto; font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums; }
|
|
49
|
+
.nav .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
50
|
+
.nav.drop { outline: 2px dashed var(--brand); outline-offset: -2px; background: var(--selected); }
|
|
51
|
+
.dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; flex: none; margin: 0 5px; }
|
|
52
|
+
.side-title { display: flex; align-items: center; justify-content: space-between; margin: 28px 13px 8px; font-size: 9px; font-weight: 650; letter-spacing: 1.5px; color: var(--text-3); }
|
|
53
|
+
.side-title button { color: var(--text-3); width: 24px; height: 24px; border-radius: 4px; display: grid; place-items: center; background: none; border: 0; }
|
|
54
|
+
.side-title button:hover { background: var(--hover); color: var(--text); }
|
|
55
|
+
.lib-side .grow { flex: 1; min-height: 32px; }
|
|
56
|
+
.side-foot { border-top: 1px solid var(--ui-line); padding-top: 12px; }
|
|
57
|
+
.where { font-size: 10px; color: var(--text-3); padding: 12px 12px 0; line-height: 1.6; word-break: break-all; }
|
|
58
|
+
.where summary { display: flex; align-items: center; gap: 7px; list-style: none; cursor: pointer; word-break: normal; }
|
|
59
|
+
.where summary::before { content: ''; width: 5px; height: 5px; border-radius: 100%; background: #63a487; }
|
|
60
|
+
.where code { display: block; margin-top: 7px; font-size: 9px; }
|
|
61
|
+
.ai-settings { margin: 12px 7px 0; font-size: 10px; }
|
|
62
|
+
.studio-note { margin: 16px 11px 22px; font-size: 11px; line-height: 1.6; color: var(--text-3); }
|
|
63
|
+
.studio-note strong { display: block; color: var(--text-2); font-size: 12px; margin-bottom: 4px; font-weight: 500; }
|
|
64
|
+
.lib-main { overflow-y: auto; min-width: 0; padding: 36px 44px 64px; scroll-behavior: smooth; outline: none; }
|
|
65
|
+
.lib-main > * { max-width: 1360px; margin-left: auto; margin-right: auto; }
|
|
66
|
+
.hero { position: relative; display: grid; grid-template-columns: 1.1fr .9fr; align-items: center; gap: 36px; padding: 8px 0 40px; }
|
|
67
|
+
.eyebrow { font-size: 9px; font-weight: 650; letter-spacing: 2px; color: var(--text-3); display: flex; align-items: center; gap: 7px; margin-bottom: 17px; }
|
|
68
|
+
.eyebrow .ic { width: 13px; height: 13px; color: var(--brand); }
|
|
69
|
+
.hero h1 { margin: 0; font-size: clamp(36px, 3.9vw, 60px); line-height: 1.1; letter-spacing: -2.4px; font-weight: 570; max-width: 640px; }
|
|
70
|
+
.hero h1 em { color: var(--brand); font-family: Georgia, serif; font-weight: 400; }
|
|
71
|
+
.hero p { max-width: 380px; color: var(--text-2); font-size: 12px; line-height: 1.8; margin: 20px 0; }
|
|
72
|
+
.hero-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
|
|
73
|
+
.text-button { display: inline-flex; align-items: center; gap: 7px; padding: 8px 0; color: var(--text-2); background: none; border: 0; font-size: 11px; text-decoration: none; white-space: nowrap; }
|
|
74
|
+
.text-button:hover { color: var(--brand); }
|
|
75
|
+
.text-button .ic { width: 14px; height: 14px; }
|
|
76
|
+
.hero-stage { position: relative; min-height: 280px; height: 100%; display: flex; align-items: center; justify-content: center; perspective: 900px; }
|
|
77
|
+
.stage-orbit { position: absolute; width: 240px; height: 240px; border: 1px solid var(--ui-line); border-radius: 100%; transform: rotate(-28deg) scaleX(1.45); }
|
|
78
|
+
.stage-orbit::after { content: ''; position: absolute; inset: 30px; border: 1px solid var(--ui-line); border-radius: 100%; }
|
|
79
|
+
.mini-slide { position: absolute; border-radius: 6px; box-shadow: 0 20px 42px #302c4025; overflow: hidden; }
|
|
80
|
+
.mini-beige { width: 235px; height: 150px; left: -3%; top: 18px; padding: 24px; color: #222629; background: #e5ddce; transform: rotate(-11deg); }
|
|
81
|
+
.mini-beige small { font-size: 7px; letter-spacing: 2px; }
|
|
82
|
+
.mini-beige b { display: block; font-family: Georgia, serif; font-size: 31px; line-height: 1.07; font-weight: 400; margin-top: 18px; }
|
|
83
|
+
.mini-beige::after { content: ''; width: 100px; height: 100px; background: #e87a57; position: absolute; right: -33px; bottom: -26px; border-radius: 50%; }
|
|
84
|
+
.mini-pop { width: 198px; height: 131px; right: 0; bottom: 5px; background: #d9ea88; transform: rotate(10deg); color: #273322; padding: 21px; }
|
|
85
|
+
.mini-pop b { font-size: 31px; letter-spacing: -1.5px; line-height: 1; }
|
|
86
|
+
.mini-pop span { font-family: Georgia, serif; font-style: italic; }
|
|
87
|
+
.mini-pop .star { position: absolute; font-size: 86px; bottom: -25px; right: -12px; color: #5b69bd; line-height: 1; }
|
|
88
|
+
.mini-dark { width: 285px; height: 182px; background: #191722; color: #fff; transform: rotate(-1deg); padding: 27px; z-index: 1; }
|
|
89
|
+
.mini-dark small { font-size: 6px; letter-spacing: 2px; color: #c1b8db; position: relative; z-index: 1; }
|
|
90
|
+
.mini-dark b { display: block; font-size: 37px; letter-spacing: -2px; line-height: 1; margin-top: 19px; position: relative; z-index: 1; font-weight: 550; }
|
|
91
|
+
.mini-dark b em { color: #c3affc; font-family: Georgia, serif; font-weight: 400; }
|
|
92
|
+
.mini-dark::before { content: ''; position: absolute; width: 178px; height: 178px; right: -38px; top: 5px; border-radius: 50%; background: radial-gradient(circle at 31% 29%, #ceb3ff 0%, #9071e1 17%, #5d41a0 33%, #251b39 65%); box-shadow: -8px 0 25px #9673e54a; }
|
|
93
|
+
.stage-label { position: absolute; z-index: 2; right: 14%; bottom: -5px; background: var(--chrome); border: 1px solid var(--ui-line); border-radius: 20px; padding: 9px 14px; box-shadow: var(--shadow-1); font-size: 9px; display: flex; gap: 7px; align-items: center; transform: rotate(-4deg); }
|
|
94
|
+
.stage-label .ic { width: 13px; height: 13px; color: var(--brand); }
|
|
95
|
+
.section-head { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 19px; }
|
|
96
|
+
.section-head h2 { font-size: 20px; font-weight: 600; letter-spacing: -.55px; margin: 0; }
|
|
97
|
+
.section-head p { font-size: 11px; color: var(--text-3); margin: 7px 0 0; }
|
|
98
|
+
.experiences-section { border-top: 1px solid var(--ui-line); padding-top: 27px; padding-bottom: 34px; }
|
|
99
|
+
.experience-filters { display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 20px; }
|
|
100
|
+
.experience-filter { border: 1px solid transparent; background: none; border-radius: 6px; color: var(--text-2); font-size: 10px; padding: 7px 12px; }
|
|
101
|
+
.experience-filter:hover { background: var(--hover); }
|
|
102
|
+
.experience-filter.active { background: var(--text); color: var(--canvas-bg); }
|
|
103
|
+
.experiences-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
|
|
104
|
+
.experience-card { position: relative; text-align: left; padding: 0; background: none; border: 0; color: var(--text); border-radius: 8px; min-width: 0; }
|
|
105
|
+
.experience-art { position: relative; display: block; aspect-ratio: 16 / 9; border-radius: 8px; overflow: hidden; padding: 22px; transition: transform .25s, box-shadow .25s; container-type: inline-size; }
|
|
106
|
+
.experience-card:hover .experience-art { transform: translateY(-4px); box-shadow: var(--shadow-2); }
|
|
107
|
+
.experience-art small { display: block; position: relative; z-index: 1; font-size: clamp(6px, 2.3cqw, 9px); letter-spacing: 1.4px; }
|
|
108
|
+
.experience-art b { display: block; position: relative; z-index: 1; font-size: clamp(20px, 11cqw, 42px); line-height: 1.07; letter-spacing: -.9px; font-weight: 550; margin-top: 17px; }
|
|
109
|
+
.art-executivo { background: #111419; color: #edebe6; }
|
|
110
|
+
.art-executivo small { color: #c2a773; }
|
|
111
|
+
.art-executivo b { max-width: 70%; font-size: 10cqw; }
|
|
112
|
+
.art-executivo em { color: #e4b660; font-weight: 400; font-family: Georgia, serif; }
|
|
113
|
+
.executive-bars { position: absolute; right: 20px; bottom: 20px; display: flex; gap: 4px; align-items: flex-end; height: 55%; width: 22%; }
|
|
114
|
+
.executive-bars i { flex: 1; height: 44%; background: #837759; border-top: 1px solid #e4b660; }
|
|
115
|
+
.executive-bars i:nth-child(2) { height: 67%; background: #ad9361; }
|
|
116
|
+
.executive-bars i:nth-child(3) { height: 100%; background: #e4b660; }
|
|
117
|
+
.art-editorial { background: #eee9df; color: #20211c; }
|
|
118
|
+
.art-editorial b { font-family: Georgia, serif; max-width: 75%; font-weight: 400; font-size: 11cqw; margin-top: 18px; }
|
|
119
|
+
.art-editorial em { font-weight: 400; color: #cc4937; }
|
|
120
|
+
.editorial-mark { position: absolute; width: 37%; aspect-ratio: 1; right: -6%; bottom: -10%; border-radius: 100%; background: #d56346; }
|
|
121
|
+
.editorial-mark::before { content: ''; position: absolute; width: 100%; height: 100%; left: -25%; top: -30%; border: 1px solid #353a2a; border-radius: 100%; }
|
|
122
|
+
.art-palco { background: #10131d; color: #f4f0fa; }
|
|
123
|
+
.art-palco b { font-size: 12cqw; font-weight: 650; max-width: 80%; }
|
|
124
|
+
.art-palco b em { color: #a2eaff; font-weight: 500; font-family: Georgia, serif; }
|
|
125
|
+
.stage-sphere { position: absolute; width: 69%; aspect-ratio: 1; border-radius: 100%; right: -13%; top: -2%; background: radial-gradient(circle at 26% 24%, #92f2f1, #489ad3 20%, #6959ba 36%, #261e56 55%, #181326 70%); box-shadow: -9px 0 35px #52cbfb29; }
|
|
126
|
+
.art-pop { background: #e6dfc9; color: #202622; }
|
|
127
|
+
.art-pop small { color: #3e463e; }
|
|
128
|
+
.art-pop b { max-width: 72%; font-size: 12cqw; font-weight: 800; letter-spacing: -1.5px; }
|
|
129
|
+
.pop-mark { position: absolute; width: 58%; aspect-ratio: 1; right: -18%; bottom: -29%; border: 29px solid #245dad; border-radius: 100%; }
|
|
130
|
+
.pop-star { position: absolute; font-size: 88px; right: 10%; top: -10%; color: #d5482b; }
|
|
131
|
+
.art-aula { background: #122927; color: #e6eadc; font-family: 'Cascadia Mono', Consolas, monospace; }
|
|
132
|
+
.art-aula small { color: #a5c5ae; font-size: 2.5cqw; letter-spacing: 0; }
|
|
133
|
+
.art-aula b { margin-top: 18px; font-family: 'Segoe UI', Arial, sans-serif; font-size: 10cqw; }
|
|
134
|
+
.art-aula em { font-style: normal; color: #bfdf6c; }
|
|
135
|
+
.code-lines { position: absolute; right: 14px; bottom: 12px; font-size: 3.8cqw; color: #91b69d; line-height: 1.7; opacity: .75; }
|
|
136
|
+
.code-cursor { position: absolute; width: 7px; height: 14px; background: #bfdf6c; bottom: 26px; left: 24px; }
|
|
137
|
+
.art-minimal { background: #eceef2; color: #202535; }
|
|
138
|
+
.art-minimal small { color: #748090; }
|
|
139
|
+
.art-minimal b { font-size: 11cqw; font-weight: 350; line-height: 1.16; max-width: 75%; margin-top: 17px; }
|
|
140
|
+
.minimal-line { position: absolute; width: 88px; height: 88px; border: 1px solid #9aacce; border-radius: 50%; right: -22px; bottom: -12px; }
|
|
141
|
+
.minimal-line::before { content: ''; position: absolute; inset: 12px; border: 1px solid #9aacce; border-radius: 50%; }
|
|
142
|
+
.experience-meta { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 12px 1px 0; }
|
|
143
|
+
.experience-meta strong { font-size: 12px; font-weight: 600; }
|
|
144
|
+
.experience-meta .experience-sub { display: block; font-size: 10px; color: var(--text-3); margin-top: 4px; font-weight: 400; }
|
|
145
|
+
.experience-meta .arrow { display: grid; place-items: center; width: 23px; height: 23px; border: 1px solid var(--ui-line); border-radius: 50%; color: var(--text-3); transition: background .2s; }
|
|
146
|
+
.experience-card:hover .arrow { background: var(--selected); color: var(--brand); border-color: transparent; }
|
|
147
|
+
.catalog-heading { padding: 5px 0 26px; }
|
|
148
|
+
.catalog-heading h1 { font-size: 38px; letter-spacing: -1.3px; font-weight: 550; margin: 0 0 12px; }
|
|
149
|
+
.catalog-heading p { color: var(--text-2); line-height: 1.8; max-width: 560px; font-size: 12px; }
|
|
150
|
+
.recent-section { padding-top: 25px; border-top: 1px solid var(--ui-line); }
|
|
151
|
+
.head { display: flex; align-items: flex-end; gap: 12px; margin-bottom: 22px; flex-wrap: wrap; }
|
|
152
|
+
.head h1 { margin: 0; font-size: 25px; font-weight: 600; letter-spacing: -.65px; display: flex; align-items: center; gap: 10px; }
|
|
153
|
+
.head .sub { color: var(--text-3); margin-top: 6px; font-size: 11px; }
|
|
154
|
+
.sort { height: 32px; border-radius: 6px; border: 1px solid var(--ui-line); background: transparent; color: var(--text-2); padding: 0 9px; font: inherit; font-size: 10px; }
|
|
155
|
+
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 24px 20px; }
|
|
156
|
+
.card { position: relative; border-radius: 9px; cursor: pointer; min-width: 0; }
|
|
157
|
+
.thumb { position: relative; aspect-ratio: 16 / 9; border-radius: 8px; overflow: hidden; background: var(--chrome-2); border: 1px solid var(--ui-line); transition: box-shadow .15s, transform .15s; }
|
|
158
|
+
.thumb img { width: 100%; height: 100%; object-fit: contain; display: block; position: relative; }
|
|
159
|
+
.thumb .loading { position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-3); font-size: 12px; }
|
|
160
|
+
.card:hover .thumb { box-shadow: var(--shadow-2); transform: translateY(-2px); }
|
|
161
|
+
.card.dragging { opacity: .4; }
|
|
162
|
+
.over { position: absolute; inset: 0; display: flex; align-items: flex-end; justify-content: flex-end; gap: 6px; padding: 10px; opacity: 0; transition: opacity .15s; background: linear-gradient(transparent 45%, #10101870); }
|
|
163
|
+
.card:hover .over, .card:focus-within .over { opacity: 1; }
|
|
164
|
+
.pill { min-height: 30px; padding: 0 10px; border-radius: 6px; background: #fffffff2; color: #1a1a1a; font-size: 10px; font-weight: 600; display: inline-flex; align-items: center; gap: 5px; box-shadow: var(--shadow-1); border: 0; cursor: pointer; font-family: inherit; }
|
|
165
|
+
.pill .ic { width: 13px; height: 13px; }
|
|
166
|
+
.meta { display: flex; align-items: flex-start; gap: 6px; padding: 12px 2px 0; }
|
|
167
|
+
.meta .t { flex: 1; min-width: 0; }
|
|
168
|
+
.meta .name { font-weight: 600; font-size: 12px; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
|
169
|
+
.meta .info { color: var(--text-3); font-size: 10px; margin-top: 6px; display: flex; gap: 5px; align-items: center; flex-wrap: wrap; }
|
|
170
|
+
.chip { display: inline-flex; align-items: center; gap: 2px; font-size: 10px; color: var(--text-3); }
|
|
171
|
+
.chip .dot { width: 5px; height: 5px; margin-left: 0; }
|
|
172
|
+
.more { width: 28px; height: 28px; border-radius: 6px; display: grid; place-items: center; color: var(--text-3); background: none; border: 0; }
|
|
173
|
+
.more:hover { background: var(--hover); color: var(--text); }
|
|
174
|
+
.new-card .thumb { border: 1px dashed var(--ui-line-strong); background: transparent; display: grid; place-items: center; color: var(--text-2); }
|
|
175
|
+
.new-card:hover .thumb { border-color: var(--brand); color: var(--brand); background: var(--selected); }
|
|
176
|
+
.new-card .plus { display: flex; flex-direction: column; align-items: center; gap: 8px; font-weight: 500; text-align: center; padding: 0 10px; font-size: 12px; }
|
|
177
|
+
.empty { text-align: center; padding: 45px 22px; color: var(--text-2); }
|
|
178
|
+
.empty .big { width: 44px; height: 44px; border-radius: 12px; background: var(--chrome-2); display: grid; place-items: center; margin: 0 auto 14px; color: var(--text-3); }
|
|
179
|
+
.empty .big .ic { width: 23px; height: 23px; }
|
|
180
|
+
.empty h2 { margin: 0 0 8px; font-size: 17px; color: var(--text); font-weight: 550; }
|
|
181
|
+
.empty p { margin: 0 auto 18px; max-width: 440px; line-height: 1.7; font-size: 12px; }
|
|
182
|
+
.empty .actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
|
|
183
|
+
.empty.compact { border: 1px dashed var(--ui-line-strong); border-radius: 10px; padding: 24px; text-align: left; display: flex; align-items: center; gap: 17px; }
|
|
184
|
+
.empty.compact .big { margin: 0; flex: none; }
|
|
185
|
+
.empty.compact .empty-copy { flex: 1; }
|
|
186
|
+
.empty.compact h2 { font-size: 14px; }
|
|
187
|
+
.empty.compact p { margin: 0; font-size: 11px; max-width: none; }
|
|
188
|
+
.trash-row { display: flex; align-items: center; gap: 14px; padding: 16px; border-radius: 8px; background: var(--chrome); border: 1px solid var(--ui-line); margin-bottom: 10px; flex-wrap: wrap; }
|
|
189
|
+
.trash-row .t { flex: 1; min-width: 180px; }
|
|
190
|
+
.trash-row .sub { color: var(--text-3); font-size: 11px; margin-top: 4px; }
|
|
191
|
+
.lmenu { position: fixed; z-index: 50; min-width: 250px; max-width: calc(100vw - 20px); background: var(--chrome); border: 1px solid var(--ui-line); border-radius: 12px; box-shadow: var(--shadow-3); padding: 7px; display: none; }
|
|
192
|
+
.lmenu.open { display: block; }
|
|
193
|
+
.mi { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 36px; padding: 5px 10px; border-radius: 6px; text-align: left; background: none; border: 0; cursor: pointer; color: var(--text); font: inherit; font-size: 12px; }
|
|
194
|
+
.mi:hover { background: var(--hover); }
|
|
195
|
+
.mi small { margin-left: auto; color: var(--text-3); }
|
|
196
|
+
.mi.danger { color: var(--err); }
|
|
197
|
+
.mi .d { display: block; font-size: 10px; color: var(--text-3); margin-top: 4px; font-weight: 400; line-height: 1.4; }
|
|
198
|
+
.mi .ic { color: var(--text-3); }
|
|
199
|
+
.lmenu.tall .mi { padding: 12px; align-items: center; }
|
|
200
|
+
.menu-label { display: block; padding: 10px 12px 5px; font-size: 8px; font-weight: 650; color: var(--text-3); letter-spacing: 1.5px; }
|
|
201
|
+
.sep { height: 1px; background: var(--ui-line); margin: 5px 4px; }
|
|
202
|
+
.ldlg-back { position: fixed; inset: 0; background: #17142166; backdrop-filter: blur(5px); display: none; place-items: center; z-index: 60; padding: 20px; }
|
|
203
|
+
.ldlg-back.open { display: grid; }
|
|
204
|
+
.ldlg { width: min(460px, calc(100vw - 32px)); max-height: calc(100dvh - 40px); overflow-y: auto; background: var(--chrome); border: 1px solid var(--ui-line); border-radius: 16px; box-shadow: var(--shadow-3); padding: 25px; }
|
|
205
|
+
.ldlg h3 { margin: 0 0 16px; font-size: 22px; font-weight: 580; letter-spacing: -.5px; }
|
|
206
|
+
.ldlg label { display: block; font-size: 11px; color: var(--text-2); margin: 15px 0 7px; }
|
|
207
|
+
.ldlg input[type=text], .ldlg textarea { width: 100%; box-sizing: border-box; padding: 11px 12px; border-radius: 8px; border: 1px solid var(--ui-line-strong); background: var(--chrome); color: var(--text); font: inherit; font-size: 13px; }
|
|
208
|
+
.ldlg textarea { min-height: 135px; resize: vertical; line-height: 1.7; }
|
|
209
|
+
.ldlg .row { display: flex; justify-content: flex-end; gap: 8px; margin-top: 22px; }
|
|
210
|
+
.swatches { display: flex; gap: 8px; flex-wrap: wrap; }
|
|
211
|
+
.sw { width: 28px; height: 28px; border-radius: 8px; border: 3px solid transparent; cursor: pointer; }
|
|
212
|
+
.sw.on { border-color: var(--text); }
|
|
213
|
+
.ldlg .status { font-size: 12px; color: var(--text-2); margin-top: 10px; min-height: 1.2em; line-height: 1.6; }
|
|
214
|
+
.experience-dialog .experience-art { aspect-ratio: 16/8; margin: -7px -7px 21px; padding: 27px; }
|
|
215
|
+
.experience-dialog .experience-art b { font-size: 35px; }
|
|
216
|
+
.experience-dialog .experience-art small { font-size: 8px; }
|
|
217
|
+
.experience-description { color: var(--text-2); font-size: 12px; line-height: 1.8; margin: -3px 0 16px; }
|
|
218
|
+
.experience-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 15px; }
|
|
219
|
+
.experience-tags span { border: 1px solid var(--ui-line); background: var(--chrome-2); padding: 5px 8px; border-radius: 4px; font-size: 9px; color: var(--text-2); }
|
|
220
|
+
.dialog-note { font-size: 10px; line-height: 1.6; color: var(--text-3); margin: 12px 0 0; }
|
|
221
|
+
.ltoast { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); background: var(--toast-bg); color: var(--toast-text); padding: 12px 17px; border-radius: 9px; box-shadow: var(--shadow-3); font-size: 12px; opacity: 0; transition: opacity .2s; pointer-events: none; z-index: 70; max-width: calc(100vw - 32px); }
|
|
222
|
+
.ltoast.show { opacity: 1; }
|
|
223
|
+
.initial-loading { display: flex; align-items: center; gap: 10px; color: var(--text-3); padding-top: 60px; justify-content: center; font-size: 12px; }
|
|
224
|
+
.loading-orbit { width: 15px; height: 15px; border: 2px solid var(--ui-line); border-top-color: var(--brand); border-radius: 100%; animation: spin .8s linear infinite; }
|
|
225
|
+
@keyframes spin { to { transform: rotate(360deg); } }
|
|
226
|
+
@media (min-width: 1680px) { .lib-main { padding: 40px 65px 70px; } .hero { padding-bottom: 48px; } .hero-stage { min-height: 320px; } .mini-dark { width: 335px; height: 207px; } .mini-dark b { font-size: 45px; } .mini-beige { left: 8%; } .mini-pop { right: 10%; } }
|
|
227
|
+
@media (max-width: 1200px) { body.lib { grid-template-columns: 190px minmax(0, 1fr); } .lib-top { padding: 0 24px; gap: 9px; } .lib-brand { padding: 0 20px; } .lib-main { padding: 30px 28px 60px; } .breadcrumb { display: none; } .hero { gap: 20px; } .hero-stage { transform: scale(.87); transform-origin: center right; margin-left: -40px; } .hero h1 { font-size: 44px; } .section-head h2 { font-size: 18px; } .experience-art { padding: 18px; } .experiences-grid { gap: 17px; } }
|
|
228
|
+
@media (max-width: 940px) { .hero { grid-template-columns: 1fr; padding-bottom: 30px; } .hero h1 { font-size: 45px; max-width: 480px; } .hero-stage { display: none; } .hero p { max-width: 420px; } .experiences-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .experience-art { padding: 20px; } .empty.compact { flex-wrap: wrap; } }
|
|
229
|
+
@media (max-width: 700px) { body.lib { grid-template-columns: 1fr; grid-template-rows: 70px minmax(0, 1fr); } .lib-brand { position: absolute; left: 8px; height: 70px; padding: 0 10px; border: 0; font-size: 20px; } .lib-brand small { font-size: 6px; } .lib-logo { width: 27px; } .lib-top { padding: 0 15px 0 168px; gap: 7px; } .lib-top .spacer { display: none; } .lib-search { width: 100%; min-width: 0; padding: 0 8px; border: 0; } .lib-search kbd, #btn-new .lbl, .lib-user .uname, #btn-theme { display: none; } #btn-new { padding: 0; min-width: 35px; min-height: 35px; } .lib-body { display: grid; grid-template-rows: auto minmax(0, 1fr); min-height: 0; } .lib-side { padding: 8px 13px; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--ui-line); flex-direction: row; } #side { flex-direction: row; align-items: center; min-height: 0; flex: none; gap: 4px; } .nav { min-height: 33px; width: auto; white-space: nowrap; font-size: 11px; gap: 7px; padding: 0 11px; } .nav .ic { width: 15px; height: 15px; } .nav .count { display: none; } .side-title { margin: 0 3px; font-size: 0; } .side-title button { width: 25px; height: 30px; } .lib-side .grow, .studio-note, .where, .ai-settings { display: none; } .side-foot { padding: 0; border: 0; } .lib-main { padding: 27px 22px 45px; } .hero { padding-top: 0; } .hero h1 { font-size: 41px; letter-spacing: -1.8px; } .hero p { font-size: 12px; margin: 16px 0 21px; } .eyebrow { font-size: 8px; margin-bottom: 17px; } .hero-actions { gap: 15px; } .section-head { gap: 10px; align-items: flex-start; } .section-head h2 { font-size: 17px; max-width: 230px; } .section-head .text-button { font-size: 10px; } .experiences-section { padding-top: 24px; } .experience-filters { gap: 2px; margin-bottom: 17px; } .experience-filter { padding: 7px 9px; font-size: 9px; } .experiences-grid { gap: 17px 12px; } .experience-art { padding: 13px; } .experience-art b { margin-top: 13px; } .experience-art small { letter-spacing: .8px; } .experience-meta { padding-top: 9px; } .experience-meta strong { font-size: 10px; } .experience-meta .experience-sub { font-size: 8px; line-height: 1.4; } .experience-meta .arrow { display: none; } .pop-star { font-size: 53px; } .pop-mark { border-width: 18px; } .code-cursor { width: 4px; height: 9px; left: 14px; bottom: 16px; } .code-lines { display: none; } .executive-bars { right: 11px; bottom: 13px; } .experience-art b { font-size: 10cqw; } .catalog-heading h1 { font-size: 30px; } .catalog-heading p { font-size: 12px; } .head h1 { font-size: 23px; } .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 12px; } .empty.compact { padding: 18px; gap: 12px; } .empty.compact .actions { justify-content: flex-start; } .empty.compact .empty-copy { min-width: 170px; } .over { padding: 6px; gap: 4px; opacity: 1; } .over .pill { font-size: 8px; padding: 0 6px; min-height: 25px; } .pill .ic { width: 10px; height: 10px; } .meta .info { font-size: 9px; } .meta .name { font-size: 11px; } .chip { font-size: 9px; } .ldlg { padding: 22px; } .ldlg .row .lib-btn { font-size: 11px; } }
|
|
230
|
+
@media (max-width: 390px) { .lib-search input { font-size: 10px; } .lib-main { padding-left: 17px; padding-right: 17px; } .hero h1 { font-size: 36px; } .lib-brand { font-size: 18px; gap: 6px; } .lib-top { padding-left: 149px; } .hero-actions { gap: 12px; } .hero-actions .lib-btn { font-size: 11px; } .section-head p { line-height: 1.6; } }
|
|
231
|
+
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }
|
|
232
|
+
.lmenu.tall { max-width: 340px; } /* menu Nova: descrições quebram em vez de alargar o menu */
|
|
233
|
+
|
|
234
|
+
/* Nova: diálogo largo (IA em uma tela; vitrine "Modelo pronto") */
|
|
235
|
+
.ldlg.wide { width: min(760px, calc(100vw - 32px)); }
|
|
236
|
+
.ldlg select { width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--ui-line-strong); background: var(--chrome); color: var(--text); font: inherit; font-size: 13px; }
|
|
237
|
+
.ldlg option { background: var(--chrome); color: var(--text); }
|
|
238
|
+
.dlg-two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 16px; }
|
|
239
|
+
.dlg-min { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-2); }
|
|
240
|
+
.dlg-min input { width: 84px; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--ui-line-strong); background: var(--chrome); color: var(--text); font: inherit; font-size: 13px; }
|
|
241
|
+
.dlg-min .hint { color: var(--text-3); font-size: 12px; }
|
|
242
|
+
.dlg-att { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
|
243
|
+
.dlg-att input[type=text] { flex: 1; min-width: 180px; width: auto; }
|
|
244
|
+
.dlg-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
|
245
|
+
.dlg-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 4px 6px 4px 10px; border-radius: 999px; background: var(--selected); color: var(--text); font-size: 12px; }
|
|
246
|
+
.dlg-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
247
|
+
.dlg-chip button { border: 0; background: none; color: var(--text-3); cursor: pointer; padding: 2px; display: inline-flex; }
|
|
248
|
+
.dlg-chip.reading { background: var(--hover); color: var(--text-3); padding-right: 10px; }
|
|
249
|
+
.dlg-chip .ic svg, .dlg-att .ic svg { width: 14px; height: 14px; }
|
|
250
|
+
.vit-filters { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
|
|
251
|
+
.vit-filter { border: 1px solid var(--ui-line); background: none; border-radius: 999px; color: var(--text-2); font: inherit; font-size: 12px; padding: 6px 12px; cursor: pointer; }
|
|
252
|
+
.vit-filter:hover { background: var(--hover); }
|
|
253
|
+
.vit-filter.active { background: var(--text); color: var(--canvas-bg); border-color: var(--text); }
|
|
254
|
+
.vit-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; max-height: min(60vh, 560px); overflow-y: auto; padding: 2px; }
|
|
255
|
+
.vit-card { display: flex; flex-direction: column; gap: 6px; text-align: left; padding: 10px; border: 1px solid var(--ui-line); border-radius: 10px; background: var(--chrome); color: var(--text); font: inherit; cursor: pointer; }
|
|
256
|
+
.vit-card:hover, .vit-card:focus-visible { border-color: var(--brand); box-shadow: var(--shadow-2); outline: none; }
|
|
257
|
+
.vit-card[hidden] { display: none; }
|
|
258
|
+
.vit-card b { font-size: 13px; font-weight: 600; }
|
|
259
|
+
.vit-card .d { font-size: 11px; color: var(--text-3); line-height: 1.45; }
|
|
260
|
+
.vit-sw { display: flex; height: 54px; border-radius: 6px; overflow: hidden; margin-bottom: 4px; }
|
|
261
|
+
.vit-sw i { flex: 1; }
|
|
262
|
+
.vit-sw i:first-child { flex: 2.4; }
|
|
263
|
+
@media (max-width: 640px) { .dlg-two { grid-template-columns: 1fr; } }
|
|
264
|
+
|
|
265
|
+
/* vitrine Modelo pronto: capa desenhada de verdade (16:9) no lugar das barras de cor */
|
|
266
|
+
.vit-intro { margin: -4px 0 14px; color: var(--text-2); font-size: 13px; line-height: 1.5; }
|
|
267
|
+
.vit-thumb { display: block; width: 100%; aspect-ratio: 16 / 9; border-radius: 8px; overflow: hidden; margin-bottom: 10px; box-shadow: inset 0 0 0 1px var(--ui-line); }
|
|
268
|
+
.vit-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
|
|
269
|
+
.ldlg.drop-over { outline: 2px dashed var(--brand); outline-offset: -6px; }
|
|
270
|
+
.ldlg label .muted { color: var(--text-3); font-weight: 400; }
|
|
271
|
+
.dlg-ask { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border: 1px solid var(--brand); border-radius: 8px; color: var(--text); }
|
|
272
|
+
.dlg-ask b { font-weight: 600; font-size: 13px; }
|
|
273
|
+
.dlg-ask-opts { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
274
|
+
.dlg-ask-free { display: flex; gap: 6px; }
|
|
275
|
+
.dlg-ask-free input { flex: 1; }
|