Skip to content

Commit a6f49c5

Browse files
authored
Merge pull request #6 from OPS-NC/feat/whitemode
[Claude] feat: thème clair de la page d'accueil
2 parents 9103c7e + ebbc0d9 commit a6f49c5

1 file changed

Lines changed: 109 additions & 29 deletions

File tree

‎templates/index.html‎

Lines changed: 109 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,22 @@
33
<head>
44
<meta charset="utf-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<meta name="color-scheme" content="light">
67
<title>DemoApp</title>
78
<style>
89
:root {
9-
--bg: #0b0f1a;
10-
--card: rgba(255, 255, 255, 0.04);
11-
--border: rgba(255, 255, 255, 0.09);
12-
--text: #f2f5fb;
13-
--muted: #8b95ad;
14-
--accent: #5b8cff;
15-
--accent-2: #b06bff;
16-
--accent-3: #2ee6a8;
10+
--bg: #eef1f7;
11+
--surface: #ffffff;
12+
--line: #e2e7f1;
13+
--line-strong: #cdd5e4;
14+
--text: #101423;
15+
--muted: #5c667d;
16+
--faint: #8b95a9;
17+
--accent: #2544d8;
18+
--accent-2: #6d28d9;
19+
--accent-3: #0d8f6b;
20+
--danger: #c62a25;
21+
--grid: rgba(16, 20, 35, 0.045);
1722
}
1823

1924
* { box-sizing: border-box; margin: 0; padding: 0; }
@@ -32,17 +37,30 @@
3237
overflow-x: hidden;
3338
}
3439

