primocode 8.36.0 → 8.38.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.
@@ -511,8 +511,17 @@
511
511
  }
512
512
 
513
513
  .el.dispositivo[data-forma="celular"] { width: 100%; }
514
+ /* O TETO DO APARELHO ACOMPANHA O QUADRO. Ele era 780px fixos, calibrados em
515
+ 1920x1080 — e num vídeo vertical de 1080x1920 isso deixa o celular ocupando
516
+ um terço da altura, boiando no meio do branco. Num anúncio o aparelho é o
517
+ assunto da cena: ele ocupa a tela. `--alto` é a altura da cena, posta pelo
518
+ renderCena. */
514
519
  .el.dispositivo[data-forma="celular"] .moldura {
515
- height: min(100%, 780px); width: auto; max-width: 100%;
520
+ /* Altura em PIXEL vindo do quadro, sem porcentagem: `min(100%, …)` dentro de
521
+ um pai de altura automática é percentagem circular — o navegador desiste
522
+ dela e o aparelho volta a ser medido pela largura. Medido: 408px de altura
523
+ num quadro de 1920, um quinto da tela. */
524
+ height: calc(var(--alto, 1080px) * .62); width: auto; max-width: 100%;
516
525
  aspect-ratio: 9 / 19;
517
526
  border-radius: 42px; padding: 12px;
518
527
  }
@@ -761,8 +770,14 @@
761
770
  .cena.animar .el[data-an="cortina"] { animation-name: anCortina; animation-duration: .85s; }
762
771
  .cena.animar .el[data-an="elastico"] { animation-name: anElastico; animation-duration: .95s; }
763
772
 
764
- /* palavra a palavra — cada palavra entra sozinha */
765
- .el.txt .pal { display: inline-block; opacity: 0; }
773
+ /* palavra a palavra — cada palavra entra sozinha.
774
+
775
+ A palavra nasce VISÍVEL, e quem a esconde é a animação (com `both`, o
776
+ estado inicial do keyframe já vale antes de ela começar). Com `opacity: 0`
777
+ aqui na base, toda cena com `anim: "palavra"` saía EM BRANCO fora do player
778
+ — na miniatura, na prévia parada do editor, em qualquer render estático.
779
+ Texto que some sem erro nenhum é o defeito mais caro deste arquivo. */
780
+ .el.txt .pal { display: inline-block; }
766
781
  .cena.animar .el[data-an="palavra"] { animation: none; opacity: 1; }
767
782
  .cena.animar .el[data-an="palavra"] .pal {
768
783
  animation: anSubir .58s cubic-bezier(.22, 1, .36, 1) both;
@@ -933,3 +948,292 @@
933
948
  display: grid; place-items: center; min-height: 0; overflow: visible;
934
949
  }
935
950
  .cena .fluxo .lado-imagem.com-aparelho > .el { max-height: 100%; }
