feat: dark mode completo via widget de acessibilidade
- main.css: @variant dark com seletor .app-dark (alinhado com PrimeVue darkModeSelector) - AccessibilityWidget: novo toggle "Modo escuro" no painel; preferências persistidas no localStorage (fonte, contraste, escuro) - PublicLayout/PortalLayout: dark:bg-slate-950/900, dark:border, dark:text em todos os elementos - AppHeader/AppFooter: dark variants em bg, border, textos e links - ServiceCard: usa cores primary em vez de blue hardcoded; dark variants completos - HomeView: dark nos avisos do carrossel (bg coloridos suavizados), card de login, seção de serviços autenticados e CTA - LoginView: dark no card, campo documento, label senha, links e botão voltar Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4658d60ad0
commit
caf25236b5
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar"]
|
||||||
|
}
|
||||||
@ -6,6 +6,9 @@
|
|||||||
--font-sans: 'DM Sans', system-ui, sans-serif;
|
--font-sans: 'DM Sans', system-ui, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dark mode via classe .app-dark — alinhado com darkModeSelector do PrimeVue */
|
||||||
|
@variant dark (&:where(.app-dark, .app-dark *));
|
||||||
|
|
||||||
/* Remove setas de number input */
|
/* Remove setas de number input */
|
||||||
input[type='number']::-webkit-outer-spin-button,
|
input[type='number']::-webkit-outer-spin-button,
|
||||||
input[type='number']::-webkit-inner-spin-button {
|
input[type='number']::-webkit-inner-spin-button {
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch } from 'vue'
|
import { ref, watch, onMounted } from 'vue'
|
||||||
|
|
||||||
const aberto = ref(false)
|
const aberto = ref(false)
|
||||||
const nivelFonte = ref(0) // 0 = normal, 1 = grande, 2 = extra-grande
|
const nivelFonte = ref(Number(localStorage.getItem('a11y-fonte') || 0))
|
||||||
const altoContraste = ref(false)
|
const altoContraste = ref(localStorage.getItem('a11y-contraste') === '1')
|
||||||
|
const modoEscuro = ref(localStorage.getItem('a11y-escuro') === '1')
|
||||||
|
|
||||||
const opcoesFonte = [
|
const opcoesFonte = [
|
||||||
{ nivel: 0, label: 'A', title: 'Texto normal' },
|
{ nivel: 0, label: 'A', title: 'Texto normal' },
|
||||||
@ -11,14 +12,31 @@ const opcoesFonte = [
|
|||||||
{ nivel: 2, label: 'A++', title: 'Texto extra-grande' },
|
{ nivel: 2, label: 'A++', title: 'Texto extra-grande' },
|
||||||
]
|
]
|
||||||
|
|
||||||
watch(nivelFonte, (val) => {
|
function applyFonte(nivel) {
|
||||||
document.documentElement.classList.remove('a11y-font-lg', 'a11y-font-xl')
|
document.documentElement.classList.remove('a11y-font-lg', 'a11y-font-xl')
|
||||||
if (val === 1) document.documentElement.classList.add('a11y-font-lg')
|
if (nivel === 1) document.documentElement.classList.add('a11y-font-lg')
|
||||||
if (val === 2) document.documentElement.classList.add('a11y-font-xl')
|
if (nivel === 2) document.documentElement.classList.add('a11y-font-xl')
|
||||||
}, { immediate: true })
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
applyFonte(nivelFonte.value)
|
||||||
|
document.documentElement.classList.toggle('a11y-contrast', altoContraste.value)
|
||||||
|
document.documentElement.classList.toggle('app-dark', modoEscuro.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(nivelFonte, (val) => {
|
||||||
|
applyFonte(val)
|
||||||
|
localStorage.setItem('a11y-fonte', val)
|
||||||
|
})
|
||||||
|
|
||||||
watch(altoContraste, (val) => {
|
watch(altoContraste, (val) => {
|
||||||
document.documentElement.classList.toggle('a11y-contrast', val)
|
document.documentElement.classList.toggle('a11y-contrast', val)
|
||||||
|
localStorage.setItem('a11y-contraste', val ? '1' : '0')
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(modoEscuro, (val) => {
|
||||||
|
document.documentElement.classList.toggle('app-dark', val)
|
||||||
|
localStorage.setItem('a11y-escuro', val ? '1' : '0')
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -39,16 +57,16 @@ watch(altoContraste, (val) => {
|
|||||||
id="a11y-panel"
|
id="a11y-panel"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-label="Opções de acessibilidade"
|
aria-label="Opções de acessibilidade"
|
||||||
class="bg-white rounded-2xl shadow-2xl border border-slate-200 p-5 w-64 origin-bottom-right"
|
class="bg-white dark:bg-slate-800 rounded-2xl shadow-2xl border border-slate-200 dark:border-slate-700 p-5 w-64 origin-bottom-right"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-2 mb-4">
|
<div class="flex items-center gap-2 mb-4">
|
||||||
<i class="pi pi-eye text-primary text-sm" aria-hidden="true" />
|
<i class="pi pi-eye text-primary text-sm" aria-hidden="true" />
|
||||||
<p class="text-xs font-bold text-slate-600 uppercase tracking-wide">Acessibilidade</p>
|
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wide">Acessibilidade</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tamanho do texto -->
|
<!-- Tamanho do texto -->
|
||||||
<div class="mb-5">
|
<div class="mb-4">
|
||||||
<p class="text-sm font-semibold text-slate-700 mb-2">Tamanho do texto</p>
|
<p class="text-sm font-semibold text-slate-700 dark:text-slate-200 mb-2">Tamanho do texto</p>
|
||||||
<div class="flex gap-2" role="group" aria-label="Escolha o tamanho do texto">
|
<div class="flex gap-2" role="group" aria-label="Escolha o tamanho do texto">
|
||||||
<button
|
<button
|
||||||
v-for="op in opcoesFonte"
|
v-for="op in opcoesFonte"
|
||||||
@ -59,7 +77,7 @@ watch(altoContraste, (val) => {
|
|||||||
'flex-1 py-2 rounded-lg border text-sm font-bold transition-colors',
|
'flex-1 py-2 rounded-lg border text-sm font-bold transition-colors',
|
||||||
nivelFonte === op.nivel
|
nivelFonte === op.nivel
|
||||||
? 'bg-primary text-white border-primary'
|
? 'bg-primary text-white border-primary'
|
||||||
: 'bg-white text-slate-600 border-slate-200 hover:border-primary/40 hover:text-primary'
|
: 'bg-white dark:bg-slate-700 text-slate-600 dark:text-slate-300 border-slate-200 dark:border-slate-600 hover:border-primary/40 hover:text-primary'
|
||||||
]"
|
]"
|
||||||
@click="nivelFonte = op.nivel"
|
@click="nivelFonte = op.nivel"
|
||||||
>
|
>
|
||||||
@ -68,16 +86,30 @@ watch(altoContraste, (val) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Alto contraste -->
|
<div class="space-y-3 pt-4 border-t border-slate-100 dark:border-slate-700">
|
||||||
<div class="flex items-center justify-between pt-4 border-t border-slate-100">
|
<!-- Modo escuro -->
|
||||||
<div>
|
<div class="flex items-center justify-between">
|
||||||
<p class="text-sm font-semibold text-slate-700">Alto contraste</p>
|
<div>
|
||||||
<p class="text-xs text-slate-400 mt-0.5">Melhora a legibilidade</p>
|
<p class="text-sm font-semibold text-slate-700 dark:text-slate-200">Modo escuro</p>
|
||||||
|
<p class="text-xs text-slate-400 dark:text-slate-500 mt-0.5">Tema de baixa luminosidade</p>
|
||||||
|
</div>
|
||||||
|
<ToggleSwitch
|
||||||
|
v-model="modoEscuro"
|
||||||
|
:aria-label="modoEscuro ? 'Desativar modo escuro' : 'Ativar modo escuro'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Alto contraste -->
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-semibold text-slate-700 dark:text-slate-200">Alto contraste</p>
|
||||||
|
<p class="text-xs text-slate-400 dark:text-slate-500 mt-0.5">Melhora a legibilidade</p>
|
||||||
|
</div>
|
||||||
|
<ToggleSwitch
|
||||||
|
v-model="altoContraste"
|
||||||
|
:aria-label="altoContraste ? 'Desativar alto contraste' : 'Ativar alto contraste'"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ToggleSwitch
|
|
||||||
v-model="altoContraste"
|
|
||||||
:aria-label="altoContraste ? 'Desativar alto contraste' : 'Ativar alto contraste'"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
@ -88,7 +120,7 @@ watch(altoContraste, (val) => {
|
|||||||
'w-12 h-12 rounded-full shadow-lg border flex items-center justify-center transition-all hover:scale-105',
|
'w-12 h-12 rounded-full shadow-lg border flex items-center justify-center transition-all hover:scale-105',
|
||||||
aberto
|
aberto
|
||||||
? 'bg-primary text-white border-primary shadow-primary/30'
|
? 'bg-primary text-white border-primary shadow-primary/30'
|
||||||
: 'bg-white text-slate-600 border-slate-200 hover:border-slate-300 hover:shadow-xl'
|
: 'bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-300 border-slate-200 dark:border-slate-700 hover:border-slate-300 hover:shadow-xl'
|
||||||
]"
|
]"
|
||||||
:aria-label="aberto ? 'Fechar painel de acessibilidade' : 'Abrir painel de acessibilidade'"
|
:aria-label="aberto ? 'Fechar painel de acessibilidade' : 'Abrir painel de acessibilidade'"
|
||||||
:aria-expanded="aberto"
|
:aria-expanded="aberto"
|
||||||
|
|||||||
@ -2,17 +2,17 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<footer class="bg-white border-t border-slate-200 mt-auto" role="contentinfo">
|
<footer class="bg-white dark:bg-slate-900 border-t border-slate-200 dark:border-slate-700 mt-auto" role="contentinfo">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||||
<div class="flex flex-col sm:flex-row items-center justify-between gap-4">
|
<div class="flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||||
<div class="flex items-center gap-2 text-sm text-slate-600">
|
<div class="flex items-center gap-2 text-sm text-slate-600 dark:text-slate-300">
|
||||||
<i class="pi pi-building text-primary" aria-hidden="true" />
|
<i class="pi pi-building text-primary" aria-hidden="true" />
|
||||||
<span>Portal do Contribuinte — ModumFiscal</span>
|
<span>Portal do Contribuinte — ModumFiscal</span>
|
||||||
</div>
|
</div>
|
||||||
<nav aria-label="Links institucionais" class="flex items-center gap-4 text-xs text-slate-500">
|
<nav aria-label="Links institucionais" class="flex items-center gap-4 text-xs text-slate-500 dark:text-slate-400">
|
||||||
<a href="#" class="hover:text-slate-700 transition-colors">Política de Privacidade</a>
|
<a href="#" class="hover:text-slate-700 dark:hover:text-slate-200 transition-colors">Política de Privacidade</a>
|
||||||
<a href="#" class="hover:text-slate-700 transition-colors">Termos de Uso</a>
|
<a href="#" class="hover:text-slate-700 dark:hover:text-slate-200 transition-colors">Termos de Uso</a>
|
||||||
<a href="#" class="hover:text-slate-700 transition-colors">Acessibilidade</a>
|
<a href="#" class="hover:text-slate-700 dark:hover:text-slate-200 transition-colors">Acessibilidade</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -11,7 +11,7 @@ const logoSrc = computed(() => prefeitura.pathLogo || logoFallback)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header class="bg-white border-b border-slate-200">
|
<header class="bg-white dark:bg-slate-900 border-b border-slate-200 dark:border-slate-700">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||||
|
|
||||||
<RouterLink
|
<RouterLink
|
||||||
@ -26,8 +26,8 @@ const logoSrc = computed(() => prefeitura.pathLogo || logoFallback)
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="leading-tight min-w-0" aria-hidden="true">
|
<div class="leading-tight min-w-0" aria-hidden="true">
|
||||||
<p class="text-xs text-slate-500 font-normal truncate">Portal do Contribuinte</p>
|
<p class="text-xs text-slate-500 dark:text-slate-400 font-normal truncate">Portal do Contribuinte</p>
|
||||||
<p class="text-sm font-semibold text-slate-800 truncate">
|
<p class="text-sm font-semibold text-slate-800 dark:text-slate-100 truncate">
|
||||||
{{ prefeitura.nomePrefeitura || 'ModumFiscal' }}
|
{{ prefeitura.nomePrefeitura || 'ModumFiscal' }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -36,7 +36,7 @@ const logoSrc = computed(() => prefeitura.pathLogo || logoFallback)
|
|||||||
<nav aria-label="Navegação principal" class="hidden md:flex items-center gap-4">
|
<nav aria-label="Navegação principal" class="hidden md:flex items-center gap-4">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
:to="{ name: 'servicos' }"
|
:to="{ name: 'servicos' }"
|
||||||
class="text-sm text-slate-600 hover:text-primary transition-colors"
|
class="text-sm text-slate-600 dark:text-slate-300 hover:text-primary transition-colors"
|
||||||
:aria-current="$route.name === 'servicos' ? 'page' : undefined"
|
:aria-current="$route.name === 'servicos' ? 'page' : undefined"
|
||||||
>
|
>
|
||||||
Serviços
|
Serviços
|
||||||
|
|||||||
@ -12,19 +12,19 @@ defineProps({
|
|||||||
<component
|
<component
|
||||||
:is="to ? 'RouterLink' : 'div'"
|
:is="to ? 'RouterLink' : 'div'"
|
||||||
:to="to ?? undefined"
|
:to="to ?? undefined"
|
||||||
class="group flex flex-col gap-3 bg-white rounded-xl border border-slate-200 p-5 hover:border-blue-300 hover:shadow-md transition-all duration-200 cursor-pointer"
|
class="group flex flex-col gap-3 bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-5 hover:border-primary/40 dark:hover:border-primary/50 hover:shadow-md transition-all duration-200 cursor-pointer"
|
||||||
>
|
>
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
<div class="w-10 h-10 bg-blue-50 rounded-lg flex items-center justify-center group-hover:bg-blue-100 transition-colors">
|
<div class="w-10 h-10 bg-primary/8 dark:bg-primary/15 rounded-lg flex items-center justify-center group-hover:bg-primary/15 dark:group-hover:bg-primary/25 transition-colors">
|
||||||
<i :class="['pi', icon, 'text-blue-700 text-lg']" />
|
<i :class="['pi', icon, 'text-primary text-lg']" />
|
||||||
</div>
|
</div>
|
||||||
<i v-if="requiresAuth" class="pi pi-lock text-slate-300 text-xs" title="Requer login" />
|
<i v-if="requiresAuth" class="pi pi-lock text-slate-300 dark:text-slate-600 text-xs" title="Requer login" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="font-semibold text-slate-800 text-sm group-hover:text-blue-700 transition-colors">{{ titulo }}</p>
|
<p class="font-semibold text-slate-800 dark:text-slate-100 text-sm group-hover:text-primary transition-colors">{{ titulo }}</p>
|
||||||
<p v-if="descricao" class="text-xs text-slate-500 mt-1 leading-relaxed">{{ descricao }}</p>
|
<p v-if="descricao" class="text-xs text-slate-500 dark:text-slate-400 mt-1 leading-relaxed">{{ descricao }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-1 text-xs text-blue-600 font-medium opacity-0 group-hover:opacity-100 transition-opacity">
|
<div class="flex items-center gap-1 text-xs text-primary font-medium opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
<span>Acessar</span>
|
<span>Acessar</span>
|
||||||
<i class="pi pi-arrow-right text-xs" />
|
<i class="pi pi-arrow-right text-xs" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -20,8 +20,8 @@ function sair() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="min-h-screen flex flex-col bg-slate-50">
|
<div class="min-h-screen flex flex-col bg-slate-50 dark:bg-slate-950">
|
||||||
<header class="bg-white border-b border-slate-200 sticky top-0 z-40" role="banner">
|
<header class="bg-white dark:bg-slate-900 border-b border-slate-200 dark:border-slate-700 sticky top-0 z-40" role="banner">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
:to="{ name: 'painel' }"
|
:to="{ name: 'painel' }"
|
||||||
@ -31,7 +31,7 @@ function sair() {
|
|||||||
<div class="w-8 h-8 bg-primary rounded-lg flex items-center justify-center">
|
<div class="w-8 h-8 bg-primary rounded-lg flex items-center justify-center">
|
||||||
<i class="pi pi-building text-white text-sm" aria-hidden="true" />
|
<i class="pi pi-building text-white text-sm" aria-hidden="true" />
|
||||||
</div>
|
</div>
|
||||||
<span class="font-semibold text-slate-800">Portal do Contribuinte</span>
|
<span class="font-semibold text-slate-800 dark:text-slate-100">Portal do Contribuinte</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
<nav aria-label="Menu do contribuinte" class="hidden md:flex items-center gap-1">
|
<nav aria-label="Menu do contribuinte" class="hidden md:flex items-center gap-1">
|
||||||
@ -39,7 +39,7 @@ function sair() {
|
|||||||
v-for="item in navItems"
|
v-for="item in navItems"
|
||||||
:key="item.name"
|
:key="item.name"
|
||||||
:to="{ name: item.name }"
|
:to="{ name: item.name }"
|
||||||
class="px-4 py-2 rounded-lg text-sm text-slate-600 hover:bg-slate-100 hover:text-slate-900 transition-colors"
|
class="px-4 py-2 rounded-lg text-sm text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800 hover:text-slate-900 dark:hover:text-slate-100 transition-colors"
|
||||||
active-class="bg-primary/10 text-primary font-semibold"
|
active-class="bg-primary/10 text-primary font-semibold"
|
||||||
:aria-current="$route.name === item.name ? 'page' : undefined"
|
:aria-current="$route.name === item.name ? 'page' : undefined"
|
||||||
>
|
>
|
||||||
@ -48,7 +48,7 @@ function sair() {
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<span class="hidden sm:block text-sm text-slate-600" aria-live="polite">
|
<span class="hidden sm:block text-sm text-slate-600 dark:text-slate-300" aria-live="polite">
|
||||||
{{ auth.nomeUsuario }}
|
{{ auth.nomeUsuario }}
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="min-h-screen flex flex-col bg-slate-50">
|
<div class="min-h-screen flex flex-col bg-slate-50 dark:bg-slate-950">
|
||||||
<AppHeader />
|
<AppHeader />
|
||||||
|
|
||||||
<!-- tabindex="-1" permite que o skip link mova o foco para cá -->
|
<!-- tabindex="-1" permite que o skip link mova o foco para cá -->
|
||||||
|
|||||||
@ -70,9 +70,9 @@ const avisos = ref([
|
|||||||
])
|
])
|
||||||
|
|
||||||
const corAviso = {
|
const corAviso = {
|
||||||
amber: { bg: 'bg-amber-50', borda: 'border-amber-200', icone: 'text-amber-600', tag: 'bg-amber-100 text-amber-700' },
|
amber: { bg: 'bg-amber-50 dark:bg-amber-900/20', borda: 'border-amber-200 dark:border-amber-700/40', icone: 'text-amber-600 dark:text-amber-400', tag: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300' },
|
||||||
green: { bg: 'bg-emerald-50', borda: 'border-emerald-200', icone: 'text-emerald-600', tag: 'bg-emerald-100 text-emerald-700' },
|
green: { bg: 'bg-emerald-50 dark:bg-emerald-900/20', borda: 'border-emerald-200 dark:border-emerald-700/40', icone: 'text-emerald-600 dark:text-emerald-400', tag: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300' },
|
||||||
blue: { bg: 'bg-blue-50', borda: 'border-blue-200', icone: 'text-blue-600', tag: 'bg-blue-100 text-blue-700' },
|
blue: { bg: 'bg-blue-50 dark:bg-blue-900/20', borda: 'border-blue-200 dark:border-blue-700/40', icone: 'text-blue-600 dark:text-blue-400', tag: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300' },
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Serviços ────────────────────────────────────────────────────────────────
|
// ─── Serviços ────────────────────────────────────────────────────────────────
|
||||||
@ -190,7 +190,7 @@ function continuar() {
|
|||||||
|
|
||||||
<!-- Direita — Card de acesso -->
|
<!-- Direita — Card de acesso -->
|
||||||
<div class="flex justify-center lg:justify-end">
|
<div class="flex justify-center lg:justify-end">
|
||||||
<div class="bg-white rounded-2xl shadow-2xl p-8 w-full max-w-sm backdrop-blur-sm">
|
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-2xl p-8 w-full max-w-sm backdrop-blur-sm">
|
||||||
|
|
||||||
<!-- Cabeçalho do card -->
|
<!-- Cabeçalho do card -->
|
||||||
<div class="flex items-center gap-3 mb-7">
|
<div class="flex items-center gap-3 mb-7">
|
||||||
@ -198,15 +198,15 @@ function continuar() {
|
|||||||
<i class="pi pi-lock-open text-white text-lg" />
|
<i class="pi pi-lock-open text-white text-lg" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="font-bold text-slate-800 text-base">Área do Contribuinte</p>
|
<p class="font-bold text-slate-800 dark:text-slate-100 text-base">Área do Contribuinte</p>
|
||||||
<p class="text-xs text-slate-500">Acesso seguro ao portal</p>
|
<p class="text-xs text-slate-500 dark:text-slate-400">Acesso seguro ao portal</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Formulário -->
|
<!-- Formulário -->
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-sm font-medium text-slate-700 mb-1.5">
|
<label class="block text-sm font-medium text-slate-700 dark:text-slate-200 mb-1.5">
|
||||||
CPF ou CNPJ
|
CPF ou CNPJ
|
||||||
</label>
|
</label>
|
||||||
<DocumentoInput
|
<DocumentoInput
|
||||||
@ -236,14 +236,14 @@ function continuar() {
|
|||||||
<div class="space-y-2.5 text-center">
|
<div class="space-y-2.5 text-center">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
:to="{ name: 'primeiro-acesso' }"
|
:to="{ name: 'primeiro-acesso' }"
|
||||||
class="flex items-center justify-center gap-2 w-full px-4 py-2.5 rounded-lg border border-slate-200 text-sm text-slate-700 hover:bg-slate-50 hover:border-slate-300 transition-colors font-medium"
|
class="flex items-center justify-center gap-2 w-full px-4 py-2.5 rounded-lg border border-slate-200 dark:border-slate-600 text-sm text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-700 hover:border-slate-300 dark:hover:border-slate-500 transition-colors font-medium"
|
||||||
>
|
>
|
||||||
<i class="pi pi-key text-slate-500 text-sm" />
|
<i class="pi pi-key text-slate-500 dark:text-slate-400 text-sm" />
|
||||||
Criar minha senha
|
Criar minha senha
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
:to="{ name: 'credenciamento' }"
|
:to="{ name: 'credenciamento' }"
|
||||||
class="block text-xs text-slate-400 hover:text-slate-600 transition-colors"
|
class="block text-xs text-slate-400 dark:text-slate-500 hover:text-slate-600 dark:hover:text-slate-300 transition-colors"
|
||||||
>
|
>
|
||||||
Ainda não cadastrado? <span class="text-primary font-semibold">Credenciar-se</span>
|
Ainda não cadastrado? <span class="text-primary font-semibold">Credenciar-se</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
@ -257,7 +257,7 @@ function continuar() {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- ─── CAROUSEL DE AVISOS ────────────────────────────────────────── -->
|
<!-- ─── CAROUSEL DE AVISOS ────────────────────────────────────────── -->
|
||||||
<section class="bg-white border-b border-slate-100" aria-label="Avisos e comunicados">
|
<section class="bg-white dark:bg-slate-900 border-b border-slate-100 dark:border-slate-800" aria-label="Avisos e comunicados">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||||
<!-- autoplay desativado quando prefers-reduced-motion está ativo -->
|
<!-- autoplay desativado quando prefers-reduced-motion está ativo -->
|
||||||
<Carousel
|
<Carousel
|
||||||
@ -285,8 +285,8 @@ function continuar() {
|
|||||||
<i :class="['pi', aviso.icone, 'text-lg', corAviso[aviso.cor].icone]" />
|
<i :class="['pi', aviso.icone, 'text-lg', corAviso[aviso.cor].icone]" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<p class="font-semibold text-slate-800 text-sm">{{ aviso.titulo }}</p>
|
<p class="font-semibold text-slate-800 dark:text-slate-100 text-sm">{{ aviso.titulo }}</p>
|
||||||
<p class="text-xs text-slate-600 mt-0.5 leading-relaxed">{{ aviso.descricao }}</p>
|
<p class="text-xs text-slate-600 dark:text-slate-300 mt-0.5 leading-relaxed">{{ aviso.descricao }}</p>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
v-if="aviso.acao"
|
v-if="aviso.acao"
|
||||||
:to="aviso.acao.to"
|
:to="aviso.acao.to"
|
||||||
@ -310,8 +310,8 @@ function continuar() {
|
|||||||
<section class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12" aria-labelledby="servicos-logados-titulo">
|
<section class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12" aria-labelledby="servicos-logados-titulo">
|
||||||
<div class="flex items-center justify-between mb-6">
|
<div class="flex items-center justify-between mb-6">
|
||||||
<div>
|
<div>
|
||||||
<h2 id="servicos-logados-titulo" class="text-xl font-bold text-slate-800">Área logada</h2>
|
<h2 id="servicos-logados-titulo" class="text-xl font-bold text-slate-800 dark:text-slate-100">Área logada</h2>
|
||||||
<p class="text-sm text-slate-600 mt-0.5">Serviços disponíveis após login</p>
|
<p class="text-sm text-slate-600 dark:text-slate-400 mt-0.5">Serviços disponíveis após login</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="hidden sm:flex items-center gap-1.5 bg-primary/8 text-primary text-xs font-semibold px-3 py-1.5 rounded-full border border-primary/15">
|
<span class="hidden sm:flex items-center gap-1.5 bg-primary/8 text-primary text-xs font-semibold px-3 py-1.5 rounded-full border border-primary/15">
|
||||||
<i class="pi pi-lock text-xs" />
|
<i class="pi pi-lock text-xs" />
|
||||||
@ -329,10 +329,10 @@ function continuar() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CTA credenciamento -->
|
<!-- CTA credenciamento -->
|
||||||
<div class="mt-10 bg-gradient-to-r from-primary/5 to-primary/10 border border-primary/15 rounded-2xl p-6 flex flex-col sm:flex-row items-center justify-between gap-5">
|
<div class="mt-10 bg-gradient-to-r from-primary/5 to-primary/10 dark:from-primary/10 dark:to-primary/15 border border-primary/15 dark:border-primary/20 rounded-2xl p-6 flex flex-col sm:flex-row items-center justify-between gap-5">
|
||||||
<div>
|
<div>
|
||||||
<p class="font-bold text-slate-800 text-base">Ainda não tem acesso ao portal?</p>
|
<p class="font-bold text-slate-800 dark:text-slate-100 text-base">Ainda não tem acesso ao portal?</p>
|
||||||
<p class="text-sm text-slate-500 mt-1 max-w-md">
|
<p class="text-sm text-slate-500 dark:text-slate-400 mt-1 max-w-md">
|
||||||
Solicite seu credenciamento e passe a gerenciar todos os seus tributos municipais de forma online.
|
Solicite seu credenciamento e passe a gerenciar todos os seus tributos municipais de forma online.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -53,7 +53,7 @@ async function entrar() {
|
|||||||
<div class="min-h-[calc(100vh-8rem)] flex items-center justify-center px-4 py-12">
|
<div class="min-h-[calc(100vh-8rem)] flex items-center justify-center px-4 py-12">
|
||||||
<div class="w-full max-w-md">
|
<div class="w-full max-w-md">
|
||||||
|
|
||||||
<div class="bg-white rounded-2xl shadow-lg border border-slate-200 overflow-hidden">
|
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-lg border border-slate-200 dark:border-slate-700 overflow-hidden">
|
||||||
|
|
||||||
<!-- Cabeçalho — h1 para hierarquia de heading correta -->
|
<!-- Cabeçalho — h1 para hierarquia de heading correta -->
|
||||||
<div class="bg-gradient-to-r from-primary-700 to-primary-800 px-8 py-6 bg-primary">
|
<div class="bg-gradient-to-r from-primary-700 to-primary-800 px-8 py-6 bg-primary">
|
||||||
@ -72,17 +72,17 @@ async function entrar() {
|
|||||||
|
|
||||||
<!-- Documento identificado -->
|
<!-- Documento identificado -->
|
||||||
<div>
|
<div>
|
||||||
<p class="text-xs font-semibold text-slate-600 uppercase tracking-wide mb-2">
|
<p class="text-xs font-semibold text-slate-600 dark:text-slate-400 uppercase tracking-wide mb-2">
|
||||||
Entrando como
|
Entrando como
|
||||||
</p>
|
</p>
|
||||||
<div class="flex items-center justify-between bg-slate-50 border border-slate-200 rounded-xl px-4 py-3">
|
<div class="flex items-center justify-between bg-slate-50 dark:bg-slate-700 border border-slate-200 dark:border-slate-600 rounded-xl px-4 py-3">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="w-8 h-8 bg-primary/10 rounded-lg flex items-center justify-center" aria-hidden="true">
|
<div class="w-8 h-8 bg-primary/10 rounded-lg flex items-center justify-center" aria-hidden="true">
|
||||||
<i class="pi pi-id-card text-primary text-sm" />
|
<i class="pi pi-id-card text-primary text-sm" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="font-mono font-semibold text-slate-800 text-sm">{{ docFormatado }}</p>
|
<p class="font-mono font-semibold text-slate-800 dark:text-slate-100 text-sm">{{ docFormatado }}</p>
|
||||||
<p class="text-xs text-slate-600">{{ tipoDoc }}</p>
|
<p class="text-xs text-slate-600 dark:text-slate-300">{{ tipoDoc }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Alvo de 44px via py-3 px-3 -->
|
<!-- Alvo de 44px via py-3 px-3 -->
|
||||||
@ -99,7 +99,7 @@ async function entrar() {
|
|||||||
|
|
||||||
<!-- Senha -->
|
<!-- Senha -->
|
||||||
<div>
|
<div>
|
||||||
<label :for="senhaId" class="block text-sm font-semibold text-slate-700 mb-1.5">
|
<label :for="senhaId" class="block text-sm font-semibold text-slate-700 dark:text-slate-200 mb-1.5">
|
||||||
Senha
|
Senha
|
||||||
</label>
|
</label>
|
||||||
<Password
|
<Password
|
||||||
@ -147,7 +147,7 @@ async function entrar() {
|
|||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
:to="{ name: 'credenciamento' }"
|
:to="{ name: 'credenciamento' }"
|
||||||
class="block text-sm text-slate-600 py-2 hover:text-slate-800 transition-colors"
|
class="block text-sm text-slate-600 dark:text-slate-400 py-2 hover:text-slate-800 dark:hover:text-slate-200 transition-colors"
|
||||||
>
|
>
|
||||||
Ainda não tem acesso? <span class="text-primary font-semibold">Credenciar-se</span>
|
Ainda não tem acesso? <span class="text-primary font-semibold">Credenciar-se</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
@ -159,7 +159,7 @@ async function entrar() {
|
|||||||
<!-- Voltar — alvo de 44px via py-3 -->
|
<!-- Voltar — alvo de 44px via py-3 -->
|
||||||
<div class="text-center mt-4">
|
<div class="text-center mt-4">
|
||||||
<button
|
<button
|
||||||
class="inline-flex items-center gap-2 text-sm text-slate-600 hover:text-slate-800 transition-colors py-3 px-4 rounded-lg hover:bg-slate-100"
|
class="inline-flex items-center gap-2 text-sm text-slate-600 dark:text-slate-400 hover:text-slate-800 dark:hover:text-slate-200 transition-colors py-3 px-4 rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800"
|
||||||
@click="router.push({ name: 'home' })"
|
@click="router.push({ name: 'home' })"
|
||||||
>
|
>
|
||||||
<i class="pi pi-arrow-left text-xs" aria-hidden="true" />
|
<i class="pi pi-arrow-left text-xs" aria-hidden="true" />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user