267 lines
5.2 KiB
CSS
267 lines
5.2 KiB
CSS
*,
|
|
*::before,
|
|
*::after {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* Garante que o atributo/propriedade "hidden" sempre vença, mesmo em
|
|
elementos cujo próprio componente define display:flex/grid/etc. */
|
|
[hidden] {
|
|
display: none !important;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
height: 100%;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
font-family: var(--font-sans);
|
|
background: var(--bg-canvas);
|
|
color: var(--text-primary);
|
|
-webkit-font-smoothing: antialiased;
|
|
transition: background var(--transition-base), color var(--transition-base);
|
|
}
|
|
|
|
h1,
|
|
h2,
|
|
h3,
|
|
h4,
|
|
p {
|
|
margin: 0;
|
|
}
|
|
|
|
button,
|
|
input {
|
|
font-family: inherit;
|
|
color: inherit;
|
|
}
|
|
|
|
button {
|
|
cursor: pointer;
|
|
border: none;
|
|
background: none;
|
|
}
|
|
|
|
a {
|
|
color: inherit;
|
|
text-decoration: none;
|
|
}
|
|
|
|
ul {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
svg {
|
|
display: block;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.visually-hidden {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 1px;
|
|
overflow: hidden;
|
|
clip: rect(0 0 0 0);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
::selection {
|
|
background: var(--accent);
|
|
color: var(--accent-contrast);
|
|
}
|
|
|
|
/* Animações globais — rápidas de propósito (a ideia é sensação de fluidez, não
|
|
"efeito"), e sem nenhum @media (prefers-reduced-motion) desativando: decisão
|
|
deliberada do usuário, essas animações devem rodar sempre, independente da
|
|
preferência de acessibilidade do sistema operacional. */
|
|
@keyframes pidFadeIn {
|
|
from {
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes pidFadeSlideUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(6px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes pidScaleIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.96);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
/* Olhos do ícone "P.I.D." (o disquete) piscando ao clicar — usado tanto na
|
|
logo da sidebar (`sidebar-brand.js`, `layout.css`) quanto no ícone do
|
|
card de login (`login-logo-blink.js`), por isso mora aqui em vez de num
|
|
CSS específico de página. Cada olho é um <g class="pid-icon-eye"> sem
|
|
nenhum transform de atributo XML (a posição já vem dos cx/cy dos
|
|
círculos) — importante porque um transform de CSS aplicado a um elemento
|
|
que já tem transform de atributo SUBSTITUI o atributo inteiro, perdendo a
|
|
posição; `transform-box:fill-box` faz o scaleY girar em torno do próprio
|
|
olho, não da origem do SVG. */
|
|
.pid-icon-eye {
|
|
transform-box: fill-box;
|
|
transform-origin: center;
|
|
}
|
|
|
|
.pid-icon-eye.is-blinking {
|
|
animation: pidIconBlink 200ms ease-in-out;
|
|
}
|
|
|
|
@keyframes pidIconBlink {
|
|
0%, 100% {
|
|
transform: scaleY(1);
|
|
}
|
|
50% {
|
|
transform: scaleY(0.05);
|
|
}
|
|
}
|
|
|
|
/* Variante "susto" do clique na logo, só durante o tema sazonal Halloween
|
|
(`seasonal-theme.js`/`pidIsHalloweenActive()`) — substitui a piscada acima
|
|
enquanto o ícone P.I.D. normal é trocado pelo vampiro
|
|
(`pidApplyVampireIcon`/`pidApplyVampireFull`). `.pid-vamp-icon-rig` é o
|
|
grupo raiz injetado dentro do <svg> (sidebar colapsada/expandida e botão
|
|
do login); `.pid-vamp-face--friendly`/`--scare` são dois grupos sempre
|
|
presentes, cruzando opacidade entre si. Mesmo cuidado de `.pid-icon-eye`
|
|
com `transform-box:fill-box` pra girar/escalar em torno do próprio ícone,
|
|
não da origem do SVG. */
|
|
.pid-vamp-icon-rig,
|
|
.pid-vamp-cape-group {
|
|
transform-box: fill-box;
|
|
transform-origin: center;
|
|
}
|
|
|
|
.pid-vamp-face--friendly {
|
|
opacity: 1;
|
|
}
|
|
|
|
.pid-vamp-face--scare {
|
|
opacity: 0;
|
|
}
|
|
|
|
.pid-vamp-icon-rig.is-scaring {
|
|
animation: pidVampShake 900ms ease;
|
|
}
|
|
|
|
.pid-vamp-icon-rig.is-scaring .pid-vamp-cape-group {
|
|
animation: pidVampCapeBurst 900ms ease;
|
|
}
|
|
|
|
.pid-vamp-icon-rig.is-scaring .pid-vamp-face--friendly {
|
|
animation: pidVampFaceOut 900ms ease;
|
|
}
|
|
|
|
.pid-vamp-icon-rig.is-scaring .pid-vamp-face--scare {
|
|
animation: pidVampFaceIn 900ms ease;
|
|
}
|
|
|
|
@keyframes pidVampFaceOut {
|
|
0% {
|
|
opacity: 1;
|
|
}
|
|
14% {
|
|
opacity: 0.15;
|
|
}
|
|
22%, 70% {
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes pidVampFaceIn {
|
|
0% {
|
|
opacity: 0;
|
|
}
|
|
14% {
|
|
opacity: 0.85;
|
|
}
|
|
22%, 70% {
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes pidVampCapeBurst {
|
|
0%, 100% {
|
|
transform: scale(1) rotate(0deg);
|
|
}
|
|
16% {
|
|
transform: scale(1.12) rotate(-3deg);
|
|
}
|
|
30% {
|
|
transform: scale(1.05) rotate(1.5deg);
|
|
}
|
|
55% {
|
|
transform: scale(1.07) rotate(-1deg);
|
|
}
|
|
}
|
|
|
|
@keyframes pidVampShake {
|
|
0% {
|
|
transform: translateX(0) scale(1);
|
|
filter: drop-shadow(0 0 0 rgba(158, 50, 65, 0));
|
|
}
|
|
10% {
|
|
transform: translateX(-2.4px) scale(1.05);
|
|
}
|
|
18% {
|
|
transform: translateX(2.6px) scale(1.08);
|
|
filter: drop-shadow(0 0 10px rgba(158, 50, 65, 0.6));
|
|
}
|
|
28% {
|
|
transform: translateX(-1.8px) scale(1.04);
|
|
}
|
|
38% {
|
|
transform: translateX(1.4px) scale(1.02);
|
|
filter: drop-shadow(0 0 12px rgba(158, 50, 65, 0.65));
|
|
}
|
|
55% {
|
|
transform: translateX(0) scale(1.01);
|
|
filter: drop-shadow(0 0 8px rgba(158, 50, 65, 0.4));
|
|
}
|
|
100% {
|
|
transform: translateX(0) scale(1);
|
|
filter: drop-shadow(0 0 0 rgba(158, 50, 65, 0));
|
|
}
|
|
}
|
|
|
|
/* scrollbar discreta */
|
|
* {
|
|
scrollbar-width: thin;
|
|
scrollbar-color: var(--border-subtle) transparent;
|
|
}
|
|
|
|
*::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
*::-webkit-scrollbar-thumb {
|
|
background: var(--border-subtle);
|
|
border-radius: var(--radius-pill);
|
|
}
|