951
+
952
+ /* ══ O KIT DE ANÚNCIO ═══════════════════════════════════════════════════════
953
+ Nasceu de um vídeo de referência mandado pelo dono — um comercial de
954
+ fintech — com uma frase só: "ainda não tá bom, tá genérico. Quero nesse
955
+ nível." Medindo a peça de hoje contra aquela, o que faltava não era tema
956
+ nem cor (tema claro e `marca.cor` já existiam): era o PRODUTO.
957
+ ══════════════════════════════════════════════════════════════════════════ */
958
+
959
+ /* ── cartão ───────────────────────────────────────────────────────────────
960
+ A proporção é a de verdade (85,6 × 54 mm = 1,586). Ela importa mais que o
961
+ desenho: um retângulo na proporção errada não é lido como cartão por mais
962
+ chip que tenha. */
963
+ .el.cartao {
964
+ --cc: var(--c-tom);
965
+ width: min(100%, 620px);
966
+ perspective: 1400px;
967
+ }
968
+ .el.cartao .cartao-corpo {
969
+ position: relative;
970
+ aspect-ratio: 1.586;
971
+ border-radius: 6.2%;
972
+ padding: 7% 7.5%;
973
+ display: flex; flex-direction: column; justify-content: space-between;
974
+ color: #fff;
975
+ /* Duas fontes de luz e uma sombra longa: é o que separa "objeto pousado na
976
+ cena" de "retângulo colado por cima". */
977
+ background:
978
+ radial-gradient(120% 140% at 12% 4%, rgba(255, 255, 255, .30), transparent 52%),
979
+ linear-gradient(145deg,
980
+ color-mix(in srgb, var(--cc) 88%, #fff),
981
+ var(--cc) 46%,
982
+ color-mix(in srgb, var(--cc) 72%, #000) 100%);
983
+ box-shadow:
984
+ inset 0 1px 0 rgba(255, 255, 255, .38),
985
+ inset 0 -1px 0 rgba(0, 0, 0, .22),
986
+ 0 2.2% 5% -1% rgba(0, 0, 0, .45);
987
+ transform: rotate(-1.6deg);
988
+ }
989
+ /* O reflexo diagonal. Sem ele o plástico vira papel colorido. */
990
+ .el.cartao .cartao-brilho {
991
+ position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
992
+ background: linear-gradient(102deg, transparent 34%, rgba(255, 255, 255, .20) 46%,
993
+ rgba(255, 255, 255, .05) 54%, transparent 62%);
994
+ }
995
+ .el.cartao .cartao-topo {
996
+ display: flex; align-items: baseline; justify-content: space-between; gap: 1em;
997
+ }
998
+ .el.cartao .cartao-marca {
999
+ font-weight: 800; font-size: 6.4cqw; letter-spacing: -.01em;
1000
+ }
1001
+ .el.cartao .cartao-variante {
1002
+ font-size: 3.4cqw; letter-spacing: .18em; text-transform: uppercase;
1003
+ opacity: .82; font-weight: 600;
1004
+ }
1005
+ .el.cartao .cartao-meio { display: flex; align-items: center; gap: 4%; }
1006
+ /* O chip: dourado, com os contatos. É o detalhe que mais faz o desenho ser
1007
+ reconhecido — some ele e sobra um cartão de visita. */
1008
+ .el.cartao .cartao-chip {
1009
+ width: 13%; aspect-ratio: 1.32; border-radius: 14%;
1010
+ background: linear-gradient(150deg, #f7e3a1, #d9b558 46%, #b8912f);
1011
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .18);
1012
+ position: relative; flex: none;
1013
+ }
1014
+ .el.cartao .cartao-chip::before,
1015
+ .el.cartao .cartao-chip::after {
1016
+ content: ""; position: absolute; left: 12%; right: 12%; height: 1px;
1017
+ background: rgba(0, 0, 0, .28);
1018
+ }
1019
+ .el.cartao .cartao-chip::before { top: 36%; }
1020
+ .el.cartao .cartao-chip::after { top: 64%; }
1021
+ .el.cartao .cartao-onda { width: 7%; opacity: .9; display: block; flex: none; }
1022
+ .el.cartao .cartao-onda svg { width: 100%; height: auto; display: block; }
1023
+ .el.cartao .cartao-numero {
1024
+ font-family: var(--f-mono);
1025
+ font-size: 5.6cqw; letter-spacing: .06em; opacity: .95;
1026
+ }
1027
+ .el.cartao .cartao-pe {
1028
+ display: flex; justify-content: space-between; gap: 1em;
1029
+ font-size: 3.1cqw; letter-spacing: .13em; text-transform: uppercase;
1030
+ opacity: .8; font-weight: 600;
1031
+ }
1032
+ /* As medidas de dentro são `cqw` — por cento da LARGURA DO CARTÃO, não da
1033
+ tela. Sem o contexto de contêiner o mesmo cartão sai com o chip do tamanho
1034
+ de uma unha na vitrine e do tamanho de uma caixa na cena cheia. */
1035
+ .el.cartao .cartao-corpo { container-type: inline-size; }
1036
+
1037
+ .el.cartao[data-face="verso"] .cartao-corpo { transform: rotate(1.6deg); }
1038
+ .el.cartao[data-mov="flutuar"] .cartao-corpo { animation: cartao-flutua 6s ease-in-out infinite; }
1039
+ .el.cartao[data-mov="girar"] .cartao-corpo { animation: cartao-gira 9s ease-in-out infinite; }
1040
+ @keyframes cartao-flutua {
1041
+ 0%, 100% { transform: rotate(-1.6deg) translateY(0); }
1042
+ 50% { transform: rotate(-.6deg) translateY(-2.2%); }
1043
+ }
1044
+ @keyframes cartao-gira {
1045
+ 0%, 100% { transform: rotate(-1.6deg) rotateY(-16deg); }
1046
+ 50% { transform: rotate(-1.6deg) rotateY(16deg); }
1047
+ }
1048
+ @media (prefers-reduced-motion: reduce) {
1049
+ .el.cartao .cartao-corpo { animation: none; }
1050
+ }
1051
+
1052
+ /* ── a tela do app ────────────────────────────────────────────────────────
1053
+ Vale sozinha na cena e vale dentro do `dispositivo`. É o mesmo elemento de
1054
+ propósito: com dois, o print da campanha e a tela do celular divergiriam na
1055
+ primeira mudança. */
1056
+ .el.app {
1057
+ width: 100%;
1058
+ font-size: calc(var(--u, 10px) * 3.4);
1059
+ display: flex; flex-direction: column; gap: 4%;
1060
+ text-align: left;
1061
+ background: #fff; color: #10161d;
1062
+ border-radius: 22px; padding: 7% 6.5%;
1063
+ box-shadow: 0 18px 50px rgba(0, 0, 0, .16);
1064
+ }
1065
+ .el.app[data-escuro] { background: #0e1319; color: #eaf0f6; box-shadow: none; }
1066
+ .el.app .app-topo {
1067
+ display: flex; align-items: center; justify-content: space-between;
1068
+ font-size: .62em; font-weight: 700; opacity: .75;
1069
+ }
1070
+ .el.app .app-topo i {
1071
+ width: 2.2em; height: .34em; border-radius: 999px;
1072
+ background: currentColor; opacity: .25; display: block;
1073
+ }
1074
+ .el.app .app-valor { display: flex; flex-direction: column; gap: .12em; }
1075
+ .el.app .app-valor small { font-size: .5em; opacity: .6; font-weight: 600; }
1076
+ .el.app .app-valor strong {
1077
+ font-size: 1.5em; font-weight: 800; letter-spacing: -.02em;
1078
+ font-variant-numeric: tabular-nums;
1079
+ }
1080
+ .el.app .app-linhas { display: flex; flex-direction: column; }
1081
+ /* O FIO entre as linhas é o que faz o olho ler "extrato". Sem ele são frases
1082
+ empilhadas, que é como a tela saía antes. */
1083
+ .el.app .app-linha {
1084
+ display: flex; align-items: center; justify-content: space-between; gap: 1em;
1085
+ padding: .62em 0; font-size: .56em;
1086
+ border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);
1087
+ }
1088
+ .el.app .app-linha:first-child { border-top: 0; }
1089
+ .el.app .app-linha span { opacity: .82; }
1090
+ .el.app .app-linha b { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
1091
+ .el.app .app-botao {
1092
+ margin-top: auto;
1093
+ background: var(--c-tom); color: #fff;
1094
+ border-radius: 999px; padding: .78em 1em;
1095
+ text-align: center; font-weight: 700; font-size: .58em;
1096
+ }
1097
+
1098
+ /* Dentro do aparelho a tela do app OCUPA o vidro: com o padrão do
1099
+ `dispositivo` (conteúdo centrado com folga) ela ficava boiando no meio, e o
1100
+ que se vê num celular de verdade é a tela cheia. */
1101
+ .el.dispositivo .tela { justify-content: flex-start; }
1102
+ .el.dispositivo .tela > .el.app {
1103
+ flex: 1; border-radius: 0; box-shadow: none;
1104
+ margin: -26px -20px; padding: 34px 22px 26px;
1105
+ background: transparent; color: var(--c-texto);
1106
+ }
1107
+
1108
+ /* ── vitrine ──────────────────────────────────────────────────────────────
1109
+ A linha de produtos com um escolhido. O item atual vem à frente; os outros
1110
+ recuam — sem isso são quatro cartões do mesmo tamanho e ninguém sabe qual
1111
+ está sendo oferecido. */
1112
+ .el.vitrine {
1113
+ width: 100%; font-size: calc(var(--u, 10px) * 3.4);
1114
+ display: flex; flex-direction: column; gap: 1.2em;
1115
+ }
1116
+ .el.vitrine .vitrine-titulo {
1117
+ text-align: center; font-size: .62em; font-weight: 700;
1118
+ letter-spacing: .04em; opacity: .82;
1119
+ }
1120
+ .el.vitrine .vitrine-fila {
1121
+ display: flex; align-items: center; justify-content: center; gap: 2.2%;
1122
+ }
1123
+ .el.vitrine .vitrine-item {
1124
+ flex: 1 1 0; min-width: 0;
1125
+ display: flex; flex-direction: column; align-items: center; gap: .5em;
1126
+ /* Recuado, não apagado: a .42 sobre fundo escuro os outros cartões somem, e
1127
+ uma vitrine com um produto só não é vitrine. */
1128
+ opacity: .58; transform: scale(.86);
1129
+ transition: opacity .4s ease, transform .4s ease;
1130
+ }
1131
+ .el.vitrine .vitrine-item.atual { opacity: 1; transform: scale(1.06); z-index: 2; }
1132
+ .el.vitrine .vitrine-item small {
1133
+ font-size: .42em; opacity: .75; text-align: center; font-weight: 600;
1134
+ }
1135
+ .el.vitrine .el.cartao { width: 100%; }
1136
+
1137
+ /* ── assinatura ───────────────────────────────────────────────────────────
1138
+ O fim do anúncio: o logo sozinho, grande, sobre a cor da casa. Ela toma a
1139
+ cena INTEIRA porque é isso que uma assinatura é — se dividisse espaço com
1140
+ outra coisa, seria mais um bloco em vez do ponto final. */
1141
+ .el.assinatura {
1142
+ position: absolute; inset: 0; z-index: 4;
1143
+ font-size: calc(var(--u, 10px) * 3);
1144
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
1145
+ gap: .5em; text-align: center; padding: 8%;
1146
+ }
1147
+ .el.assinatura[data-sobre="marca"] { background: var(--c-tom); color: #fff; }
1148
+ .el.assinatura[data-sobre="claro"] { background: #fff; color: #10161d; }
1149
+ .el.assinatura[data-sobre="escuro"] { background: #080b0e; color: #fff; }
1150
+ .el.assinatura .assinatura-logo { width: min(52%, 520px); height: auto; display: block; }
1151
+ .el.assinatura .assinatura-nome {
1152
+ font-size: 3.6em; font-weight: 800; letter-spacing: -.03em; line-height: 1;
1153
+ }
1154
+ .el.assinatura .assinatura-frase { font-size: .62em; opacity: .82; letter-spacing: .02em; }
1155
+
1156
+ /* Título de anúncio quebra EQUILIBRADO. "Um cartão. Seu jeito." saía em
1157
+ quatro linhas — três palavras e um órfão —, e é assim que uma frase curta
1158
+ vira um bloco desengonçado no meio do quadro. */
1159
+ .el.texto.titulo, .el.texto[data-papel="titulo"] { text-wrap: balance; }
1160
+
1161
+ /* ═══════════════════════════════════════════════════════════════════════
1162
+ A COMPOSIÇÃO DE SLIDE (ver comporCabecaCorpo, em render.js).
1163
+
1164
+ Cabeça ancorada em cima, corpo centrado no que sobra — e o corpo em escala
1165
+ de PROJETOR. Os tamanhos de antes (lista 34px, cartão 27/19, tabela 22)
1166
+ foram calibrados para caber; num quadro de 1920 projetado numa sala eles
1167
+ somem, e o que sobra é o vazio em volta. Só dentro desta composição: a cena
1168
+ de vídeo com um título sozinho, e a capa, continuam como eram.
1169
+ ═══════════════════════════════════════════════════════════════════════ */
1170
+
1171
+ .cena .fluxo[data-composicao="cabeca-corpo"] { justify-content: flex-start; }
1172
+ .cena .fluxo[data-composicao="cabeca-corpo"] > .corpo-inicio { margin-top: auto; }
1173
+ .cena .fluxo[data-composicao="cabeca-corpo"] > .corpo-fim { margin-bottom: auto; }
1174
+ /* O título respira antes do corpo; o chapéu cola no título. */
1175
+ .cena .fluxo[data-composicao="cabeca-corpo"] > .el.txt.titulo { margin-bottom: calc(var(--u, 19px) * .4); }
1176
+ .cena .fluxo[data-composicao="cabeca-corpo"] > .el.txt.chapeu { margin-bottom: calc(var(--u, 19px) * -.9); }
1177
+
1178
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.lista { gap: calc(24px * var(--esc, 1)); }
1179
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.lista .item {
1180
+ font-size: calc(40px * var(--esc, 1));
1181
+ line-height: 1.38;
1182
+ padding-left: calc(50px * var(--esc, 1));
1183
+ }
1184
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.lista .item::before { width: 14px; height: 14px; top: .56em; }
1185
+
1186
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.cartoes { gap: 28px; }
1187
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.cartoes .cartao {
1188
+ padding: 40px 42px;
1189
+ min-height: calc(var(--alto, 1080px) * .27);
1190
+ gap: 14px;
1191
+ border-radius: 24px;
1192
+ }
1193
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.cartoes .cartao b { font-size: 36px; line-height: 1.15; }
1194
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.cartoes .cartao span { font-size: 25px; line-height: 1.45; }
1195
+
1196
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.numeros { gap: calc(40px * var(--esc, 1)); }
1197
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.numeros .num { gap: 14px; }
1198
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.numeros .num b { font-size: var(--tam-num, calc(140px * var(--esc, 1))); }
1199
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.numeros .num span { font-size: calc(27px * var(--esc, 1)); }
1200
+
1201
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.tabela table { font-size: 29px; }
1202
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.tabela th,
1203
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.tabela td { padding: 22px 24px; }
1204
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.tabela th { font-size: 18px; }
1205
+
1206
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.codigo { font-size: 26px; }
1207
+
1208
+ /* O rodapé da apresentação: nome do deck e "03 / 08". Discreto — é âncora,
1209
+ não conteúdo. */
1210
+ .cena .rodape {
1211
+ position: absolute;
1212
+ z-index: 2;
1213
+ display: flex;
1214
+ justify-content: space-between;
1215
+ align-items: baseline;
1216
+ gap: 24px;
1217
+ font-family: var(--f-corpo);
1218
+ font-size: calc(var(--u, 19px) * .95);
1219
+ letter-spacing: .04em;
1220
+ color: var(--c-fraco);
1221
+ opacity: .82;
1222
+ pointer-events: none;
1223
+ white-space: nowrap;
1224
+ }
1225
+ .cena .rodape span:first-child { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
1226
+ .cena .rodape span:last-child { font-variant-numeric: tabular-nums; }
1227
+
1228
+ /* Os números grandes NÃO quebram: coluna do tamanho do conteúdo, distribuídas.
1229
+ Com três colunas iguais de um terço, "R$ 200 bi" a 140px partia em duas
1230
+ linhas — o `!important` existe porque o render escreve `repeat(n, 1fr)`
1231
+ inline, e é justamente isso que se troca aqui. */
1232
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.numeros {
1233
+ grid-template-columns: none !important;
1234
+ grid-auto-flow: column;
1235
+ grid-auto-columns: max-content;
1236
+ justify-content: space-between;
1237
+ column-gap: calc(var(--u, 19px) * 3);
1238
+ }
1239
+ .cena .fluxo[data-composicao="cabeca-corpo"] .el.numeros .num b { white-space: nowrap; }