Files
tribunal-app/src/app/globals.css
T
Valentin ROBIN 358bed0c2e Passe de polish visuel sur tout le site
Corrige deux incohérences trouvées en chemin : le compteur de passages dans le char en gold-bright sur marbre (même défaut de contraste déjà vu ailleurs), et le point du Crieur toujours rouge même pour un honneur positif. Réutilise les ornements existants mais jamais appelés (meander-divider entre le podium et le classement, DiamondDivider sur /profile avec une nouvelle convention de carte secondaire). Ajoute une ambiance discrète (fond qui respire très lentement, halo doré sur les cartes marbre, désactivés sous prefers-reduced-motion), étend les confettis et un nouveau son à Icare pour la parité avec la Corne d'Abondance, des loading.tsx sur les pages les plus consultées, et un petit ornement sur les états vides plutôt qu'un texte brut.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 15:03:52 +02:00

268 lines
7.4 KiB
CSS

@import "tailwindcss";
:root {
--ink: #0a1b33;
--ink-2: #0f2748;
--marble: #f4ecd8;
--marble-2: #e9dec2;
--gold: #c9a227;
--gold-bright: #e7c560;
--oxblood: #a5342a;
--sea: #2e6e7e;
--olive: #5e6b3b;
--silver: #c7cdd6;
--bronze: #b08d57;
--text-marble: #2a2116;
--text-mut: #7a6a4c;
--background: var(--ink);
--foreground: var(--marble);
}
@theme inline {
--color-ink: var(--ink);
--color-ink-2: var(--ink-2);
--color-marble: var(--marble);
--color-marble-2: var(--marble-2);
--color-gold: var(--gold);
--color-gold-bright: var(--gold-bright);
--color-oxblood: var(--oxblood);
--color-sea: var(--sea);
--color-olive: var(--olive);
--color-silver: var(--silver);
--color-bronze: var(--bronze);
--color-text-marble: var(--text-marble);
--color-text-mut: var(--text-mut);
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-heading: var(--font-cinzel);
--font-serif: var(--font-cormorant);
--font-sans: var(--font-manrope);
}
/* Intensité du dégradé "mer" du fond, en pourcentage — enregistrée via
@property pour qu'un navigateur qui la supporte anime une transition
fluide entre les deux valeurs de ambient-glow (sinon dégradation sans
casse : la valeur du keyframe s'applique quand même, juste sans lissage
intermédiaire). */
@property --sea-glow {
syntax: "<percentage>";
inherits: true;
initial-value: 30%;
}
body {
--sea-glow: 30%;
background:
radial-gradient(ellipse 80% 50% at 20% -10%, color-mix(in srgb, var(--ink-2) 75%, transparent) 0%, transparent 60%),
radial-gradient(ellipse 70% 60% at 100% 110%, color-mix(in srgb, var(--sea) var(--sea-glow), transparent) 0%, transparent 65%),
var(--ink);
background-attachment: fixed;
color: var(--foreground);
font-family: var(--font-sans), Arial, Helvetica, sans-serif;
}
*:focus-visible {
outline: 2px solid var(--gold-bright);
outline-offset: 2px;
}
/* Carte "marbre" : surface claire avec léger grain, bordure dorée fine. */
.marble-surface {
background:
radial-gradient(circle at 18% 12%, color-mix(in srgb, var(--marble-2) 65%, transparent) 0%, transparent 42%),
radial-gradient(circle at 82% 88%, color-mix(in srgb, var(--marble-2) 55%, transparent) 0%, transparent 48%),
linear-gradient(150deg, var(--marble) 0%, var(--marble) 55%, var(--marble-2) 100%);
color: var(--text-marble);
}
/* Frise à méandre (motif grec), séparateur horizontal discret. */
.meander-divider {
height: 10px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='10' viewBox='0 0 32 10'%3E%3Cpath d='M0 8 H6 V2 H16 V8 H22 V2 H32' fill='none' stroke='%23C9A227' stroke-width='1.3'/%3E%3C/svg%3E");
background-repeat: repeat-x;
background-position: center;
background-size: 32px 10px;
opacity: 0.45;
}
@keyframes points-flash {
0% {
background-color: color-mix(in srgb, var(--gold-bright) 55%, transparent);
}
100% {
background-color: transparent;
}
}
.animate-points-flash {
animation: points-flash 900ms ease-out;
}
/* Chiffre romain "gravé" dans le socle du podium. */
.engraved {
text-shadow:
0 1px 0 rgba(255, 255, 255, 0.35),
0 -1px 1px rgba(0, 0, 0, 0.35);
}
/* Socle du podium : marbre veiné + arête lumineuse en haut. */
.pedestal-marble {
position: relative;
background:
linear-gradient(100deg, transparent 0%, rgba(255, 255, 255, 0.12) 18%, transparent 32%),
linear-gradient(80deg, transparent 55%, rgba(255, 255, 255, 0.08) 68%, transparent 80%),
linear-gradient(180deg, color-mix(in srgb, var(--marble) 92%, white) 0%, var(--marble) 40%, var(--marble-2) 100%);
box-shadow:
inset 0 2px 0 rgba(255, 255, 255, 0.55),
0 10px 18px -6px rgba(10, 27, 51, 0.55);
}
.podium-glow {
box-shadow: 0 0 30px 6px color-mix(in srgb, var(--gold-bright) 45%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
/* Mer de nuit qui respire très lentement, plutôt qu'un fond figé — reste
imperceptible comme un vrai mouvement, juste une ambiance qui vit. */
@keyframes ambient-glow {
from {
--sea-glow: 22%;
}
to {
--sea-glow: 42%;
}
}
body {
animation: ambient-glow 40s ease-in-out infinite alternate;
}
/* Léger halo doré respirant sur les cartes marbre, façon lueur de
torche — un outline (jamais box-shadow/border, déjà utilisés par les
classes Tailwind de chaque carte) pour ne jamais entrer en conflit
avec l'ombre/la bordure propres à chaque usage. N'affecte pas la mise
en page (outline ne prend pas de place). */
@keyframes card-flicker {
0%,
100% {
outline-color: transparent;
}
50% {
outline-color: color-mix(in srgb, var(--gold) 35%, transparent);
}
}
.marble-surface {
outline: 1px solid transparent;
outline-offset: 2px;
animation: card-flicker 7s ease-in-out infinite;
}
@keyframes podium-rise {
0% {
opacity: 0;
transform: translateY(28px) scale(0.92);
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.animate-podium-rise {
animation: podium-rise 600ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
@keyframes wreath-pop {
0% {
opacity: 0;
transform: scale(0.5) translateY(6px);
}
70% {
opacity: 1;
transform: scale(1.08) translateY(0);
}
100% {
transform: scale(1) translateY(0);
}
}
.animate-wreath-pop {
animation: wreath-pop 500ms cubic-bezier(0.2, 0.7, 0.3, 1) 500ms both;
}
@keyframes reveal-pop {
0% {
opacity: 0;
transform: scale(0.82);
box-shadow: 0 0 0 0 color-mix(in srgb, var(--gold-bright) 0%, transparent);
}
60% {
opacity: 1;
transform: scale(1.04);
}
100% {
transform: scale(1);
box-shadow: 0 0 40px 8px color-mix(in srgb, var(--gold-bright) 45%, transparent);
}
}
.animate-reveal {
animation: reveal-pop 700ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
/* Simple fondu, sans mise à l'échelle — contrairement à reveal-pop,
utilisé sur des pièces de La Corne d'Abondance dont la taille exacte
doit être lisible dès la première frame (reveal-pop passe par 82% puis
104% avant de se stabiliser à 100%, ce qui faisait paraître une pièce
tout juste lâchée d'une taille différente de celle annoncée). */
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.animate-fade-in {
animation: fade-in 200ms ease-out both;
}
/* Avertissement de débordement (La Corne d'Abondance) : clignote sur les
pièces qui dépassent la ligne de danger pendant le délai de grâce
avant game over, pour signaler que le compte à rebours est en cours. */
@keyframes danger-blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.25;
}
}
.animate-danger-blink {
animation: danger-blink 500ms ease-in-out infinite;
}
/* Confettis de fin de partie (Le Vol d'Icare) : chute + rotation + fondu,
dérive latérale et vitesse propres à chaque confetti via variables CSS. */
@keyframes confetti-fall {
0% {
transform: translate(0, -10%) rotate(0deg);
opacity: 1;
}
100% {
transform: translate(var(--confetti-drift, 0px), 340px) rotate(var(--confetti-spin, 360deg));
opacity: 0;
}
}
.animate-confetti-fall {
animation: confetti-fall 1200ms ease-in both;
}
}