/* ========================================================================= Sistema visual das apostilas da LASER, compartilhado por todas as edições. Paginação A4 via Paged.js. Identidade da liga: prussiano, âmbar, laranja e vermelho, tirados da logo oficial (laser.cin.ufpe.br). Uma apostila nova só precisa de: e usar as classes documentadas aqui. ========================================================================= */ :root { /* Paleta da LASER, extraída da logo oficial (laser.cin.ufpe.br). O gradiente é o próprio "feixe" da marca. */ --prussiano: #003049; --vermelho: #D62828; --laranja: #F77F00; --ambar: #FCBF49; --creme: #EAE2B7; /* O laranja da marca é vibrante demais para texto: 2,63:1 sobre branco. Esta versão queimada mantém a matiz e passa em AA (4,74:1). */ --laranja-texto: #B85800; --tinta: #062639; --tinta-2: #33566a; --tinta-3: #557080; /* 5,23:1 no branco e 4,94:1 na linha zebrada */ --linha: #c2d2db; --linha-suave: #dde7ed; --fundo-suave: #f5f9fb; /* O feixe da marca. Use APENAS em superfície grande e decorativa: uma faixa, um traço largo, o desenho da capa. Nunca recortado em texto: cinco paradas de cor num glifo viram arco-íris e ainda quebram o contraste. */ --marca: linear-gradient(90deg, var(--prussiano), var(--creme), var(--ambar), var(--laranja), var(--vermelho)); } /* ------------------------------------------------------------------------- 1. Página A4 ------------------------------------------------------------------------- */ @page { size: A4; margin: 20mm 18mm 18mm 18mm; @bottom-left { content: string(titulo-corrente); font-family: "Inter", sans-serif; font-size: 7.5pt; color: #94a3b8; padding-bottom: 4mm; } @bottom-right { content: counter(page); font-family: "Outfit", sans-serif; font-size: 9pt; font-weight: 700; color: #64748b; padding-bottom: 4mm; } } /* Capa e contracapa sem cabeçalho, rodapé ou margem. */ @page capa { margin: 0; @bottom-left { content: none; } @bottom-right { content: none; } } .pagina-capa { page: capa; /* Sem break-after: todo .capitulo já traz break-before, e as duas juntas podem gerar uma página em branco depois da capa. */ } /* Capa: clara e minimalista. O desenho é o feixe da LASER atravessando a página. Conceitual, não decorativo. */ .capa { width: 210mm; height: 297mm; background: #fdfdfb; color: var(--tinta); display: flex; flex-direction: column; padding: 30mm 24mm 24mm; position: relative; overflow: hidden; } .capa-curvas { position: absolute; inset: 0; width: 210mm; height: 297mm; pointer-events: none; } /* O desenho fica no fundo; todo o resto sobe acima dele. Precisa excluir .capa-curvas: mesma especificidade sobrescreveria o absolute. */ .capa > *:not(.capa-curvas) { position: relative; z-index: 1; } .capa-marca { display: flex; align-items: center; gap: 4mm; margin-bottom: 26mm; } .capa-marca img { height: 9mm; width: auto; } .capa-marca span { font-size: 8pt; line-height: 1.35; color: var(--tinta-3); border-left: 0.6pt solid var(--linha); padding-left: 4mm; } .capa-selo { font-family: "Outfit", sans-serif; font-size: 8pt; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; color: var(--laranja-texto); margin-bottom: 5mm; } .capa-titulo { font-family: "Outfit", sans-serif; font-size: 42pt; font-weight: 300; line-height: 1.02; letter-spacing: -0.025em; margin: 0 0 6mm; color: var(--prussiano); max-width: 140mm; } .capa-titulo strong { font-weight: 700; } .capa-sub { font-size: 11pt; font-weight: 300; line-height: 1.55; color: var(--tinta-2); max-width: 116mm; text-align: left; margin-bottom: 0; } .capa-rodape { margin-top: auto; display: flex; justify-content: space-between; align-items: flex-end; gap: 8mm; font-size: 8pt; color: var(--tinta-3); line-height: 1.6; border-top: 0.6pt solid var(--linha); padding-top: 5mm; } .capa-rodape strong { color: var(--tinta); font-weight: 600; display: block; font-size: 9pt; margin-bottom: 0.8mm; } /* ------------------------------------------------------------------------- 2. Base tipográfica ------------------------------------------------------------------------- */ * { box-sizing: border-box; } html { /* Faz fundos e cores chegarem ao PDF em vez de imprimirem em branco. */ -webkit-print-color-adjust: exact; print-color-adjust: exact; } body { margin: 0; font-family: "Inter", system-ui, -apple-system, sans-serif; font-size: 10pt; line-height: 1.62; color: var(--tinta-2); hyphens: auto; } p { margin: 0 0 3.2mm; text-align: justify; /* Nunca deixa uma ou duas linhas soltas no pé nem no topo da página. */ orphans: 3; widows: 3; } strong { color: var(--tinta); font-weight: 600; } a { color: #b34700; text-decoration: none; border-bottom: 0.6pt solid #f7c9a0; } ul, ol { margin: 0 0 3.5mm; padding-left: 5.5mm; } li { margin-bottom: 1.4mm; orphans: 2; widows: 2; } li::marker { color: var(--laranja-texto); } /* ------------------------------------------------------------------------- 3. Capítulos e títulos ------------------------------------------------------------------------- */ .capitulo { break-before: page; } .capitulo-abertura { display: flex; align-items: flex-start; gap: 5mm; margin-bottom: 7mm; padding-bottom: 4mm; border-bottom: 2.2pt solid var(--tinta); } .capitulo-numero { font-family: "Outfit", sans-serif; font-size: 44pt; font-weight: 300; /* leve, para não competir com o título em 800 */ line-height: 0.8; letter-spacing: -0.03em; color: var(--laranja-texto); flex-shrink: 0; font-variant-numeric: lining-nums; } h1, h2, h3, h4 { font-family: "Outfit", sans-serif; color: var(--tinta); margin: 0; break-after: avoid; text-align: left; } h2 { font-size: 19pt; font-weight: 800; line-height: 1.1; letter-spacing: -0.01em; /* Alimenta o rodapé com o capítulo corrente. */ string-set: titulo-corrente content(); } .capitulo-abertura .subtitulo { font-family: "Inter", sans-serif; font-size: 9pt; font-weight: 400; color: var(--tinta-3); margin-top: 1.5mm; line-height: 1.45; } h3 { font-size: 12.5pt; break-before: auto; font-weight: 700; margin: 7mm 0 2.5mm; padding-left: 3mm; border-left: 2.5pt solid var(--laranja); } h4 { font-size: 10pt; font-weight: 700; margin: 5mm 0 2mm; text-transform: uppercase; letter-spacing: 0.06em; color: var(--tinta-3); } /* ------------------------------------------------------------------------- 3.1. Coesão entre blocos O fragmentador quebra onde couber, e o resultado padrão separa coisas que pertencem juntas: a frase que apresenta uma tabela numa página e a tabela na seguinte. Estas duas classes resolvem, e devem ser usadas sempre que um trecho só faz sentido lido de uma vez. ------------------------------------------------------------------------- */ /* Na frase que apresenta o que vem logo abaixo. Proíbe quebra logo depois dela. */ .junto { break-after: avoid; } /* NÃO declare break-before:avoid de forma genérica (h3 + *, .junto + *). Testado: o Paged.js encadeia as recusas e produz páginas com 2% de conteúdo, além de partir palavras entre páginas. Para manter um título junto do que ele apresenta, envolva os dois em .grupo, que usa break-inside:avoid, o único controle que o fragmentador aplica de forma previsível. */ /* No wrapper de um conjunto curto que precisa caber inteiro na mesma página (uma introdução mais os itens que ela apresenta, por exemplo). */ .grupo { break-inside: avoid; } /* ------------------------------------------------------------------------- 4. Caixas de destaque Cada tipo tem um papel didático fixo. Não misture. ------------------------------------------------------------------------- */ .caixa { break-inside: avoid; margin: 4.5mm 0; padding: 3.5mm 4mm; border-radius: 2mm; border-left: 2.5pt solid var(--cor-caixa, var(--laranja)); background: var(--fundo-caixa, #fff8ec); font-size: 9pt; line-height: 1.55; } .caixa p { margin-bottom: 2mm; text-align: left; } .caixa p:last-child { margin-bottom: 0; } .caixa-titulo { font-family: "Outfit", sans-serif; font-weight: 800; font-size: 8.5pt; text-transform: uppercase; letter-spacing: 0.07em; color: var(--cor-caixa, var(--laranja)); margin-bottom: 1.5mm; } .caixa.atencao { --cor-caixa: #a35a00; --fundo-caixa: #fff8ea; } .caixa.erro { --cor-caixa: #b01f1f; --fundo-caixa: #fdf1f1; } .caixa.dica { --cor-caixa: #0b6b52; --fundo-caixa: #eefaf5; } .caixa.curiosidade { --cor-caixa: #003049; --fundo-caixa: #eff6fa; } /* ------------------------------------------------------------------------- 5. Tabelas ------------------------------------------------------------------------- */ table { width: 100%; border-collapse: collapse; font-size: 8.5pt; margin: 4mm 0 5mm; break-inside: avoid; } caption { caption-side: bottom; font-size: 7.5pt; color: var(--tinta-3); text-align: left; padding-top: 1.8mm; } thead { break-inside: avoid; break-after: avoid; /* Repete o cabeçalho quando a tabela atravessa a página. */ display: table-header-group; } tbody tr { break-inside: avoid; } /* As tabelas de 12 linhas (uma por série) podem dividir: mantê-las inteiras empurrava a tabela toda e deixava quase metade da página em branco. */ table.compacta { break-inside: auto; } th { font-family: "Outfit", sans-serif; font-weight: 700; font-size: 7.5pt; text-transform: uppercase; letter-spacing: 0.05em; text-align: left; color: #fff; background: var(--tinta); padding: 2.2mm 2.5mm; } td { padding: 2.2mm 2.5mm; border-bottom: 0.5pt solid var(--linha-suave); vertical-align: top; } tbody tr:nth-child(even) { background: var(--fundo-suave); } td.destaque { font-weight: 600; color: var(--tinta); } td.sim { color: #0b6b52; font-weight: 600; } td.nao { color: var(--tinta-3); } /* ------------------------------------------------------------------------- 6. Código ------------------------------------------------------------------------- */ pre { break-inside: avoid; margin: 4mm 0; padding: 4mm 4.5mm; background: #062639; border-radius: 2mm; color: #e2e8f0; font-family: "JetBrains Mono", ui-monospace, "Courier New", monospace; font-size: 8pt; line-height: 1.6; white-space: pre-wrap; overflow-wrap: break-word; } code { font-family: "JetBrains Mono", ui-monospace, "Courier New", monospace; font-size: 8.6pt; background: #f2f6f8; color: #b34700; padding: 0.4mm 1.2mm; border-radius: 1mm; } pre code { background: none; color: inherit; padding: 0; font-size: inherit; } .c-com { color: #94a3b8; font-style: italic; } /* comentário */ .c-key { color: #c4b5fd; } /* palavra-chave */ .c-fun { color: #7dd3fc; } /* função */ .c-str { color: #86efac; } /* string */ .c-num { color: #fdba74; } /* número */ .c-pre { color: #f9a8d4; } /* diretiva */ .legenda-codigo { font-size: 7.5pt; color: var(--tinta-3); margin: -2.5mm 0 4mm; } /* ------------------------------------------------------------------------- 7. Figuras ------------------------------------------------------------------------- */ figure { break-inside: avoid; margin: 5mm 0; text-align: center; } figure img { max-width: 100%; height: auto; border-radius: 1.5mm; } /* Diagramas desenhados em SVG dentro do próprio documento, para herdarem a paleta da liga. Traço fino e sem preenchimento pesado: imprimem bem. */ .diagrama { width: 100%; height: auto; display: block; } .diagrama text { font-family: "Inter", system-ui, sans-serif; fill: var(--tinta-2); } .diagrama .rotulo { font-family: "Outfit", sans-serif; font-weight: 700; fill: var(--tinta); } .diagrama .miudo { fill: var(--tinta-3); } .diagrama .caixa { fill: #ffffff; stroke: var(--linha); stroke-width: 1.2; } .diagrama .caixa-destaque { fill: #fff6ea; stroke: var(--laranja); stroke-width: 1.4; } .diagrama .traco { stroke: var(--tinta-3); stroke-width: 1.2; fill: none; } .diagrama .onda { stroke: var(--prussiano); stroke-width: 1.8; fill: none; stroke-linejoin: round; } figcaption { font-size: 7.5pt; color: var(--tinta-3); margin-top: 2mm; text-align: left; line-height: 1.5; } /* ------------------------------------------------------------------------- 8. Grade de séries: cada chip com a cor que o site usa ------------------------------------------------------------------------- */ .grade-series { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm; margin: 4mm 0; } .chip { break-inside: avoid; border: 0.8pt solid var(--linha); border-top: 2.5pt solid var(--cor-chip, var(--laranja)); border-radius: 1.5mm; padding: 3mm 3.5mm; } .chip-nome { font-family: "Outfit", sans-serif; font-weight: 800; font-size: 11pt; line-height: 1.1; /* A cor da série fica na faixa superior do card, que é decoração e não precisa de contraste. Dez das doze cores reprovam em AA como texto (o amarelo do P4 dá 1,63:1 sobre branco), então o nome vai em tinta. */ color: var(--tinta); } .chip-papel { font-size: 7.5pt; font-weight: 600; color: var(--tinta-3); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 2mm; } .chip p { font-size: 8.2pt; line-height: 1.5; margin-bottom: 2mm; text-align: left; } .chip dl { margin: 0; font-size: 7.6pt; display: grid; grid-template-columns: auto 1fr; gap: 0.6mm 2mm; border-top: 0.5pt solid var(--linha-suave); padding-top: 1.8mm; } .chip dt { color: var(--tinta-3); font-weight: 500; } .chip dd { margin: 0; color: var(--tinta); font-weight: 600; } /* ------------------------------------------------------------------------- 9. Sumário: numeração de página resolvida pelo Paged.js ------------------------------------------------------------------------- */ .sumario { margin-top: 6mm; } .sumario a { display: flex; align-items: baseline; gap: 2mm; border: none; color: var(--tinta); text-decoration: none; padding: 1.8mm 0; border-bottom: 0.5pt solid var(--linha-suave); font-size: 10pt; } .sumario .num { font-family: "Outfit", sans-serif; font-weight: 700; color: var(--laranja-texto); min-width: 7mm; } .sumario .txt { font-weight: 600; } .sumario .pontos { flex: 1; border-bottom: 0.5pt dotted var(--linha); transform: translateY(-1mm); } .sumario a::after { content: target-counter(attr(href url), page); font-family: "Outfit", sans-serif; font-weight: 700; color: var(--tinta-3); } /* ------------------------------------------------------------------------- 10. Passos numerados da prática ------------------------------------------------------------------------- */ .passo { /* Indivisível: testado com break-inside:auto, o círculo com o número do passo ficava sozinho no pé da página, separado do próprio conteúdo. */ break-inside: avoid; display: grid; grid-template-columns: 8mm 1fr; gap: 3mm; margin-bottom: 5mm; } .passo-num { font-family: "Outfit", sans-serif; font-weight: 800; font-size: 12pt; color: #fff; background: var(--prussiano); width: 8mm; height: 8mm; border-radius: 50%; display: flex; align-items: center; justify-content: center; line-height: 1; } .passo h3 { margin-top: 0.5mm; border: none; padding: 0; } /* ------------------------------------------------------------------------- 11. Visual só de tela (Paged.js desenha as folhas) ------------------------------------------------------------------------- */ @media screen { body { background: radial-gradient(60rem 40rem at 50% -10rem, #eaf1f5 0%, transparent 70%), #dfe7ec; padding: 10mm 0 16mm; } /* Pilha de folhas centralizada na janela, com respiro entre elas. */ .pagedjs_pages { display: flex; flex-direction: column; align-items: center; gap: 9mm; width: 100%; max-width: none; } .pagedjs_page { background: #fff; box-shadow: 0 0 0 1px rgba(6, 38, 57, 0.07), 0 6px 22px -6px rgba(6, 38, 57, 0.22); border-radius: 1.5mm; margin: 0; transition: box-shadow 0.2s ease; } .pagedjs_page:hover { box-shadow: 0 0 0 1px rgba(6, 38, 57, 0.12), 0 10px 30px -8px rgba(6, 38, 57, 0.3); } /* A capa é sangria total: sem cantos arredondados brigando com o desenho. */ .pagedjs_page:first-child { border-radius: 0; } .aviso-carregando { font-family: "Inter", sans-serif; text-align: center; padding: 40mm 20mm; color: #5b7688; font-size: 11pt; } /* Leitura confortável: um pouco mais de corpo do que no papel. */ .pagedjs_page_content { font-size: 10.2pt; } } /* Telas estreitas: encolhe a folha inteira em vez de estourar a largura. */ @media screen and (max-width: 230mm) { .pagedjs_pages { transform: scale(calc(100vw / 232mm)); transform-origin: top center; } } /* ------------------------------------------------------------------------- 8. Regras Especiais para Impressão Física e Geração de PDF (@media print) ------------------------------------------------------------------------- */ @media print { .aviso-carregando { display: none !important; } /* BLOCO DE CÓDIGO - TEMA CLARO DE ALTO CONTRASTE Elimina o fundo escuro pesado no papel e resolve o problema de sangria de tinta (dot gain) que engolia as letras. */ pre { background: #f8fafc !important; border: 0.35mm solid #cbd5e1 !important; color: #0f172a !important; box-shadow: none !important; -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; } pre code { background: transparent !important; border: none !important; padding: 0 !important; color: #0f172a !important; font-weight: 500 !important; -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; } pre span { background: transparent !important; border: none !important; padding: 0 !important; } /* Cores de sintaxe de alta densidade e seguras para CMYK/P&B */ .c-com { color: #475569 !important; font-style: italic !important; } .c-key { color: #6b21a8 !important; font-weight: 600 !important; } .c-fun { color: #0369a1 !important; font-weight: 600 !important; } .c-str { color: #15803d !important; } .c-num { color: #b45309 !important; font-weight: 600 !important; } .c-pre { color: #be185d !important; font-weight: 600 !important; } /* Código inline (apenas fora do pre) */ :not(pre) > code { background: #f1f5f9 !important; color: #9a3412 !important; border: 0.2mm solid #cbd5e1 !important; padding: 0.4mm 1.2mm !important; border-radius: 1mm !important; -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; } }