40+
/* Deux couches d'ambiance : teintes diffuses + trame technique, pensées pour le fond clair. */
3541
body::before {
3642
content: "";
3743
position: fixed;
3844
inset: -30%;
3945
background:
40-
radial-gradient(45rem 45rem at 20% 15%, rgba(91, 140, 255, 0.20), transparent 60%),
41-
radial-gradient(40rem 40rem at 80% 85%, rgba(176, 107, 255, 0.18), transparent 60%),
42-
radial-gradient(35rem 35rem at 60% 30%, rgba(46, 230, 168, 0.10), transparent 60%);
43-
filter: blur(20px);
46+
radial-gradient(45rem 45rem at 18% 12%, rgba(37, 68, 216, 0.10), transparent 62%),
47+
radial-gradient(40rem 40rem at 82% 88%, rgba(109, 40, 217, 0.09), transparent 62%),
48+
radial-gradient(35rem 35rem at 62% 28%, rgba(13, 143, 107, 0.07), transparent 62%);
49+
z-index: -2;
50+
animation: drift 32s ease-in-out infinite alternate;
51+
}
52+
53+
body::after {
54+
content: "";
55+
position: fixed;
56+
inset: 0;
57+
background-image:
58+
linear-gradient(var(--grid) 1px, transparent 1px),
59+
linear-gradient(90deg, var(--grid) 1px, transparent 1px);
60+
background-size: 4rem 4rem;
61+
mask-image: radial-gradient(70% 60% at 50% 40%, #000, transparent 100%);
62+
-webkit-mask-image: radial-gradient(70% 60% at 50% 40%, #000, transparent 100%);
4463
z-index: -1;
45-
animation: drift 24s ease-in-out infinite alternate;
4664
}
4765

4866
@keyframes drift {
@@ -80,25 +98,33 @@
8098

8199
.card {
82100
position: relative;
101+
overflow: hidden;
83102
padding: 2.25rem 2rem;
84-
border: 1px solid var(--border);
103+
border: 1px solid var(--line);
85104
border-radius: 1.25rem;
86-
background: var(--card);
87-
backdrop-filter: blur(16px);
88-
-webkit-backdrop-filter: blur(16px);
89-
box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.35);
105+
background: var(--surface);
106+
box-shadow:
107+
0 1px 2px rgba(16, 24, 40, 0.05),
108+
0 1.25rem 2.5rem -1rem rgba(16, 24, 40, 0.14);
90109
text-align: center;
91-
transition: transform 0.25s ease, border-color 0.25s ease;
110+
transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
92111
}
93112

94-
.card:hover { transform: translateY(-4px); border-color: rgba(255, 255, 255, 0.2); }
113+
.card:hover {
114+
transform: translateY(-4px);
115+
border-color: var(--line-strong);
116+
box-shadow:
117+
0 1px 2px rgba(16, 24, 40, 0.05),
118+
0 2rem 3.5rem -1rem rgba(16, 24, 40, 0.18);
119+
}
95120

121+
/* Sur fond clair la profondeur vient du liseré, pas d'un halo lumineux. */
96122
.card::after {
97123
content: "";
98124
position: absolute;
99-
inset-inline: 15%;
100-
top: -1px;
101-
height: 1px;
125+
inset-inline: 0;
126+
top: 0;
127+
height: 2px;
102128
background: linear-gradient(90deg, transparent, var(--glow, var(--accent)), transparent);
103129
}
104130

@@ -135,29 +161,77 @@
135161
word-break: break-all;
136162
}
137163

164+
/* Progression de la minute en cours : la seule pièce animée par les données. */
165+
.minute {
166+
margin: 1.1rem auto 0;
167+
width: 68%;
168+
height: 3px;
169+
border-radius: 999px;
170+
background: var(--line);
171+
overflow: hidden;
172+
}
173+
174+
.minute i {
175+
display: block;
176+
height: 100%;
177+
width: 0;
178+
border-radius: inherit;
179+
background: linear-gradient(90deg, var(--accent), var(--accent-2));
180+
transition: width 0.6s linear;
181+
}
182+
138183
.commit {
139184
margin-top: 0.45rem;
140185
font-size: 0.68rem;
141186
letter-spacing: 0.04em;
142-
color: #6b748c;
187+
color: var(--faint);
143188
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
144189
}
145190

146-
.commit span { color: #97a1b8; }
191+
.commit span { color: var(--text); }
147192

148193
.badge {
149-
display: inline-block;
194+
display: inline-flex;
195+
align-items: center;
196+
gap: 0.4rem;
150197
margin-top: 0.9rem;
151198
padding: 0.3rem 0.75rem;
152-
border: 1px solid var(--border);
199+
border: 1px solid var(--line);
153200
border-radius: 999px;
201+
background: #f7f9fc;
154202
font-size: 0.75rem;
155203
color: var(--muted);
156204
}
157205

206+
.dot {
207+
width: 0.45rem;
208+
height: 0.45rem;
209+
border-radius: 50%;
210+
background: var(--accent-3);
211+
box-shadow: 0 0 0 3px rgba(13, 143, 107, 0.15);
212+
animation: beat 2.4s ease-in-out infinite;
213+
}
214+
215+
.dot.ko {
216+
background: var(--danger);
217+
box-shadow: 0 0 0 3px rgba(198, 42, 37, 0.15);
218+
}
219+
220+
@keyframes beat {
221+
0%, 100% { opacity: 1; }
222+
50% { opacity: 0.35; }
223+
}
224+
158225
footer { color: var(--muted); font-size: 0.78rem; letter-spacing: 0.05em; }
159226

160-
.offline { color: #ff7b7b; }
227+
.offline { color: var(--danger); }
228+
229+
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
230+
231+
@media (prefers-reduced-motion: reduce) {
232+
body::before, .dot { animation: none; }
233+
.card, .minute i { transition: none; }
234+
}
161235
</style>
162236
</head>
163237
<body>
@@ -171,6 +245,7 @@ <h1>DemoApp</h1>
171245
<div class="label">Heure locale</div>
172246
<div class="value" id="time">{{ time }}</div>
173247
<div class="sub" id="date">{{ date }}</div>
248+
<div class="minute" aria-hidden="true"><i id="minute-fill"></i></div>
174249
<span class="badge" id="tz">{{ timezone }} (UTC{{ offset[:3] }}:{{ offset[3:] }})</span>
175250
</section>
176251

@@ -188,7 +263,9 @@ <h1>DemoApp</h1>
188263
{% if views is none %}<span class="offline">redis KO</span>{% else %}{{ views }}{% endif %}
189264
</div>
190265
<div class="sub">visites enregistrées</div>
191-
<span class="badge">Backend Redis</span>
266+
<span class="badge">
267+
<span class="dot{% if views is none %} ko{% endif %}"></span>Backend Redis
268+
</span>
192269
</section>
193270
</main>
194271

@@ -202,6 +279,7 @@ <h1>DemoApp</h1>
202279
function tick() {
203280
const el = document.getElementById("time");
204281
const dateEl = document.getElementById("date");
282+
const fill = document.getElementById("minute-fill");
205283
const now = new Date();
206284
try {
207285
el.textContent = now.toLocaleTimeString("fr-FR", { timeZone: tzName, hour12: false });
@@ -211,6 +289,8 @@ <h1>DemoApp</h1>
211289
} catch (e) {
212290
// timezone inconnue du navigateur : on laisse la valeur serveur
213291
}
292+
// Le décalage horaire ne change pas le rang de la seconde dans la minute.
293+
fill.style.width = ((now.getSeconds() + 1) / 60 * 100).toFixed(2) + "%";
214294
}
215295

216296
setInterval(tick, 1000);

0 commit comments

Comments
 (0)