diff --git a/docs/screenshots/01_hub_claro.png b/docs/screenshots/01_hub_claro.png index 83fd2bb..0e5c3e3 100644 Binary files a/docs/screenshots/01_hub_claro.png and b/docs/screenshots/01_hub_claro.png differ diff --git a/docs/screenshots/01_hub_escuro.png b/docs/screenshots/01_hub_escuro.png index c94a9f2..d08daa8 100644 Binary files a/docs/screenshots/01_hub_escuro.png and b/docs/screenshots/01_hub_escuro.png differ diff --git a/docs/screenshots/01_layout_claro.png b/docs/screenshots/01_layout_claro.png index 83fd2bb..0e5c3e3 100644 Binary files a/docs/screenshots/01_layout_claro.png and b/docs/screenshots/01_layout_claro.png differ diff --git a/docs/screenshots/02_diagnostico.png b/docs/screenshots/02_diagnostico.png index eb585ee..87f0654 100644 Binary files a/docs/screenshots/02_diagnostico.png and b/docs/screenshots/02_diagnostico.png differ diff --git a/docs/screenshots/02_diagnostico_claro.png b/docs/screenshots/02_diagnostico_claro.png index eb585ee..87f0654 100644 Binary files a/docs/screenshots/02_diagnostico_claro.png and b/docs/screenshots/02_diagnostico_claro.png differ diff --git a/docs/screenshots/02_diagnostico_escuro.png b/docs/screenshots/02_diagnostico_escuro.png index 1697968..0a2f1b7 100644 Binary files a/docs/screenshots/02_diagnostico_escuro.png and b/docs/screenshots/02_diagnostico_escuro.png differ diff --git a/docs/screenshots/02_layout_escuro.png b/docs/screenshots/02_layout_escuro.png index c94a9f2..d08daa8 100644 Binary files a/docs/screenshots/02_layout_escuro.png and b/docs/screenshots/02_layout_escuro.png differ diff --git a/docs/screenshots/03_configuracoes.png b/docs/screenshots/03_configuracoes.png index 2e7c5b0..e521f1b 100644 Binary files a/docs/screenshots/03_configuracoes.png and b/docs/screenshots/03_configuracoes.png differ diff --git a/docs/screenshots/03_configuracoes_claro.png b/docs/screenshots/03_configuracoes_claro.png index 2e7c5b0..e521f1b 100644 Binary files a/docs/screenshots/03_configuracoes_claro.png and b/docs/screenshots/03_configuracoes_claro.png differ diff --git a/docs/screenshots/03_configuracoes_escuro.png b/docs/screenshots/03_configuracoes_escuro.png index 0ebd4c9..ece2330 100644 Binary files a/docs/screenshots/03_configuracoes_escuro.png and b/docs/screenshots/03_configuracoes_escuro.png differ diff --git a/docs/screenshots/04_certificados_claro.png b/docs/screenshots/04_certificados_claro.png index 6552726..6a33154 100644 Binary files a/docs/screenshots/04_certificados_claro.png and b/docs/screenshots/04_certificados_claro.png differ diff --git a/docs/screenshots/04_certificados_escuro.png b/docs/screenshots/04_certificados_escuro.png index b2669e1..b11f997 100644 Binary files a/docs/screenshots/04_certificados_escuro.png and b/docs/screenshots/04_certificados_escuro.png differ diff --git a/docs/screenshots/05_validacao_claro.png b/docs/screenshots/05_validacao_claro.png index 96a57ce..4051699 100644 Binary files a/docs/screenshots/05_validacao_claro.png and b/docs/screenshots/05_validacao_claro.png differ diff --git a/docs/screenshots/05_validacao_escuro.png b/docs/screenshots/05_validacao_escuro.png index 74fef19..0aadcf2 100644 Binary files a/docs/screenshots/05_validacao_escuro.png and b/docs/screenshots/05_validacao_escuro.png differ diff --git a/docs/screenshots/06_solicitacao_claro.png b/docs/screenshots/06_solicitacao_claro.png index 718193e..235ca63 100644 Binary files a/docs/screenshots/06_solicitacao_claro.png and b/docs/screenshots/06_solicitacao_claro.png differ diff --git a/docs/screenshots/06_solicitacao_escuro.png b/docs/screenshots/06_solicitacao_escuro.png index be4b876..a1a0339 100644 Binary files a/docs/screenshots/06_solicitacao_escuro.png and b/docs/screenshots/06_solicitacao_escuro.png differ diff --git a/docs/screenshots/07_selos_claro.png b/docs/screenshots/07_selos_claro.png index 0e17c51..1f6606c 100644 Binary files a/docs/screenshots/07_selos_claro.png and b/docs/screenshots/07_selos_claro.png differ diff --git a/docs/screenshots/07_selos_escuro.png b/docs/screenshots/07_selos_escuro.png index 2ff3dbe..2dfb757 100644 Binary files a/docs/screenshots/07_selos_escuro.png and b/docs/screenshots/07_selos_escuro.png differ diff --git a/docs/screenshots/08_sobre_claro.png b/docs/screenshots/08_sobre_claro.png index d2d6a88..f646f01 100644 Binary files a/docs/screenshots/08_sobre_claro.png and b/docs/screenshots/08_sobre_claro.png differ diff --git a/docs/screenshots/08_sobre_escuro.png b/docs/screenshots/08_sobre_escuro.png index 2e095d4..9ca3fd1 100644 Binary files a/docs/screenshots/08_sobre_escuro.png and b/docs/screenshots/08_sobre_escuro.png differ diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/MainAppView.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/MainAppView.java index 5420450..3dd7577 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/MainAppView.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/MainAppView.java @@ -114,7 +114,7 @@ public final class MainAppView { brandFooter.setAlignment(Pos.CENTER); Node smallLogo = SvgIcons.cyberShieldLogo(16); Label lblBrandFoot = new Label("CyberCore"); - lblBrandFoot.setStyle("-fx-font-weight: bold; -fx-font-size: 11.5px;"); + lblBrandFoot.getStyleClass().addAll("cyber-version-label", "text-bold"); brandFooter.getChildren().addAll(smallLogo, lblBrandFoot); Label lblVersion = new Label("v" + CyberCoreUiConstants.APP_VERSION); @@ -174,15 +174,13 @@ public final class MainAppView { brandRow.setAlignment(Pos.CENTER_LEFT); Label lblAssinador = new Label("ASSINADOR"); - lblAssinador.getStyleClass().addAll("cyber-brand-title", "serpro-header-title"); - lblAssinador.setStyle("-fx-font-weight: 300; -fx-opacity: 0.85;"); + lblAssinador.getStyleClass().addAll("cyber-brand-title", "serpro-header-title", "cyber-brand-prefix"); Label lblSep = new Label("|"); - lblSep.setStyle("-fx-font-size: 16px; -fx-opacity: 0.4;"); + lblSep.getStyleClass().add("cyber-brand-separator"); Label lblBrand = new Label("CyberCore"); - lblBrand.getStyleClass().addAll("cyber-brand-title", "serpro-header-brand"); - lblBrand.setStyle("-fx-font-weight: bold;"); + lblBrand.getStyleClass().addAll("cyber-brand-title", "serpro-header-brand", "text-bold"); brandRow.getChildren().addAll(lblAssinador, lblSep, lblBrand); @@ -225,7 +223,7 @@ public final class MainAppView { iconBox.setAlignment(Pos.CENTER); Label label = new Label(dark ? "Modo Claro" : "Modo Escuro"); - label.setStyle("-fx-font-size: 11.5px; -fx-font-weight: bold;"); + label.getStyleClass().add("text-bold"); content.getChildren().addAll(iconBox, label); themeToggleBtn.setGraphic(content); diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/PdfCertificateSignDialog.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/PdfCertificateSignDialog.java index c9d7bde..1f269d7 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/PdfCertificateSignDialog.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/PdfCertificateSignDialog.java @@ -167,15 +167,15 @@ public final class PdfCertificateSignDialog { summaryGrid.setVgap(6); Label lblDocTitle = new Label("Arquivo:"); - lblDocTitle.setStyle("-fx-font-weight: bold; -fx-text-fill: -fx-text-secondary; -fx-font-size: 11.5px;"); + lblDocTitle.getStyleClass().addAll("form-label-muted", "text-bold"); Label lblDocValue = new Label(sourcePdfFile.getName() + " (" + (sourcePdfFile.length() / 1024) + " KB)"); - lblDocValue.setStyle("-fx-font-weight: bold; -fx-text-fill: -fx-text-primary; -fx-font-size: 11.5px;"); + lblDocValue.getStyleClass().addAll("form-label", "text-bold"); lblDocValue.setWrapText(true); Label lblSealTitle = new Label("Selo Visual:"); - lblSealTitle.setStyle("-fx-font-weight: bold; -fx-text-fill: -fx-text-secondary; -fx-font-size: 11.5px;"); + lblSealTitle.getStyleClass().addAll("form-label-muted", "text-bold"); Label lblSealValue = new Label(sealSummaryText); - lblSealValue.setStyle("-fx-text-fill: #0284c7; -fx-font-weight: bold; -fx-font-size: 11.5px;"); + lblSealValue.getStyleClass().addAll("text-primary", "text-bold"); lblSealValue.setWrapText(true); summaryGrid.add(lblDocTitle, 0, 0); @@ -237,13 +237,12 @@ public final class PdfCertificateSignDialog { } }); - // Banner informativo para certificados da Loja do Windows (sem PIN) windowsStoreBox = new HBox(8); windowsStoreBox.setAlignment(Pos.CENTER_LEFT); windowsStoreBox.setPadding(new Insets(10, 12, 10, 12)); - windowsStoreBox.setStyle("-fx-background-color: #ecfdf5; -fx-border-color: #a7f3d0; -fx-border-radius: 6px; -fx-background-radius: 6px;"); + windowsStoreBox.getStyleClass().add("status-badge-valid"); Label lblWinNotice = new Label("✓ Certificado instalado no computador — Gerenciado nativamente pelo Windows (PIN não necessário)"); - lblWinNotice.setStyle("-fx-text-fill: #065f46; -fx-font-weight: bold; -fx-font-size: 11.5px;"); + lblWinNotice.getStyleClass().addAll("text-success", "text-bold"); lblWinNotice.setWrapText(true); HBox.setHgrow(lblWinNotice, Priority.ALWAYS); windowsStoreBox.getChildren().add(lblWinNotice); @@ -282,9 +281,9 @@ public final class PdfCertificateSignDialog { VBox tipBox = new VBox(2); tipBox.setPadding(new Insets(8, 10, 8, 10)); - tipBox.setStyle("-fx-background-color: -fx-bg-primary; -fx-border-color: -fx-border-light; -fx-border-radius: 6px; -fx-background-radius: 6px;"); + tipBox.getStyleClass().add("dialog-box"); Label lblTip = new Label("🔒 Segurança: O PIN é criptografado localmente com AES-256-GCM vinculado à máquina e nunca é transmitido na rede."); - lblTip.setStyle("-fx-font-size: 11px; -fx-text-fill: -fx-text-secondary;"); + lblTip.getStyleClass().add("text-muted"); lblTip.setWrapText(true); lblTip.setMaxWidth(Double.MAX_VALUE); tipBox.getChildren().add(lblTip); @@ -381,7 +380,7 @@ public final class PdfCertificateSignDialog { chkRememberPin.setManaged(false); btnClearRememberedPin.setVisible(true); lblPinNotice.setText("✓ PIN lembrado com segurança neste computador"); - lblPinNotice.setStyle("-fx-text-fill: #10b981; -fx-font-weight: bold; -fx-font-size: 11.5px;"); + lblPinNotice.getStyleClass().setAll("label", "text-success", "text-bold"); } else { pinField.clear(); pinField.setDisable(false); @@ -390,7 +389,7 @@ public final class PdfCertificateSignDialog { btnClearRememberedPin.setVisible(false); boolean isA3 = cert.type() == CertificateType.A3; lblPinNotice.setText(isA3 ? "Requer PIN do token" : "Requer senha do certificado"); - lblPinNotice.setStyle("-fx-text-fill: -fx-text-secondary; -fx-font-size: 11.5px;"); + lblPinNotice.getStyleClass().setAll("label", "text-muted"); } } @@ -483,7 +482,7 @@ public final class PdfCertificateSignDialog { setFormDisabled(false); progressIndicator.setVisible(false); lblStatus.setText("✓ Documento assinado com sucesso!"); - lblStatus.setStyle("-fx-text-fill: #10b981; -fx-font-weight: bold;"); + lblStatus.getStyleClass().setAll("label", "text-success", "text-bold"); // Salva o PIN de forma segura se solicitado pelo usuário if (!isWindowsStore && chkRememberPin.isSelected() && enteredPin != null && enteredPin.length > 0) { @@ -508,7 +507,7 @@ public final class PdfCertificateSignDialog { } lblStatus.setText("✕ Falha na assinatura"); - lblStatus.setStyle("-fx-text-fill: #ef4444; -fx-font-weight: bold;"); + lblStatus.getStyleClass().setAll("label", "text-danger", "text-bold"); showAlert(Alert.AlertType.ERROR, "Erro na Assinatura do PDF", "Não foi possível concluir a assinatura digital:\n" + (ex != null ? ex.getMessage() : "Erro desconhecido")); diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/PdfSignDialog.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/PdfSignDialog.java index 07bee99..8bef6bf 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/PdfSignDialog.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/PdfSignDialog.java @@ -276,7 +276,7 @@ public final class PdfSignDialog { HBox btnNextContent = new HBox(8); btnNextContent.setAlignment(Pos.CENTER); Label lblBtnNextText = new Label("Avançar"); - lblBtnNextText.setStyle("-fx-font-weight: bold; -fx-font-size: 12px; -fx-text-fill: #ffffff;"); + lblBtnNextText.getStyleClass().add("text-bold"); btnNextContent.getChildren().addAll(lblBtnNextText, SvgIcons.arrowRightIcon(12)); btnNextToCert = new Button(); @@ -325,11 +325,10 @@ public final class PdfSignDialog { HBox themeHeader = new HBox(8); themeHeader.setAlignment(Pos.CENTER_LEFT); Label lblDefaultBadge = new Label("★ PADRÃO"); - lblDefaultBadge.setStyle("-fx-background-color: #0284c7; -fx-text-fill: #ffffff; -fx-padding: 2px 6px; -fx-background-radius: 4px; -fx-font-weight: bold; -fx-font-size: 10px;"); + lblDefaultBadge.getStyleClass().add("badge-primary"); lblSealThemeName = new Label(); - lblSealThemeName.getStyleClass().add("cert-title"); - lblSealThemeName.setStyle("-fx-font-size: 12.5px; -fx-font-weight: bold;"); + lblSealThemeName.getStyleClass().addAll("cert-title", "text-bold"); themeHeader.getChildren().addAll(lblDefaultBadge, lblSealThemeName); lblSealThemeDesc = new Label(); @@ -538,7 +537,7 @@ public final class PdfSignDialog { pageSheetContainer = new StackPane(); pageSheetContainer.setAlignment(Pos.TOP_LEFT); - pageSheetContainer.setStyle("-fx-background-color: #ffffff; -fx-border-color: #94a3b8; -fx-border-width: 1px;"); + pageSheetContainer.getStyleClass().add("preview-box"); DropShadow sheetShadow = new DropShadow(16, 0, 4, Color.rgb(0, 0, 0, 0.30)); pageSheetContainer.setEffect(sheetShadow); updateContainerZoomDimensions(); @@ -684,11 +683,11 @@ public final class PdfSignDialog { if (btnToggleResize != null) { if (isResizeModeActive) { btnToggleResize.setText("✓ Concluir"); - btnToggleResize.setStyle("-fx-background-color: #0284c7; -fx-text-fill: white; -fx-font-weight: bold;"); + btnToggleResize.getStyleClass().setAll("btn-primary"); lblPositionFeedback.setText("👉 Puxe a alça azul no canto do selo para ajustar o tamanho"); } else { btnToggleResize.setText("📏 Redimensionar"); - btnToggleResize.setStyle(""); + btnToggleResize.getStyleClass().setAll("btn-secondary"); updateFeedbackLabel(); } } diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SealDesignerDialog.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SealDesignerDialog.java index ea6a2c1..638d721 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SealDesignerDialog.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SealDesignerDialog.java @@ -276,7 +276,7 @@ public final class SealDesignerDialog { logoBtnRow.setAlignment(Pos.CENTER_LEFT); lblLogoStatus = new Label("Nenhum logotipo carregado (usando emblema vetorial)"); - lblLogoStatus.setStyle("-fx-font-size: 11px; -fx-text-fill: #64748b;"); + lblLogoStatus.getStyleClass().add("text-muted"); Label lblFallbackIcon = new Label("Emblema Vetorial Alternativo (caso sem logo própria):"); lblFallbackIcon.getStyleClass().add("form-label"); @@ -341,7 +341,7 @@ public final class SealDesignerDialog { lblPreviewTitle.getStyleClass().add("dialog-field-title"); Label lblPreviewNotice = new Label("O selo sempre exibe o nome completo do signatário com destaque e máxima legibilidade."); - lblPreviewNotice.setStyle("-fx-font-size: 11px; -fx-text-fill: #94a3b8;"); + lblPreviewNotice.getStyleClass().add("text-muted"); lblPreviewNotice.setWrapText(true); previewImageView = new ImageView(); @@ -351,7 +351,7 @@ public final class SealDesignerDialog { HBox previewContainer = new HBox(previewImageView); previewContainer.setAlignment(Pos.CENTER); previewContainer.setPadding(new Insets(16, 8, 16, 8)); - previewContainer.setStyle("-fx-background-color: #090d16; -fx-background-radius: 8px; -fx-border-color: #334155; -fx-border-radius: 8px;"); + previewContainer.getStyleClass().add("preview-box"); VBox previewContentBox = new VBox(10); previewContentBox.setAlignment(Pos.CENTER); @@ -442,7 +442,7 @@ public final class SealDesignerDialog { byte[] bytes = Files.readAllBytes(file.toPath()); customLogoBase64 = Base64.getEncoder().encodeToString(bytes); lblLogoStatus.setText("✓ Imagem carregada: " + file.getName()); - lblLogoStatus.setStyle("-fx-font-size: 11px; -fx-text-fill: #16a34a; -fx-font-weight: bold;"); + lblLogoStatus.getStyleClass().setAll("label", "text-success", "text-bold"); btnClearLogo.setDisable(false); updatePreview(); } catch (Exception ex) { @@ -454,7 +454,7 @@ public final class SealDesignerDialog { private void handleClearLogo() { customLogoBase64 = null; lblLogoStatus.setText("Nenhum logotipo carregado (usando emblema vetorial)"); - lblLogoStatus.setStyle("-fx-font-size: 11px; -fx-text-fill: #64748b;"); + lblLogoStatus.getStyleClass().setAll("label", "text-muted"); btnClearLogo.setDisable(true); updatePreview(); } @@ -524,12 +524,12 @@ public final class SealDesignerDialog { if (theme.customLogoBase64() != null && !theme.customLogoBase64().isBlank()) { this.customLogoBase64 = theme.customLogoBase64(); lblLogoStatus.setText("✓ Logotipo carregado com sucesso!"); - lblLogoStatus.setStyle("-fx-font-size: 11px; -fx-text-fill: #16a34a; -fx-font-weight: bold;"); + lblLogoStatus.getStyleClass().setAll("label", "text-success", "text-bold"); btnClearLogo.setDisable(false); } else { this.customLogoBase64 = null; lblLogoStatus.setText("Nenhum logotipo carregado (usando emblema vetorial)"); - lblLogoStatus.setStyle("-fx-font-size: 11px; -fx-text-fill: #64748b;"); + lblLogoStatus.getStyleClass().setAll("label", "text-muted"); btnClearLogo.setDisable(true); } diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SealManagementDialog.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SealManagementDialog.java index 47fccba..ecd3e50 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SealManagementDialog.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SealManagementDialog.java @@ -118,7 +118,7 @@ public final class SealManagementDialog { listViewSeals = new ListView<>(); VBox.setVgrow(listViewSeals, Priority.ALWAYS); - listViewSeals.setStyle("-fx-background-color: transparent; -fx-background-radius: 6px;"); + listViewSeals.getStyleClass().add("cyber-scroll-pane"); listViewSeals.setCellFactory(lv -> new SealListCell()); listViewSeals.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> onThemeSelected(newV)); @@ -153,10 +153,10 @@ public final class SealManagementDialog { lblPreviewHeader.getStyleClass().add("dialog-field-title"); lblSelectedName = new Label("Selecione um selo para visualizar"); - lblSelectedName.setStyle("-fx-font-weight: bold; -fx-font-size: 14px;"); + lblSelectedName.getStyleClass().add("dialog-header-title"); lblSelectedDesc = new Label(""); - lblSelectedDesc.setStyle("-fx-font-size: 11.5px; -fx-text-fill: #64748b;"); + lblSelectedDesc.getStyleClass().add("text-muted"); lblSelectedDesc.setWrapText(true); previewImageView = new ImageView(); @@ -166,14 +166,14 @@ public final class SealManagementDialog { HBox previewContainer = new HBox(previewImageView); previewContainer.setAlignment(Pos.CENTER); previewContainer.setPadding(new Insets(14, 10, 14, 10)); - previewContainer.setStyle("-fx-background-color: #090d16; -fx-background-radius: 8px; -fx-border-color: #334155; -fx-border-radius: 8px;"); + previewContainer.getStyleClass().add("preview-box"); VBox.setVgrow(previewContainer, Priority.ALWAYS); lblActiveBadge = new Label(""); - lblActiveBadge.setStyle("-fx-font-weight: bold; -fx-font-size: 12px;"); + lblActiveBadge.getStyleClass().add("text-bold"); lblFeedback = new Label(""); - lblFeedback.setStyle("-fx-font-size: 12px; -fx-font-weight: bold; -fx-text-fill: #16a34a;"); + lblFeedback.getStyleClass().addAll("text-success", "text-bold"); // Botões de Ação do Selo Selecionado VBox sealActions = new VBox(8); @@ -271,16 +271,14 @@ public final class SealManagementDialog { boolean isDefault = theme.id().equalsIgnoreCase(currentDefaultThemeId); if (isDefault) { lblActiveBadge.setText("★ ESTE É O SELO PADRÃO ATIVO PARA TODAS AS ASSINATURAS"); - lblActiveBadge.setStyle("-fx-text-fill: #38bdf8; -fx-font-weight: bold; -fx-font-size: 11.5px;"); + lblActiveBadge.getStyleClass().setAll("label", "text-primary", "text-bold"); btnSetDefault.setText("★ Selo Padrão Ativo no Sistema"); btnSetDefault.setDisable(true); - btnSetDefault.setStyle("-fx-opacity: 0.95; -fx-background-color: #0369a1; -fx-text-fill: #ffffff; -fx-font-weight: bold;"); } else { lblActiveBadge.setText("Selo disponível para uso."); - lblActiveBadge.setStyle("-fx-text-fill: #94a3b8; -fx-font-size: 11.5px;"); + lblActiveBadge.getStyleClass().setAll("label", "text-muted"); btnSetDefault.setText("✔ Definir como Selo Padrão Ativo"); btnSetDefault.setDisable(false); - btnSetDefault.setStyle(""); } btnEditClone.setDisable(false); @@ -460,14 +458,14 @@ public final class SealManagementDialog { VBox textBox = new VBox(2); Label lblName = new Label(item.name()); - lblName.setStyle("-fx-font-weight: bold; -fx-font-size: 12.5px;"); + lblName.getStyleClass().add("cert-title"); lblName.maxWidthProperty().bind(listViewSeals.widthProperty().subtract(120)); lblName.setWrapText(true); String desc = (item.description() != null && !item.description().isBlank()) ? item.description() : "Identidade visual de assinatura"; Label lblDesc = new Label(desc); - lblDesc.setStyle("-fx-font-size: 11px; -fx-text-fill: #64748b;"); + lblDesc.getStyleClass().add("cert-detail"); lblDesc.maxWidthProperty().bind(listViewSeals.widthProperty().subtract(120)); lblDesc.setWrapText(true); @@ -480,14 +478,12 @@ public final class SealManagementDialog { boolean isDefault = item.id().equalsIgnoreCase(currentDefaultThemeId); if (isDefault) { Label badgeDefault = new Label("★ PADRÃO"); - badgeDefault.setStyle("-fx-background-color: #0284c7; -fx-text-fill: #ffffff; -fx-font-size: 9.5px; -fx-font-weight: bold; -fx-padding: 2px 6px; -fx-background-radius: 4px;"); + badgeDefault.getStyleClass().add("badge-primary"); badgesBox.getChildren().add(badgeDefault); } Label badgeType = new Label(item.isCustom() ? "Personalizado" : "Sistema"); - badgeType.setStyle(item.isCustom() - ? "-fx-background-color: #fef3c7; -fx-text-fill: #b45309; -fx-font-size: 9.5px; -fx-padding: 2px 6px; -fx-background-radius: 4px;" - : "-fx-background-color: #e0f2fe; -fx-text-fill: #0369a1; -fx-font-size: 9.5px; -fx-padding: 2px 6px; -fx-background-radius: 4px;"); + badgeType.getStyleClass().add(item.isCustom() ? "cert-badge-a3" : "cert-badge-a1"); badgesBox.getChildren().add(badgeType); card.getChildren().addAll(textBox, badgesBox); diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SettingsView.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SettingsView.java index 30f3da9..015b825 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SettingsView.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SettingsView.java @@ -53,7 +53,7 @@ public final class SettingsView extends VBox { Label subtitleLabel = new Label("Parâmetros de segurança local, identidade visual dos selos e aplicações autorizadas."); subtitleLabel.getStyleClass().add("brand-subtitle"); - saveFeedbackLabel.setStyle("-fx-text-fill: #10b981; -fx-font-size: 11.5px; -fx-font-weight: bold;"); + saveFeedbackLabel.getStyleClass().addAll("text-success", "text-bold"); headerBox.getChildren().addAll(titleLabel, subtitleLabel, saveFeedbackLabel); @@ -126,10 +126,9 @@ public final class SettingsView extends VBox { Button btnClearPins = new Button("Limpar PINs Salvos (Sessão e Computador)"); btnClearPins.getStyleClass().add("btn-secondary"); - btnClearPins.setStyle("-fx-padding: 6px 14px; -fx-font-size: 12px;"); Label pinStatusLabel = new Label(); - pinStatusLabel.setStyle("-fx-text-fill: #34d399; -fx-font-size: 12px;"); + pinStatusLabel.getStyleClass().add("text-success"); btnClearPins.setOnAction(e -> { PinSessionManager.getInstance().clearAll(); @@ -152,12 +151,11 @@ public final class SettingsView extends VBox { sealHeaderRow.setAlignment(Pos.CENTER_LEFT); Label lblSealsDesc = new Label("Gerencie os temas e identidades gráficas instaladas para assinaturas PDF:"); - lblSealsDesc.setStyle("-fx-text-fill: #94a3b8; -fx-font-size: 12px;"); + lblSealsDesc.getStyleClass().add("text-muted"); HBox.setHgrow(lblSealsDesc, Priority.ALWAYS); Button btnCreateSeal = new Button("🎨 Criar ou Instalar Selo..."); btnCreateSeal.getStyleClass().add("btn-primary"); - btnCreateSeal.setStyle("-fx-padding: 6px 14px; -fx-font-size: 12px;"); btnCreateSeal.setOnAction(e -> openSealDesigner()); sealHeaderRow.getChildren().addAll(lblSealsDesc, btnCreateSeal); @@ -176,7 +174,7 @@ public final class SettingsView extends VBox { ScrollPane scrollApps = new ScrollPane(appsContainer); scrollApps.setFitToWidth(true); scrollApps.setPrefHeight(150); - scrollApps.setStyle("-fx-background: transparent; -fx-background-color: transparent;"); + scrollApps.getStyleClass().add("cyber-scroll-pane"); appsBox.getChildren().addAll(appsTitle, scrollApps); @@ -222,12 +220,11 @@ public final class SettingsView extends VBox { if (isDefault) { Label badgeDefault = new Label("★ PADRÃO"); - badgeDefault.setStyle("-fx-background-color: #0284c7; -fx-text-fill: #ffffff; -fx-padding: 3px 8px; -fx-background-radius: 4px; -fx-font-weight: bold; -fx-font-size: 11px;"); + badgeDefault.getStyleClass().add("badge-primary"); item.getChildren().add(badgeDefault); } else { Button btnSetDefault = new Button("★ Definir Padrão"); btnSetDefault.getStyleClass().addAll("btn-secondary", "btn-compact"); - btnSetDefault.setStyle("-fx-padding: 3px 8px; -fx-font-size: 11px;"); btnSetDefault.setOnAction(e -> { AgentConfiguration current = configService.getConfig(); configService.updateConfig(new AgentConfiguration( @@ -247,8 +244,7 @@ public final class SettingsView extends VBox { if (theme.isCustom()) { Button btnDelete = new Button("Excluir"); - btnDelete.getStyleClass().add("btn-secondary"); - btnDelete.setStyle("-fx-padding: 3px 8px; -fx-font-size: 11px; -fx-text-fill: #f87171;"); + btnDelete.getStyleClass().add("btn-danger-sm"); btnDelete.setOnAction(e -> { try { PdfSealThemeRegistry.uninstallCustomTheme(theme.id()); @@ -310,8 +306,7 @@ public final class SettingsView extends VBox { statusLabel.getStyleClass().add(app.enabled() ? "diagnostic-value-ok" : "diagnostic-value-warn"); Button btnRevoke = new Button("Revogar"); - btnRevoke.getStyleClass().add("btn-secondary"); - btnRevoke.setStyle("-fx-padding: 4px 10px; -fx-font-size: 11px; -fx-text-fill: #f87171;"); + btnRevoke.getStyleClass().add("btn-danger-sm"); btnRevoke.setOnAction(e -> { if (onRevokeApplication != null) { onRevokeApplication.accept(app.applicationId()); diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SignaturePromptDialog.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SignaturePromptDialog.java index 4fafec3..4a01a1c 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SignaturePromptDialog.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SignaturePromptDialog.java @@ -194,11 +194,10 @@ public class SignaturePromptDialog { rememberedBox.setAlignment(Pos.CENTER_LEFT); Label rememberedBadge = new Label("● PIN salvo nesta sessão ativa"); - rememberedBadge.setStyle("-fx-text-fill: #10b981; -fx-font-weight: bold; -fx-font-size: 12px;"); + rememberedBadge.getStyleClass().addAll("text-success", "text-bold"); Button btnChangePin = new Button("Alterar PIN"); btnChangePin.getStyleClass().add("btn-secondary"); - btnChangePin.setStyle("-fx-padding: 4px 10px; -fx-font-size: 11px;"); VBox inputWrapper = new VBox(8); inputWrapper.setVisible(false); @@ -222,7 +221,6 @@ public class SignaturePromptDialog { VBox inputWrapper = new VBox(8); Label pinPromptLabel = new Label("Informe o PIN do dispositivo para autorizar a chave privada:"); pinPromptLabel.getStyleClass().add("dialog-subtitle"); - pinPromptLabel.setStyle("-fx-font-size: 12px;"); cbSavePin.setSelected(false); inputWrapper.getChildren().addAll(pinPromptLabel, pinField, cbSavePin); @@ -233,7 +231,7 @@ public class SignaturePromptDialog { // Label de Alerta de Validação Label validationLabel = new Label(); - validationLabel.setStyle("-fx-text-fill: #f87171; -fx-font-size: 12px;"); + validationLabel.getStyleClass().addAll("text-danger", "text-bold"); validationLabel.setVisible(false); validationLabel.setManaged(false); diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SignatureValidationDialog.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SignatureValidationDialog.java index 0f1c54f..ffce1d4 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SignatureValidationDialog.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/SignatureValidationDialog.java @@ -152,7 +152,7 @@ public final class SignatureValidationDialog { ScrollPane scrollResult = new ScrollPane(resultBox); scrollResult.setFitToWidth(true); - scrollResult.setStyle("-fx-background: transparent; -fx-background-color: transparent;"); + scrollResult.getStyleClass().add("cyber-scroll-pane"); VBox.setVgrow(scrollResult, Priority.ALWAYS); // Rodapé @@ -277,27 +277,26 @@ public final class SignatureValidationDialog { statusBadge.setPadding(new Insets(10, 14, 10, 14)); Label lblBadge = new Label(result.status().getDescription()); - lblBadge.setStyle("-fx-font-weight: bold; -fx-font-size: 14px;"); if (result.status() == ValidationStatus.VALID) { - statusBadge.setStyle("-fx-background-color: rgba(16, 185, 129, 0.15); -fx-background-radius: 6px; -fx-border-color: #10b981; -fx-border-radius: 6px;"); - lblBadge.setStyle(lblBadge.getStyle() + " -fx-text-fill: #10b981;"); + statusBadge.getStyleClass().add("status-badge-valid"); + lblBadge.getStyleClass().addAll("text-success", "text-bold"); } else if (result.status() == ValidationStatus.INVALID) { - statusBadge.setStyle("-fx-background-color: rgba(239, 68, 68, 0.15); -fx-background-radius: 6px; -fx-border-color: #ef4444; -fx-border-radius: 6px;"); - lblBadge.setStyle(lblBadge.getStyle() + " -fx-text-fill: #ef4444;"); + statusBadge.getStyleClass().add("status-badge-invalid"); + lblBadge.getStyleClass().addAll("text-danger", "text-bold"); } else { - statusBadge.setStyle("-fx-background-color: rgba(245, 158, 11, 0.15); -fx-background-radius: 6px; -fx-border-color: #f59e0b; -fx-border-radius: 6px;"); - lblBadge.setStyle(lblBadge.getStyle() + " -fx-text-fill: #f59e0b;"); + statusBadge.getStyleClass().add("status-badge-warning"); + lblBadge.getStyleClass().addAll("text-warning", "text-bold"); } Label lblType = new Label("• Formato: " + result.type().getDescription()); - lblType.setStyle("-fx-font-size: 12px; -fx-text-fill: #cbd5e1;"); + lblType.getStyleClass().add("text-muted"); statusBadge.getChildren().addAll(lblBadge, lblType); Label lblMsg = new Label(result.summaryMessage()); lblMsg.setWrapText(true); - lblMsg.setStyle("-fx-font-size: 12.5px; -fx-font-weight: bold;"); + lblMsg.getStyleClass().add("text-bold"); resultBox.getChildren().addAll(statusBadge, lblMsg); @@ -324,7 +323,7 @@ public final class SignatureValidationDialog { lblTime.getStyleClass().add("cert-detail"); Label lblIntegrity = new Label(s.isValid() ? "✓ Assinatura íntegra e chave pública conferida." : "✗ Falha na integridade da assinatura."); - lblIntegrity.setStyle(s.isValid() ? "-fx-text-fill: #10b981; -fx-font-weight: bold; -fx-font-size: 11.5px;" : "-fx-text-fill: #ef4444; -fx-font-weight: bold; -fx-font-size: 11.5px;"); + lblIntegrity.getStyleClass().addAll(s.isValid() ? "text-success" : "text-danger", "text-bold"); card.getChildren().addAll(lblSignerName, lblCert, lblTime, lblIntegrity); resultBox.getChildren().add(card); diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/XmlSignDialog.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/XmlSignDialog.java index a9656ad..ad3a41a 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/XmlSignDialog.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/XmlSignDialog.java @@ -125,7 +125,7 @@ public final class XmlSignDialog { // ScrollPane ScrollPane scrollPane = new ScrollPane(); scrollPane.setFitToWidth(true); - scrollPane.setStyle("-fx-background-color: transparent; -fx-background: transparent; -fx-border-color: transparent;"); + scrollPane.getStyleClass().add("cyber-scroll-pane"); VBox formContent = new VBox(16); formContent.setPadding(new Insets(4, 8, 4, 0)); @@ -340,16 +340,16 @@ public final class XmlSignDialog { pinField.setDisable(true); pinField.clear(); lblPinNotice.setText("✓ PIN memorizado na sessão segura"); - lblPinNotice.setStyle("-fx-text-fill: #10b981; -fx-font-weight: bold;"); + lblPinNotice.getStyleClass().setAll("label", "text-success", "text-bold"); } else if (isA3 && "provider-win-store".equalsIgnoreCase(cert.providerId())) { pinField.setDisable(true); pinField.clear(); lblPinNotice.setText("Autenticação nativa pelo Windows/Driver"); - lblPinNotice.setStyle("-fx-text-fill: -fx-accent;"); + lblPinNotice.getStyleClass().setAll("label", "text-primary"); } else { pinField.setDisable(false); lblPinNotice.setText(isA3 ? "Requer PIN do Smart Card" : "Requer senha do certificado A1"); - lblPinNotice.setStyle("-fx-text-fill: -fx-text-secondary;"); + lblPinNotice.getStyleClass().setAll("label", "text-muted"); } } @@ -435,7 +435,7 @@ public final class XmlSignDialog { setFormDisabled(true); progressIndicator.setVisible(true); lblStatus.setText("Assinando documento XML (" + profile.getDisplayName() + ")..."); - lblStatus.setStyle("-fx-text-fill: -fx-accent;"); + lblStatus.getStyleClass().setAll("label", "text-primary"); boolean validate = chkValidateAfter.isSelected(); @@ -459,7 +459,7 @@ public final class XmlSignDialog { setFormDisabled(false); progressIndicator.setVisible(false); lblStatus.setText("✓ Documento XML assinado e validado com sucesso!"); - lblStatus.setStyle("-fx-text-fill: #10b981; -fx-font-weight: bold;"); + lblStatus.getStyleClass().setAll("label", "text-success", "text-bold"); showSuccessDialog(targetFile); }); @@ -470,7 +470,7 @@ public final class XmlSignDialog { Throwable ex = signTask.getException(); logger.error("Falha ao assinar XML", ex); lblStatus.setText("✕ Falha na assinatura"); - lblStatus.setStyle("-fx-text-fill: #ef4444; -fx-font-weight: bold;"); + lblStatus.getStyleClass().setAll("label", "text-danger", "text-bold"); showAlert(Alert.AlertType.ERROR, "Erro na Assinatura do XML", "Não foi possível concluir a assinatura XMLDSig:\n" + (ex != null ? ex.getMessage() : "Erro desconhecido")); diff --git a/modules/cybercore-ui/src/main/resources/styles/theme.css b/modules/cybercore-ui/src/main/resources/styles/theme.css index a90da8e..6559a91 100644 --- a/modules/cybercore-ui/src/main/resources/styles/theme.css +++ b/modules/cybercore-ui/src/main/resources/styles/theme.css @@ -1,1224 +1,718 @@ /* ========================================================================== - CyberCore Signer — Dual Theme Design System (Claro / Escuro) - Paleta Harmonizada e Alto Contraste (WCAG AA Compliant) + CyberCore Signer — Unified Design Tokens & Theming System + Totalmente baseado em Tokens Semânticos (Looked-up Colors) e WCAG AA + ========================================================================== */ + +/* ========================================================================== + 1. DEFINIÇÃO DE DESIGN TOKENS ========================================================================== */ .root { -fx-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; -fx-font-size: 13px; - -fx-text-secondary: #64748b; +} + +/* --- Tema Claro (Light Theme) --- */ +.theme-light { + /* Superfícies & Fundos */ + -fx-color-background: #f1f5f9; + -fx-color-surface: #ffffff; + -fx-color-surface-hover: #f8fafc; + -fx-color-surface-active: #e2e8f0; + -fx-color-surface-subtle: #f8fafc; + + /* Bordas */ + -fx-color-border: #cbd5e1; + -fx-color-border-subtle: #e2e8f0; + -fx-color-border-hover: #94a3b8; + + /* Tipografia (WCAG AA: contraste >= 4.5:1) */ + -fx-color-text: #0f172a; + -fx-color-text-muted: #475569; + -fx-color-text-inverse: #ffffff; + + /* Primária (Azul da Marca CyberCore) */ + -fx-color-primary: #0284c7; + -fx-color-primary-hover: #0369a1; + -fx-color-primary-active: #075985; + -fx-color-primary-subtle: #e0f2fe; + + /* Sucesso */ + -fx-color-success: #16a34a; + -fx-color-success-hover: #15803d; + -fx-color-success-subtle: #dcfce7; + -fx-color-success-border: #86efac; + + /* Aviso */ + -fx-color-warning: #d97706; + -fx-color-warning-hover: #b45309; + -fx-color-warning-subtle: #fef3c7; + -fx-color-warning-border: #fde68a; + + /* Erro */ + -fx-color-error: #dc2626; + -fx-color-error-hover: #b91c1c; + -fx-color-error-subtle: #fee2e2; + -fx-color-error-border: #fca5a5; + + /* Foco & Realce */ + -fx-color-focus: #0284c7; + + /* Sombras & Efeitos */ + -fx-color-shadow: rgba(15, 23, 42, 0.06); + -fx-color-shadow-hover: rgba(15, 23, 42, 0.12); + + /* Lookups nativos do JavaFX */ + -fx-base: -fx-color-background; + -fx-background: -fx-color-background; + -fx-control-inner-background: -fx-color-surface; + -fx-text-fill: -fx-color-text; +} + +/* --- Tema Escuro (Dark Theme) --- */ +.theme-dark { + /* Superfícies & Fundos */ + -fx-color-background: #090d16; + -fx-color-surface: #111827; + -fx-color-surface-hover: #1e293b; + -fx-color-surface-active: #334155; + -fx-color-surface-subtle: #0f172a; + + /* Bordas */ + -fx-color-border: #334155; + -fx-color-border-subtle: #1e293b; + -fx-color-border-hover: #475569; + + /* Tipografia (WCAG AA: contraste >= 4.5:1) */ + -fx-color-text: #f8fafc; + -fx-color-text-muted: #94a3b8; + -fx-color-text-inverse: #0f172a; + + /* Primária (Azul da Marca CyberCore Dark) */ + -fx-color-primary: #38bdf8; + -fx-color-primary-hover: #0284c7; + -fx-color-primary-active: #0369a1; + -fx-color-primary-subtle: rgba(56, 189, 248, 0.15); + + /* Sucesso */ + -fx-color-success: #34d399; + -fx-color-success-hover: #10b981; + -fx-color-success-subtle: rgba(52, 211, 153, 0.15); + -fx-color-success-border: rgba(52, 211, 153, 0.4); + + /* Aviso */ + -fx-color-warning: #fbbf24; + -fx-color-warning-hover: #f59e0b; + -fx-color-warning-subtle: rgba(251, 191, 36, 0.15); + -fx-color-warning-border: rgba(251, 191, 36, 0.4); + + /* Erro */ + -fx-color-error: #f87171; + -fx-color-error-hover: #ef4444; + -fx-color-error-subtle: rgba(248, 113, 113, 0.15); + -fx-color-error-border: rgba(248, 113, 113, 0.4); + + /* Foco & Realce */ + -fx-color-focus: #38bdf8; + + /* Sombras & Efeitos */ + -fx-color-shadow: rgba(0, 0, 0, 0.4); + -fx-color-shadow-hover: rgba(0, 0, 0, 0.6); + + /* Lookups nativos do JavaFX */ + -fx-base: -fx-color-background; + -fx-background: -fx-color-background; + -fx-control-inner-background: -fx-color-surface; + -fx-text-fill: -fx-color-text; } /* ========================================================================== - 1. TEMA CLARO (LIGHT THEME) + 2. REGRAS GERAIS DE ESTRUTURA E CONTAINERS ========================================================================== */ -.theme-light { - -fx-base: #f8fafc; - -fx-background: #f1f5f9; - -fx-control-inner-background: #ffffff; - -fx-text-fill: #0f172a; - -fx-text-secondary: #64748b; +.cyber-root, +.serpro-root, +.dialog-container { + -fx-background-color: -fx-color-background; + -fx-text-fill: -fx-color-text; } -.theme-light.cyber-root, -.theme-light .cyber-root, -.theme-light.serpro-root, -.theme-light .serpro-root, -.theme-light.dialog-container, -.theme-light .dialog-container { - -fx-background-color: #f1f5f9; +.content-pane { + -fx-background-color: -fx-color-background; + -fx-padding: 20px 24px; } -/* Header Claro */ -.theme-light .cyber-header-bar { - -fx-background-color: #ffffff; - -fx-border-color: #e2e8f0; +.dialog-box, +.content-card { + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border-subtle; + -fx-border-width: 1px; + -fx-border-radius: 8px; + -fx-background-radius: 8px; + -fx-padding: 16px; + -fx-effect: dropshadow(three-pass-box, -fx-color-shadow, 6, 0, 0, 2); +} + +/* Header Principal */ +.cyber-header-bar { + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border-subtle; -fx-border-width: 0 0 1px 0; -fx-padding: 12px 24px; } -.theme-light .cyber-brand-title { - -fx-font-size: 17px; +.cyber-brand-title { + -fx-font-size: 18px; -fx-font-weight: bold; - -fx-text-fill: #0f172a; + -fx-text-fill: -fx-color-text; } -.theme-light .cyber-brand-subtitle { +.cyber-brand-prefix { + -fx-font-weight: 300; + -fx-opacity: 0.85; +} + +.cyber-brand-separator { + -fx-font-size: 15px; + -fx-opacity: 0.4; + -fx-text-fill: -fx-color-text-muted; +} + +.cyber-brand-subtitle { -fx-font-size: 11px; - -fx-text-fill: #64748b; + -fx-text-fill: -fx-color-text-muted; } -.theme-light .cyber-status-badge { - -fx-background-color: #ecfdf5; - -fx-border-color: #10b981; - -fx-border-radius: 14px; +.cyber-status-badge { + -fx-background-color: -fx-color-success-subtle; + -fx-border-color: -fx-color-success-border; + -fx-border-radius: 16px; -fx-border-width: 1px; - -fx-background-radius: 14px; - -fx-text-fill: #047857; - -fx-padding: 5px 12px; - -fx-font-size: 11.5px; + -fx-background-radius: 16px; + -fx-text-fill: -fx-color-success; + -fx-padding: 4px 12px; + -fx-font-size: 11px; -fx-font-weight: bold; } -/* Botão Toggle de Tema */ -.theme-light .theme-toggle-btn { - -fx-background-color: #ffffff; - -fx-border-color: #cbd5e1; +/* Botão de Alternância de Tema */ +.theme-toggle-btn { + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border; -fx-border-radius: 18px; -fx-border-width: 1px; -fx-background-radius: 18px; - -fx-text-fill: #334155; - -fx-padding: 5px 12px; - -fx-font-size: 11.5px; + -fx-text-fill: -fx-color-text; + -fx-padding: 4px 12px; + -fx-font-size: 11px; -fx-font-weight: bold; -fx-cursor: hand; - -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.04), 4, 0, 0, 1); + -fx-effect: dropshadow(three-pass-box, -fx-color-shadow, 4, 0, 0, 1); } -.theme-light .theme-toggle-btn:hover { - -fx-background-color: #f8fafc; - -fx-border-color: #0284c7; - -fx-text-fill: #0284c7; +.theme-toggle-btn:hover { + -fx-background-color: -fx-color-surface-hover; + -fx-border-color: -fx-color-primary; + -fx-text-fill: -fx-color-primary; } -/* Cartões de Ação (Hub Central) - Modo Claro */ -.theme-light .cyber-action-card, -.theme-light .serpro-action-btn { - -fx-background-color: #ffffff; - -fx-border-color: #e2e8f0; +/* ========================================================================== + 3. HUB DE AÇÕES E PAINEL LATERAL + ========================================================================== */ + +.cyber-action-card, +.serpro-action-btn { + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border; -fx-border-width: 1.2px; -fx-border-radius: 8px; -fx-background-radius: 8px; - -fx-padding: 6px 10px; + -fx-padding: 8px 12px; -fx-alignment: CENTER_LEFT; -fx-cursor: hand; -fx-pref-height: 68px; -fx-min-height: 68px; -fx-max-width: Infinity; - -fx-effect: dropshadow(three-pass-box, rgba(15, 23, 42, 0.04), 6, 0, 0, 2); + -fx-effect: dropshadow(three-pass-box, -fx-color-shadow, 6, 0, 0, 2); } -.theme-light .cyber-action-card:hover, -.theme-light .serpro-action-btn:hover { - -fx-background-color: #ffffff; - -fx-border-color: #0284c7; - -fx-effect: dropshadow(three-pass-box, rgba(2, 132, 199, 0.16), 8, 0, 0, 3); +.cyber-action-card:hover, +.serpro-action-btn:hover { + -fx-background-color: -fx-color-surface-hover; + -fx-border-color: -fx-color-primary; + -fx-effect: dropshadow(three-pass-box, -fx-color-shadow-hover, 10, 0, 0, 4); } -.theme-light .cyber-action-card:pressed, -.theme-light .serpro-action-btn:pressed { - -fx-background-color: #f0f9ff; - -fx-border-color: #0369a1; +.cyber-action-card:pressed, +.serpro-action-btn:pressed { + -fx-background-color: -fx-color-surface-active; } -.theme-light .cyber-action-text, -.theme-light .serpro-action-text { - -fx-font-size: 11.5px; - -fx-font-weight: bold; - -fx-text-fill: #1e293b; - -fx-line-spacing: 1px; -} - -/* Painel Lateral - Modo Claro */ -.theme-light .cyber-side-column { - -fx-background-color: #ffffff; - -fx-border-color: #e2e8f0; - -fx-border-width: 1px; - -fx-border-radius: 10px; - -fx-background-radius: 10px; - -fx-padding: 14px; - -fx-effect: dropshadow(three-pass-box, rgba(15, 23, 42, 0.03), 6, 0, 0, 2); -} - -.theme-light .cyber-side-card, -.theme-light .serpro-side-btn { - -fx-background-color: #f8fafc; - -fx-border-color: #e2e8f0; - -fx-border-width: 1px; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-padding: 8px 12px; - -fx-alignment: CENTER_LEFT; - -fx-cursor: hand; - -fx-pref-height: 42px; - -fx-min-height: 42px; - -fx-max-width: Infinity; -} - -.theme-light .cyber-side-card:hover, -.theme-light .serpro-side-btn:hover { - -fx-background-color: #f0f9ff; - -fx-border-color: #0284c7; - -fx-effect: dropshadow(three-pass-box, rgba(2, 132, 199, 0.12), 4, 0, 0, 1); -} - -.theme-light .cyber-side-card:pressed, -.theme-light .serpro-side-btn:pressed { - -fx-background-color: #e0f2fe; -} - -.theme-light .cyber-side-text, -.theme-light .serpro-side-text { - -fx-font-size: 12.5px; - -fx-font-weight: bold; - -fx-text-fill: #334155; -} - -.theme-light .cyber-version-label, -.theme-light .serpro-version-label { - -fx-font-size: 11px; - -fx-text-fill: #64748b; -} - -/* Diálogos e Caixas - Modo Claro */ -.theme-light .dialog-header, -.theme-light .dialog-title, -.theme-light .section-title { - -fx-font-size: 16px; - -fx-font-weight: bold; - -fx-text-fill: #0369a1; -} - -.theme-light .dialog-subtitle, -.theme-light .section-subtitle, -.theme-light .brand-subtitle { - -fx-font-size: 12px; - -fx-text-fill: #64748b; -} - -.theme-light .dialog-box, -.theme-light .content-card { - -fx-background-color: #ffffff; - -fx-background-radius: 8px; - -fx-border-color: #e2e8f0; - -fx-border-radius: 8px; - -fx-border-width: 1px; - -fx-padding: 16px; - -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.04), 6, 0, 0, 2); -} - -.theme-light .label { - -fx-text-fill: #1e293b; -} - -.theme-light .form-label { - -fx-font-size: 12px; - -fx-font-weight: bold; - -fx-text-fill: #334155; -} - -.theme-light .form-label-muted { - -fx-font-size: 11px; - -fx-text-fill: #64748b; -} - -.theme-light .dialog-field-title { - -fx-font-size: 12px; - -fx-font-weight: bold; - -fx-text-fill: #0369a1; -} - -.theme-light .dialog-field-value, -.theme-light .detail-value { +.cyber-action-text, +.serpro-action-text { -fx-font-size: 13px; - -fx-text-fill: #0f172a; + -fx-font-weight: bold; + -fx-text-fill: -fx-color-text; + -fx-line-spacing: 2px; } -.theme-light .dialog-hash-value { - -fx-font-family: "Courier New", monospace; - -fx-font-size: 12px; - -fx-text-fill: #0369a1; - -fx-background-color: #f1f5f9; - -fx-border-color: #e2e8f0; - -fx-border-radius: 4px; - -fx-padding: 8px; - -fx-background-radius: 4px; -} - -.theme-light .log-console-area { - -fx-font-family: 'Consolas', 'Courier New', monospace; - -fx-font-size: 11.5px; - -fx-control-inner-background: #f8fafc; - -fx-text-fill: #0369a1; - -fx-border-color: #cbd5e1; - -fx-border-radius: 6px; - -fx-background-radius: 6px; -} - -.theme-light .seal-preview-box { - -fx-background-color: #f8fafc; - -fx-border-color: #cbd5e1; +.cyber-side-column { + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border-subtle; + -fx-border-width: 1px; -fx-border-radius: 8px; -fx-background-radius: 8px; -fx-padding: 12px; - -fx-alignment: CENTER; + -fx-effect: dropshadow(three-pass-box, -fx-color-shadow, 4, 0, 0, 1); } - -/* Controles de Formulário - Modo Claro */ -.theme-light .text-field, -.theme-light .password-field { - -fx-background-color: #ffffff; - -fx-border-color: #cbd5e1; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-text-fill: #0f172a; - -fx-prompt-text-fill: #94a3b8; - -fx-padding: 7px 12px; -} - -.theme-light .text-field:focused, -.theme-light .password-field:focused { - -fx-border-color: #0284c7; - -fx-background-color: #ffffff; -} - -.theme-light .combo-box { - -fx-background-color: #ffffff; - -fx-border-color: #cbd5e1; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-padding: 3px 6px; -} - -.theme-light .combo-box .cell { - -fx-text-fill: #0f172a; -} - -.theme-light .combo-box-popup .list-view { - -fx-background-color: #ffffff; - -fx-border-color: #cbd5e1; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.08), 8, 0, 0, 3); -} - -.theme-light .combo-box-popup .list-cell { - -fx-text-fill: #0f172a; - -fx-padding: 7px 12px; -} - -.theme-light .combo-box-popup .list-cell:hover, -.theme-light .combo-box-popup .list-cell:filled:selected { - -fx-background-color: #e0f2fe; - -fx-text-fill: #0369a1; -} - -/* CheckBox - Modo Claro (CORRIGIDO: texto perfeitamente visível) */ -.theme-light .check-box { - -fx-text-fill: #1e293b; - -fx-font-size: 13px; -} - -.theme-light .check-box > .box { - -fx-background-color: #ffffff; - -fx-border-color: #cbd5e1; - -fx-border-radius: 4px; - -fx-background-radius: 4px; - -fx-border-width: 1.2px; - -fx-padding: 3px; -} - -.theme-light .check-box:selected > .box { - -fx-background-color: #0284c7; - -fx-border-color: #0284c7; -} - -.theme-light .check-box:selected > .box > .mark { - -fx-background-color: #ffffff; -} - -/* RadioButton - Modo Claro */ -.theme-light .radio-button { - -fx-text-fill: #1e293b; - -fx-font-size: 13px; -} - -.theme-light .radio-button > .radio { - -fx-background-color: #ffffff; - -fx-border-color: #cbd5e1; - -fx-border-radius: 100px; - -fx-background-radius: 100px; - -fx-border-width: 1.5px; - -fx-padding: 3px; - -fx-alignment: center; -} - -.theme-light .radio-button:selected > .radio { - -fx-border-color: #0284c7; -} - -.theme-light .radio-button:selected > .radio > .dot { - -fx-background-color: #0284c7; - -fx-background-radius: 100px; - -fx-padding: 4px; - -fx-background-insets: 0; -} - -/* ColorPicker - Modo Claro */ -.theme-light .color-picker { - -fx-background-color: #ffffff; - -fx-border-color: #cbd5e1; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-border-width: 1.2px; - -fx-padding: 3px 6px; - -fx-pref-height: 32px; - -fx-cursor: hand; -} - -.theme-light .color-picker:hover { - -fx-border-color: #0284c7; -} - -.theme-light .color-picker .color-picker-label { - -fx-text-fill: #1e293b; - -fx-font-weight: bold; - -fx-font-size: 11.5px; -} - -.theme-light .color-row { - -fx-alignment: CENTER_LEFT; - -fx-spacing: 12px; - -fx-padding: 3px 0; -} - -/* Tabela - Modo Claro */ -.theme-light .table-view { - -fx-background-color: #ffffff; - -fx-border-color: #cbd5e1; - -fx-border-radius: 6px; - -fx-background-radius: 6px; -} - -.theme-light .table-view .column-header-background { - -fx-background-color: #f8fafc; - -fx-border-color: #e2e8f0; - -fx-border-width: 0 0 1px 0; -} - -.theme-light .table-view .column-header .label { - -fx-text-fill: #334155; - -fx-font-weight: bold; - -fx-font-size: 12px; -} - -.theme-light .table-view .table-row-cell { - -fx-background-color: #ffffff; - -fx-border-color: transparent transparent #f1f5f9 transparent; - -fx-border-width: 0 0 1px 0; -} - -.theme-light .table-view .table-row-cell:odd { - -fx-background-color: #f8fafc; -} - -.theme-light .table-view .table-row-cell:hover { - -fx-background-color: #f0f9ff; -} - -.theme-light .table-view .table-row-cell:filled:selected { - -fx-background-color: #e0f2fe; -} - -.theme-light .table-view .table-cell { - -fx-text-fill: #0f172a; - -fx-padding: 8px 12px; -} - -.theme-light .table-view .placeholder .label { - -fx-text-fill: #64748b; -} - -/* ========================================================================== - 2. TEMA ESCURO (DARK THEME) - ========================================================================== */ - -.theme-dark { - -fx-base: #121824; - -fx-background: #0b0f17; - -fx-control-inner-background: #131c2e; - -fx-text-fill: #f1f5f9; - -fx-text-secondary: #94a3b8; -} - -.theme-dark.cyber-root, -.theme-dark .cyber-root, -.theme-dark.serpro-root, -.theme-dark .serpro-root, -.theme-dark.dialog-container, -.theme-dark .dialog-container { - -fx-background-color: #0b0f17; -} - -/* Header Escuro */ -.theme-dark .cyber-header-bar { - -fx-background-color: #121824; - -fx-border-color: #1e293b; - -fx-border-width: 0 0 1px 0; - -fx-padding: 12px 24px; -} - -.theme-dark .cyber-brand-title { - -fx-font-size: 17px; - -fx-font-weight: bold; - -fx-text-fill: #ffffff; -} - -.theme-dark .cyber-brand-subtitle { - -fx-font-size: 11px; - -fx-text-fill: #94a3b8; -} - -.theme-dark .cyber-status-badge { - -fx-background-color: rgba(16, 185, 129, 0.15); - -fx-border-color: #10b981; - -fx-border-radius: 14px; +.cyber-side-card, +.serpro-side-btn { + -fx-background-color: transparent; + -fx-border-color: transparent; -fx-border-width: 1px; - -fx-background-radius: 14px; - -fx-text-fill: #34d399; - -fx-padding: 5px 12px; - -fx-font-size: 11.5px; - -fx-font-weight: bold; -} - -/* Botão Toggle de Tema */ -.theme-dark .theme-toggle-btn { - -fx-background-color: #1e293b; - -fx-border-color: #334155; - -fx-border-radius: 18px; - -fx-border-width: 1px; - -fx-background-radius: 18px; - -fx-text-fill: #e2e8f0; - -fx-padding: 5px 12px; - -fx-font-size: 11.5px; - -fx-font-weight: bold; - -fx-cursor: hand; - -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.25), 4, 0, 0, 1); -} - -.theme-dark .theme-toggle-btn:hover { - -fx-background-color: #334155; - -fx-border-color: #38bdf8; - -fx-text-fill: #38bdf8; -} - -/* Cartões de Ação (Hub Central) - Modo Escuro */ -.theme-dark .cyber-action-card, -.theme-dark .serpro-action-btn { - -fx-background-color: #131c2e; - -fx-border-color: #1e293b; - -fx-border-width: 1.2px; - -fx-border-radius: 8px; - -fx-background-radius: 8px; - -fx-padding: 8px 12px; + -fx-border-radius: 6px; + -fx-background-radius: 6px; + -fx-padding: 6px 10px; -fx-alignment: CENTER_LEFT; -fx-cursor: hand; - -fx-pref-height: 72px; - -fx-min-height: 72px; - -fx-max-width: Infinity; - -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.35), 8, 0, 0, 2); -} - -.theme-dark .cyber-action-card:hover, -.theme-dark .serpro-action-btn:hover { - -fx-background-color: #182338; - -fx-border-color: #38bdf8; - -fx-effect: dropshadow(three-pass-box, rgba(56, 189, 248, 0.2), 10, 0, 0, 3); -} - -.theme-dark .cyber-action-card:pressed, -.theme-dark .serpro-action-btn:pressed { - -fx-background-color: #0f172a; - -fx-border-color: #0284c7; -} - -.theme-dark .cyber-action-text, -.theme-dark .serpro-action-text { - -fx-font-size: 11.5px; - -fx-font-weight: bold; - -fx-text-fill: #f8fafc; - -fx-line-spacing: 1px; -} - -/* Painel Lateral - Modo Escuro */ -.theme-dark .cyber-side-column { - -fx-background-color: #121824; - -fx-border-color: #1e293b; - -fx-border-width: 1px; - -fx-border-radius: 10px; - -fx-background-radius: 10px; - -fx-padding: 14px; - -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.3), 8, 0, 0, 2); -} - -.theme-dark .cyber-side-card, -.theme-dark .serpro-side-btn { - -fx-background-color: #131c2e; - -fx-border-color: #1e293b; - -fx-border-width: 1px; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-padding: 8px 12px; - -fx-alignment: CENTER_LEFT; - -fx-cursor: hand; - -fx-pref-height: 42px; - -fx-min-height: 42px; -fx-max-width: Infinity; } -.theme-dark .cyber-side-card:hover, -.theme-dark .serpro-side-btn:hover { - -fx-background-color: #1a253c; - -fx-border-color: #38bdf8; - -fx-effect: dropshadow(three-pass-box, rgba(56, 189, 248, 0.15), 4, 0, 0, 1); +.cyber-side-card:hover, +.serpro-side-btn:hover { + -fx-background-color: -fx-color-surface-hover; + -fx-border-color: -fx-color-border-subtle; } -.theme-dark .cyber-side-card:pressed, -.theme-dark .serpro-side-btn:pressed { - -fx-background-color: #0f172a; +.cyber-side-card:pressed, +.serpro-side-btn:pressed { + -fx-background-color: -fx-color-surface-active; } -.theme-dark .cyber-side-text, -.theme-dark .serpro-side-text { - -fx-font-size: 12.5px; - -fx-font-weight: bold; - -fx-text-fill: #cbd5e1; +.cyber-side-text, +.serpro-side-text { + -fx-font-size: 13px; + -fx-text-fill: -fx-color-text; + -fx-font-weight: 500; } -.theme-dark .cyber-version-label, -.theme-dark .serpro-version-label { +.cyber-version-label, +.serpro-version-label { -fx-font-size: 11px; - -fx-text-fill: #94a3b8; -} - -/* Diálogos e Caixas - Modo Escuro */ -.theme-dark .dialog-header, -.theme-dark .dialog-title, -.theme-dark .section-title { - -fx-font-size: 16px; - -fx-font-weight: bold; - -fx-text-fill: #38bdf8; -} - -.theme-dark .dialog-subtitle, -.theme-dark .section-subtitle, -.theme-dark .brand-subtitle { - -fx-font-size: 12px; - -fx-text-fill: #94a3b8; -} - -.theme-dark .dialog-box, -.theme-dark .content-card { - -fx-background-color: #131c2e; - -fx-background-radius: 8px; - -fx-border-color: #1e293b; - -fx-border-radius: 8px; - -fx-border-width: 1px; - -fx-padding: 16px; - -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.35), 8, 0, 0, 2); -} - -.theme-dark .label { - -fx-text-fill: #f1f5f9; -} - -.theme-dark .form-label { - -fx-font-size: 12px; - -fx-font-weight: bold; - -fx-text-fill: #cbd5e1; -} - -.theme-dark .form-label-muted { - -fx-font-size: 11px; - -fx-text-fill: #94a3b8; -} - -.theme-dark .dialog-field-title { - -fx-font-size: 12px; - -fx-font-weight: bold; - -fx-text-fill: #38bdf8; -} - -.theme-dark .dialog-field-value, -.theme-dark .detail-value { - -fx-font-size: 13px; - -fx-text-fill: #f1f5f9; -} - -.theme-dark .dialog-hash-value { - -fx-font-family: "Courier New", monospace; - -fx-font-size: 12px; - -fx-text-fill: #38bdf8; - -fx-background-color: #090d16; - -fx-border-color: #1e293b; - -fx-border-radius: 4px; - -fx-padding: 8px; - -fx-background-radius: 4px; -} - -.theme-dark .log-console-area { - -fx-font-family: 'Consolas', 'Courier New', monospace; - -fx-font-size: 11.5px; - -fx-control-inner-background: #0b1329; - -fx-text-fill: #38bdf8; - -fx-border-color: #334155; - -fx-border-radius: 6px; - -fx-background-radius: 6px; -} - -.theme-dark .seal-preview-box { - -fx-background-color: #0b1329; - -fx-border-color: #334155; - -fx-border-radius: 8px; - -fx-background-radius: 8px; - -fx-padding: 12px; - -fx-alignment: CENTER; -} - -/* Controles de Formulário - Modo Escuro */ -.theme-dark .text-field, -.theme-dark .password-field { - -fx-background-color: #0f172a; - -fx-border-color: #334155; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-text-fill: #f1f5f9; - -fx-prompt-text-fill: #64748b; - -fx-padding: 7px 12px; -} - -.theme-dark .text-field:focused, -.theme-dark .password-field:focused { - -fx-border-color: #38bdf8; - -fx-background-color: #0f172a; -} - -.theme-dark .combo-box { - -fx-background-color: #131c2e; - -fx-border-color: #334155; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-padding: 3px 6px; -} - -.theme-dark .combo-box .cell { - -fx-text-fill: #f1f5f9; -} - -.theme-dark .combo-box-popup .list-view { - -fx-background-color: #131c2e; - -fx-border-color: #334155; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.4), 8, 0, 0, 3); -} - -.theme-dark .combo-box-popup .list-cell { - -fx-text-fill: #f1f5f9; - -fx-padding: 7px 12px; -} - -.theme-dark .combo-box-popup .list-cell:hover, -.theme-dark .combo-box-popup .list-cell:filled:selected { - -fx-background-color: #1e293b; - -fx-text-fill: #38bdf8; -} - -/* CheckBox - Modo Escuro */ -.theme-dark .check-box { - -fx-text-fill: #f1f5f9; - -fx-font-size: 13px; -} - -.theme-dark .check-box > .box { - -fx-background-color: #0f172a; - -fx-border-color: #475569; - -fx-border-radius: 4px; - -fx-background-radius: 4px; - -fx-border-width: 1.2px; - -fx-padding: 3px; -} - -.theme-dark .check-box:selected > .box { - -fx-background-color: #0284c7; - -fx-border-color: #38bdf8; -} - -.theme-dark .check-box:selected > .box > .mark { - -fx-background-color: #ffffff; -} - -/* RadioButton - Modo Escuro */ -.theme-dark .radio-button { - -fx-text-fill: #f1f5f9; - -fx-font-size: 13px; -} - -.theme-dark .radio-button > .radio { - -fx-background-color: #0f172a; - -fx-border-color: #475569; - -fx-border-radius: 100px; - -fx-background-radius: 100px; - -fx-border-width: 1.5px; - -fx-padding: 3px; - -fx-alignment: center; -} - -.theme-dark .radio-button:selected > .radio { - -fx-border-color: #38bdf8; -} - -.theme-dark .radio-button:selected > .radio > .dot { - -fx-background-color: #38bdf8; - -fx-background-radius: 100px; - -fx-padding: 4px; - -fx-background-insets: 0; -} - -/* ColorPicker - Modo Escuro */ -.theme-dark .color-picker { - -fx-background-color: #0f172a; - -fx-border-color: #334155; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-border-width: 1.2px; - -fx-padding: 3px 6px; - -fx-pref-height: 32px; - -fx-cursor: hand; -} - -.theme-dark .color-picker:hover { - -fx-border-color: #38bdf8; -} - -.theme-dark .color-picker .color-picker-label { - -fx-text-fill: #f1f5f9; - -fx-font-weight: bold; - -fx-font-size: 11.5px; -} - -.theme-dark .color-row { - -fx-alignment: CENTER_LEFT; - -fx-spacing: 12px; - -fx-padding: 3px 0; -} - -/* Tabela - Modo Escuro (CORRIGIDO: fundo escuro e textos contrastados) */ -.theme-dark .table-view { - -fx-background-color: #0f172a; - -fx-border-color: #1e293b; - -fx-border-radius: 6px; - -fx-background-radius: 6px; -} - -.theme-dark .table-view .column-header-background { - -fx-background-color: #131c2e; - -fx-border-color: #1e293b; - -fx-border-width: 0 0 1px 0; -} - -.theme-dark .table-view .column-header .label { - -fx-text-fill: #cbd5e1; - -fx-font-weight: bold; - -fx-font-size: 12px; -} - -.theme-dark .table-view .table-row-cell { - -fx-background-color: #0f172a; - -fx-border-color: transparent transparent #1e293b transparent; - -fx-border-width: 0 0 1px 0; -} - -.theme-dark .table-view .table-row-cell:odd { - -fx-background-color: #131c2e; -} - -.theme-dark .table-view .table-row-cell:hover { - -fx-background-color: #1e293b; -} - -.theme-dark .table-view .table-row-cell:filled:selected { - -fx-background-color: #1e293b; -} - -.theme-dark .table-view .table-cell { - -fx-text-fill: #f1f5f9; - -fx-padding: 8px 12px; -} - -.theme-dark .table-view .placeholder .label { - -fx-text-fill: #64748b; + -fx-text-fill: -fx-color-text-muted; } /* ========================================================================== - 3. BOTÕES E COMPONENTES COMUNS (DUAL THEME) + 4. TIPOGRAFIA & LABELS ========================================================================== */ -/* Botões Base e Proteção contra Truncamento com Reticências */ -.button { - -fx-min-width: -1; +.dialog-header, +.dialog-title, +.brand-title { + -fx-font-size: 18px; + -fx-font-weight: bold; + -fx-text-fill: -fx-color-text; } +.dialog-header-title { + -fx-font-size: 15px; + -fx-font-weight: bold; + -fx-text-fill: -fx-color-text; +} + +.section-title { + -fx-font-size: 15px; + -fx-font-weight: bold; + -fx-text-fill: -fx-color-text; +} + +.dialog-subtitle, +.dialog-header-subtitle, +.section-subtitle, +.brand-subtitle { + -fx-font-size: 11px; + -fx-text-fill: -fx-color-text-muted; +} + +.dialog-field-title, +.form-label { + -fx-font-size: 13px; + -fx-font-weight: bold; + -fx-text-fill: -fx-color-text; +} + +.form-label-muted { + -fx-font-size: 11px; + -fx-text-fill: -fx-color-text-muted; +} + +.dialog-field-value, +.detail-value { + -fx-font-size: 13px; + -fx-text-fill: -fx-color-text; +} + +.dialog-hash-value { + -fx-font-family: "Courier New", Courier, monospace; + -fx-font-size: 11px; + -fx-text-fill: -fx-color-text-muted; + -fx-background-color: -fx-color-surface-subtle; + -fx-padding: 4px 8px; + -fx-background-radius: 4px; + -fx-border-color: -fx-color-border-subtle; + -fx-border-radius: 4px; +} + +/* Utilitários semânticos */ +.text-primary { + -fx-text-fill: -fx-color-primary; +} + +.text-success { + -fx-text-fill: -fx-color-success; +} + +.text-warning { + -fx-text-fill: -fx-color-warning; +} + +.text-danger { + -fx-text-fill: -fx-color-error; +} + +.text-muted { + -fx-text-fill: -fx-color-text-muted; +} + +.text-bold { + -fx-font-weight: bold; +} + +/* ========================================================================== + 5. BOTÕES E CONTROLES DE AÇÃO + ========================================================================== */ + .btn-primary { - -fx-background-color: #0284c7; - -fx-text-fill: #ffffff; + -fx-background-color: -fx-color-primary; + -fx-text-fill: -fx-color-text-inverse; + -fx-font-size: 13px; -fx-font-weight: bold; - -fx-padding: 8px 18px; + -fx-padding: 8px 16px; -fx-background-radius: 6px; -fx-cursor: hand; - -fx-alignment: center; - -fx-effect: dropshadow(three-pass-box, rgba(2, 132, 199, 0.25), 4, 0, 0, 1); + -fx-effect: dropshadow(three-pass-box, -fx-color-shadow, 4, 0, 0, 1); } .btn-primary:hover { - -fx-background-color: #0369a1; + -fx-background-color: -fx-color-primary-hover; +} + +.btn-primary:pressed { + -fx-background-color: -fx-color-primary-active; } .btn-secondary { - -fx-background-color: #e2e8f0; - -fx-text-fill: #1e293b; + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border; + -fx-border-width: 1px; + -fx-text-fill: -fx-color-text; + -fx-font-size: 13px; -fx-font-weight: bold; - -fx-padding: 8px 18px; + -fx-padding: 8px 16px; -fx-background-radius: 6px; - -fx-alignment: center; + -fx-border-radius: 6px; -fx-cursor: hand; } .btn-secondary:hover { - -fx-background-color: #cbd5e1; + -fx-background-color: -fx-color-surface-hover; + -fx-border-color: -fx-color-border-hover; } -.theme-dark .btn-secondary { - -fx-background-color: #1e293b; - -fx-border-color: #334155; - -fx-border-radius: 6px; - -fx-border-width: 1px; - -fx-text-fill: #e2e8f0; +.btn-secondary:pressed { + -fx-background-color: -fx-color-surface-active; } -.theme-dark .btn-secondary:hover { - -fx-background-color: #334155; - -fx-border-color: #38bdf8; - -fx-text-fill: #38bdf8; -} - -.btn-cancel { - -fx-background-color: transparent; - -fx-border-color: #94a3b8; - -fx-border-radius: 6px; - -fx-text-fill: #475569; - -fx-font-weight: bold; - -fx-padding: 8px 18px; - -fx-alignment: center; - -fx-cursor: hand; -} - -.btn-cancel:hover { - -fx-border-color: #ef4444; - -fx-text-fill: #ef4444; -} - -.theme-dark .btn-cancel { - -fx-border-color: #475569; - -fx-text-fill: #94a3b8; -} - -.theme-dark .btn-cancel:hover { - -fx-border-color: #f87171; - -fx-text-fill: #f87171; -} - -/* Botões Padronizados para Diálogos e Modais */ -.btn-dialog { - -fx-min-width: 110px; - -fx-pref-height: 34px; - -fx-alignment: center; -} - -.btn-dialog-wide { - -fx-min-width: 220px; - -fx-pref-height: 36px; - -fx-alignment: center; -} - -/* Botões Compactos (barras de ferramentas e atalhos em linha) */ -.btn-compact { - -fx-padding: 5px 12px; - -fx-font-size: 11.5px; - -fx-alignment: center; -} - -/* Botão de Perigo / Exclusão / Remoção */ .btn-danger { - -fx-background-color: #fee2e8; - -fx-text-fill: #b91c1c; - -fx-border-color: #fca5a5; - -fx-border-radius: 6px; - -fx-background-radius: 6px; - -fx-border-width: 1px; - -fx-font-size: 12px; + -fx-background-color: -fx-color-error; + -fx-text-fill: -fx-color-text-inverse; + -fx-font-size: 13px; -fx-font-weight: bold; - -fx-padding: 6px 14px; - -fx-alignment: center; + -fx-padding: 8px 16px; + -fx-background-radius: 6px; -fx-cursor: hand; } .btn-danger:hover { - -fx-background-color: #ef4444; - -fx-text-fill: #ffffff; - -fx-border-color: #dc2626; + -fx-background-color: -fx-color-error-hover; } -.theme-dark .btn-danger { - -fx-background-color: rgba(239, 68, 68, 0.2); - -fx-text-fill: #f87171; - -fx-border-color: #dc2626; - -fx-alignment: center; +.btn-danger-sm { + -fx-background-color: transparent; + -fx-border-color: -fx-color-error-border; + -fx-border-radius: 4px; + -fx-background-radius: 4px; + -fx-text-fill: -fx-color-error; + -fx-font-size: 11px; + -fx-font-weight: bold; + -fx-padding: 4px 8px; + -fx-cursor: hand; } -.theme-dark .btn-danger:hover { - -fx-background-color: #ef4444; - -fx-text-fill: #ffffff; - -fx-border-color: #ef4444; +.btn-danger-sm:hover { + -fx-background-color: -fx-color-error-subtle; } -/* Badges de Certificados */ -.cert-card { - -fx-background-color: #ffffff; - -fx-border-color: #e2e8f0; +/* ========================================================================== + 6. INPUTS E CAMPOS DE FORMULÁRIO + ========================================================================== */ + +.text-field, +.password-field, +.text-area { + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border; -fx-border-width: 1px; + -fx-border-radius: 6px; + -fx-background-radius: 6px; + -fx-text-fill: -fx-color-text; + -fx-prompt-text-fill: -fx-color-text-muted; + -fx-padding: 8px 12px; + -fx-font-size: 13px; +} + +.text-field:focused, +.password-field:focused, +.text-area:focused { + -fx-border-color: -fx-color-focus; + -fx-effect: dropshadow(three-pass-box, -fx-color-primary-subtle, 4, 0, 0, 0); +} + +.combo-box { + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border; + -fx-border-width: 1px; + -fx-border-radius: 6px; + -fx-background-radius: 6px; + -fx-font-size: 13px; +} + +.combo-box:hover { + -fx-border-color: -fx-color-border-hover; +} + +.combo-box:focused { + -fx-border-color: -fx-color-focus; +} + +.combo-box .list-cell { + -fx-text-fill: -fx-color-text; + -fx-background-color: -fx-color-surface; + -fx-padding: 6px 10px; +} + +.combo-box-popup .list-view { + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border; + -fx-border-radius: 6px; + -fx-background-radius: 6px; + -fx-effect: dropshadow(three-pass-box, -fx-color-shadow-hover, 8, 0, 0, 4); +} + +.combo-box-popup .list-cell:hover { + -fx-background-color: -fx-color-surface-hover; +} + +.check-box, +.radio-button { + -fx-text-fill: -fx-color-text; + -fx-font-size: 13px; + -fx-cursor: hand; +} + +/* ========================================================================== + 7. CARTÕES DE CERTIFICADO & BADGES + ========================================================================== */ + +.cert-card { + -fx-background-color: -fx-color-surface; + -fx-border-color: -fx-color-border; + -fx-border-width: 1.2px; -fx-border-radius: 8px; -fx-background-radius: 8px; -fx-padding: 12px 16px; - -fx-effect: dropshadow(three-pass-box, rgba(15, 23, 42, 0.04), 4, 0, 0, 1); -} - -.theme-dark .cert-card { - -fx-background-color: #131c2e; - -fx-border-color: #1e293b; - -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.3), 6, 0, 0, 2); + -fx-effect: dropshadow(three-pass-box, -fx-color-shadow, 4, 0, 0, 1); } .cert-card:hover { - -fx-border-color: #0284c7; + -fx-background-color: -fx-color-surface-hover; + -fx-border-color: -fx-color-primary; } -.theme-dark .cert-card:hover { - -fx-border-color: #38bdf8; +.cert-card-selected { + -fx-background-color: -fx-color-primary-subtle; + -fx-border-color: -fx-color-primary; + -fx-border-width: 1.5px; } .cert-title { - -fx-font-size: 13.5px; + -fx-font-size: 13px; -fx-font-weight: bold; - -fx-text-fill: #0f172a; -} - -.theme-dark .cert-title { - -fx-text-fill: #f8fafc; + -fx-text-fill: -fx-color-text; } .cert-detail { - -fx-font-size: 11.5px; - -fx-text-fill: #64748b; -} - -.theme-dark .cert-detail { - -fx-text-fill: #94a3b8; + -fx-font-size: 11px; + -fx-text-fill: -fx-color-text-muted; } .cert-badge-a1 { - -fx-background-color: rgba(2, 132, 199, 0.12); - -fx-border-color: #0284c7; + -fx-background-color: -fx-color-primary-subtle; + -fx-border-color: -fx-color-primary; -fx-border-radius: 4px; - -fx-border-width: 1px; -fx-background-radius: 4px; - -fx-text-fill: #0284c7; - -fx-padding: 2px 8px; + -fx-text-fill: -fx-color-primary; -fx-font-size: 11px; -fx-font-weight: bold; + -fx-padding: 2px 8px; } .cert-badge-a3 { - -fx-background-color: rgba(16, 185, 129, 0.12); - -fx-border-color: #10b981; + -fx-background-color: -fx-color-warning-subtle; + -fx-border-color: -fx-color-warning-border; -fx-border-radius: 4px; - -fx-border-width: 1px; -fx-background-radius: 4px; - -fx-text-fill: #10b981; - -fx-padding: 2px 8px; + -fx-text-fill: -fx-color-warning; -fx-font-size: 11px; -fx-font-weight: bold; + -fx-padding: 2px 8px; } .cert-status-available { - -fx-text-fill: #10b981; - -fx-font-weight: bold; - -fx-font-size: 11.5px; -} - -.cert-status-expired { - -fx-text-fill: #ef4444; - -fx-font-weight: bold; - -fx-font-size: 11.5px; -} - -/* Painel de Pré-Visualização de Selos */ -.seal-preview-box { - -fx-background-color: #f8fafc; - -fx-border-color: #cbd5e1; - -fx-border-radius: 8px; - -fx-background-radius: 8px; - -fx-border-style: dashed; - -fx-padding: 14px; - -fx-alignment: center; -} - -.theme-dark .seal-preview-box { - -fx-background-color: #090d16; - -fx-border-color: #334155; -} - -/* ScrollBar & Progress */ -.progress-bar > .track { - -fx-background-color: #e2e8f0; - -fx-background-radius: 4px; -} - -.theme-dark .progress-bar > .track { - -fx-background-color: #1e293b; -} - -.progress-bar > .bar { - -fx-background-color: #0284c7; - -fx-background-radius: 4px; -} - -/* ========================================================================= - WIZARD STEPPER (FLUXO MULTI-ETAPAS) - ========================================================================= */ -.wizard-stepper { - -fx-alignment: center-left; - -fx-padding: 2px 0 6px 0; -} - -.wizard-step-pill { - -fx-alignment: center; - -fx-padding: 4px 12px; - -fx-background-radius: 14px; - -fx-border-radius: 14px; - -fx-border-width: 1px; -} - -.theme-light .wizard-step-pill { - -fx-background-color: #f1f5f9; - -fx-border-color: #cbd5e1; -} - -.theme-dark .wizard-step-pill { - -fx-background-color: #1e293b; - -fx-border-color: #334155; -} - -.theme-light .wizard-step-pill-active { - -fx-background-color: #e0f2fe; - -fx-border-color: #0284c7; -} - -.theme-dark .wizard-step-pill-active { - -fx-background-color: #0c4a6e; - -fx-border-color: #38bdf8; -} - -.wizard-step-badge { + -fx-text-fill: -fx-color-success; -fx-font-size: 11px; -fx-font-weight: bold; - -fx-alignment: center; - -fx-min-width: 20px; - -fx-min-height: 20px; - -fx-background-radius: 10px; - -fx-text-fill: #ffffff; } -.theme-light .wizard-step-badge-active { - -fx-background-color: #0284c7; - -fx-text-fill: #ffffff; -} - -.theme-dark .wizard-step-badge-active { - -fx-background-color: #38bdf8; - -fx-text-fill: #0f172a; -} - -.theme-light .wizard-step-badge-inactive { - -fx-background-color: #94a3b8; - -fx-text-fill: #ffffff; -} - -.theme-dark .wizard-step-badge-inactive { - -fx-background-color: #475569; - -fx-text-fill: #e2e8f0; -} - -.wizard-step-text { - -fx-font-size: 11.5px; +.cert-status-unavailable { + -fx-text-fill: -fx-color-error; + -fx-font-size: 11px; -fx-font-weight: bold; } -.theme-light .wizard-step-text-active { - -fx-text-fill: #0369a1; +.badge-primary { + -fx-background-color: -fx-color-primary; + -fx-text-fill: -fx-color-text-inverse; + -fx-font-size: 11px; + -fx-font-weight: bold; + -fx-padding: 2px 8px; + -fx-background-radius: 4px; } -.theme-dark .wizard-step-text-active { - -fx-text-fill: #38bdf8; +.badge-muted { + -fx-background-color: -fx-color-surface-subtle; + -fx-text-fill: -fx-color-text-muted; + -fx-font-size: 11px; + -fx-padding: 2px 8px; + -fx-background-radius: 4px; + -fx-border-color: -fx-color-border-subtle; + -fx-border-radius: 4px; } -.theme-light .wizard-step-text-inactive { - -fx-text-fill: #64748b; +.status-badge-valid { + -fx-background-color: -fx-color-success-subtle; + -fx-border-color: -fx-color-success-border; + -fx-border-radius: 6px; + -fx-background-radius: 6px; + -fx-text-fill: -fx-color-success; + -fx-padding: 4px 10px; + -fx-font-size: 11px; + -fx-font-weight: bold; } -.theme-dark .wizard-step-text-inactive { - -fx-text-fill: #94a3b8; +.status-badge-invalid { + -fx-background-color: -fx-color-error-subtle; + -fx-border-color: -fx-color-error-border; + -fx-border-radius: 6px; + -fx-background-radius: 6px; + -fx-text-fill: -fx-color-error; + -fx-padding: 4px 10px; + -fx-font-size: 11px; + -fx-font-weight: bold; } -.wizard-step-separator { - -fx-pref-width: 28px; - -fx-min-width: 20px; - -fx-pref-height: 2px; +.status-badge-warning { + -fx-background-color: -fx-color-warning-subtle; + -fx-border-color: -fx-color-warning-border; + -fx-border-radius: 6px; + -fx-background-radius: 6px; + -fx-text-fill: -fx-color-warning; + -fx-padding: 4px 10px; + -fx-font-size: 11px; + -fx-font-weight: bold; } -.theme-light .wizard-step-separator { - -fx-background-color: #cbd5e1; +.status-badge-active { + -fx-background-color: -fx-color-primary-subtle; + -fx-border-color: -fx-color-primary; + -fx-border-radius: 12px; + -fx-background-radius: 12px; + -fx-text-fill: -fx-color-primary; + -fx-padding: 4px 12px; + -fx-font-size: 11px; + -fx-font-weight: bold; } -.theme-dark .wizard-step-separator { - -fx-background-color: #334155; +/* ========================================================================== + 8. VISUALIZAÇÃO DE LOGS, PREVIEWS E SCROLLS + ========================================================================== */ + +.log-console-area { + -fx-font-family: "Courier New", Courier, monospace; + -fx-font-size: 11px; + -fx-background-color: -fx-color-surface-subtle; + -fx-text-fill: -fx-color-text; + -fx-border-color: -fx-color-border; + -fx-border-radius: 6px; + -fx-background-radius: 6px; } -.theme-light .wizard-step-separator-active { - -fx-background-color: #0284c7; -} - -.theme-dark .wizard-step-separator-active { - -fx-background-color: #38bdf8; -} - -.document-summary-box { - -fx-padding: 10px 14px; +.preview-box { + -fx-background-color: -fx-color-surface-subtle; + -fx-border-color: -fx-color-border; -fx-border-radius: 8px; -fx-background-radius: 8px; - -fx-border-width: 1px; - -fx-alignment: center-left; + -fx-padding: 12px; } -.theme-light .document-summary-box { - -fx-background-color: #f8fafc; - -fx-border-color: #e2e8f0; +.info-notice-box { + -fx-background-color: -fx-color-primary-subtle; + -fx-border-color: -fx-color-primary; + -fx-border-radius: 6px; + -fx-background-radius: 6px; + -fx-padding: 8px 12px; } -.theme-dark .document-summary-box { - -fx-background-color: #0f172a; - -fx-border-color: #1e293b; +.cyber-scroll-pane { + -fx-background-color: transparent; + -fx-background: transparent; } +.cyber-scroll-pane > .viewport { + -fx-background-color: transparent; +} + +.scroll-bar:vertical, +.scroll-bar:horizontal { + -fx-background-color: transparent; +} + +.scroll-bar .thumb { + -fx-background-color: -fx-color-border; + -fx-background-radius: 4px; +} + +.scroll-bar .thumb:hover { + -fx-background-color: -fx-color-border-hover; +}