Skip to content

Commit e59d24e

Browse files
committed
improve banner
1 parent b4f276a commit e59d24e

2 files changed

Lines changed: 114 additions & 109 deletions

File tree

apps/web/app/globals.css

Lines changed: 83 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ header {
4545
font-family: var(--font-heading), system-ui, sans-serif;
4646
}
4747

48-
/* ===============================
49-
🌤️ Dynamic Weather Hero Banner (REALISTIC)
50-
================================ */
48+
/* =================================================
49+
🌤️ REALISTIC WEATHER HERO — FULL SYSTEM
50+
================================================= */
5151

5252
.hero {
5353
position: relative;
@@ -68,133 +68,121 @@ header {
6868
}
6969
}
7070

71-
/* Overlay para contraste do texto */
71+
/* Overlay */
7272
.hero-overlay {
7373
position: absolute;
7474
inset: 0;
7575
background: linear-gradient(
7676
to bottom,
77-
rgba(10, 37, 64, 0.45),
77+
rgba(10, 37, 64, 0.35),
7878
rgba(10, 37, 64, 0.75)
7979
);
80-
z-index: 3;
80+
z-index: 4;
8181
}
8282

8383
/* Conteúdo */
8484
.hero-content {
8585
position: relative;
86-
z-index: 4;
86+
z-index: 5;
8787
height: 100%;
8888
display: flex;
8989
flex-direction: column;
9090
justify-content: center;
9191
align-items: center;
92-
padding: 0 1.5rem;
9392
text-align: center;
93+
padding: 0 1.5rem;
9494
color: white;
9595
}
9696

97-
.hero-title {
98-
font-family: var(--font-heading);
99-
font-size: clamp(2rem, 4vw, 3.2rem);
100-
font-weight: 600;
101-
}
102-
103-
.hero-subtitle {
104-
margin-top: 1rem;
105-
max-width: 44rem;
106-
font-size: 1.15rem;
107-
color: #e5e7eb;
108-
}
109-
11097
/* =================================================
111-
☀️ CLEAR — céu limpo com sol visível
98+
☀️ CLEAR + SOL
11299
================================================= */
113100

114-
.hero-clear {
101+
.hero-clear,
102+
.hero-sunrise,
103+
.hero-sunset {
115104
background:
116-
radial-gradient(
117-
circle at 50% 18%,
118-
rgba(255, 255, 255, 0.55),
119-
rgba(255, 255, 255, 0.15),
120-
transparent 60%
121-
),
122105
linear-gradient(
123106
to bottom,
124107
#4facfe 0%,
125-
#00c6fb 40%,
108+
#00c6fb 45%,
126109
#0a2540 100%
127110
);
128-
background-size: 120% 120%;
129-
animation: skyMove 22s ease-in-out infinite;
130111
}
131112

132-
/* Halo solar animado */
133-
.hero-clear::before {
113+
/* Sol */
114+
.hero-clear::before,
115+
.hero-sunrise::before,
116+
.hero-sunset::before {
134117
content: "";
135118
position: absolute;
136-
top: 8%;
137-
left: 50%;
119+
top: var(--sun-y, 18%);
120+
left: var(--sun-x, 50%);
138121
width: 420px;
139122
height: 420px;
140123
transform: translateX(-50%);
141124
background: radial-gradient(
142125
circle,
143-
rgba(255, 255, 255, 0.35),
144-
rgba(255, 255, 255, 0.15),
126+
rgba(255,255,255,0.5),
127+
rgba(255,255,255,0.2),
145128
transparent 70%
146129
);
147130
filter: blur(40px);
148131
animation: sunPulse 6s ease-in-out infinite;
149132
z-index: 1;
150133
}
151134

152-
/* =================================================
153-
☁️ CLOUDS — nuvens em movimento
154-
================================================= */
135+
/* Amanhecer */
136+
.hero-sunrise {
137+
background:
138+
linear-gradient(
139+
to bottom,
140+
#f97316 0%,
141+
#fb7185 35%,
142+
#0a2540 100%
143+
);
144+
}
155145

156-
.hero-clouds {
146+
/* Entardecer */
147+
.hero-sunset {
157148
background:
158149
linear-gradient(
159150
to bottom,
160-
#94a3b8 0%,
161-
#64748b 45%,
162-
#1e293b 100%
151+
#f59e0b 0%,
152+
#fb7185 40%,
153+
#0a2540 100%
163154
);
164155
}
165156

166-
/* Camada de nuvens */
157+
/* =================================================
158+
☁️ CLOUDS
159+
================================================= */
160+
167161
.hero-clouds::before,
168-
.hero-clouds::after {
162+
.hero-rain::before {
169163
content: "";
170164
position: absolute;
171-
inset: -20%;
172-
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='400'%3E%3Cg fill='rgba(255,255,255,0.15)'%3E%3Cellipse cx='200' cy='200' rx='200' ry='80'/%3E%3Cellipse cx='500' cy='180' rx='250' ry='90'/%3E%3C/g%3E%3C/svg%3E");
165+
inset: -30%;
166+
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='400'%3E%3Cg fill='rgba(255,255,255,0.18)'%3E%3Cellipse cx='200' cy='200' rx='200' ry='80'/%3E%3Cellipse cx='500' cy='180' rx='260' ry='100'/%3E%3C/g%3E%3C/svg%3E");
173167
background-size: 800px 400px;
174-
animation: cloudsMove 90s linear infinite;
175-
z-index: 1;
176-
}
177-
178-
.hero-clouds::after {
179-
opacity: 0.5;
180-
animation-duration: 140s;
168+
animation: cloudsMove 120s linear infinite;
169+
z-index: 2;
181170
}
182171

183172
/* =================================================
184-
🌧️ RAIN — chuva animada
173+
🌧️ RAIN + CLOUDS
185174
================================================= */
186175

187176
.hero-rain {
188177
background:
189178
linear-gradient(
190179
to bottom,
191-
#0f172a 0%,
192-
#020617 100%
180+
#020617 0%,
181+
#0f172a 100%
193182
);
194183
}
195184

196-
/* Pingos de chuva */
197-
.hero-rain::before {
185+
.hero-rain::after {
198186
content: "";
199187
position: absolute;
200188
inset: 0;
@@ -205,71 +193,74 @@ header {
205193
transparent 1px,
206194
transparent 12px
207195
);
208-
animation: rainFall 0.7s linear infinite;
196+
animation: rainFall 0.6s linear infinite;
209197
opacity: 0.35;
210-
z-index: 2;
198+
z-index: 3;
211199
}
212200

213201
/* =================================================
214-
🌙 NIGHT — céu noturno profundo
202+
🌩️ LIGHTNING
203+
================================================= */
204+
205+
.hero-rain::before {
206+
animation:
207+
cloudsMove 120s linear infinite,
208+
lightningFlash 14s infinite;
209+
}
210+
211+
@keyframes lightningFlash {
212+
0%, 96%, 100% {
213+
opacity: 1;
214+
}
215+
97% {
216+
opacity: 1;
217+
filter: brightness(1.6);
218+
}
219+
98% {
220+
filter: brightness(1);
221+
}
222+
}
223+
224+
/* =================================================
225+
🌙 NIGHT
215226
================================================= */
216227

217228
.hero-night {
218229
background:
219-
radial-gradient(
220-
circle at 50% 30%,
221-
rgba(255, 255, 255, 0.08),
222-
transparent 60%
223-
),
224230
linear-gradient(
225231
to bottom,
226232
#020617 0%,
227233
#020617 100%
228234
);
229235
}
230236

231-
/* ===============================
232-
Animações
233-
================================ */
234-
235-
@keyframes skyMove {
236-
0% {
237-
background-position: 50% 0%;
238-
}
239-
50% {
240-
background-position: 50% 100%;
241-
}
242-
100% {
243-
background-position: 50% 0%;
244-
}
245-
}
237+
/* =================================================
238+
Animations
239+
================================================= */
246240

247241
@keyframes sunPulse {
248-
0%,
249-
100% {
250-
transform: translateX(-50%) scale(1);
242+
0%, 100% {
251243
opacity: 0.9;
252244
}
253245
50% {
254-
transform: translateX(-50%) scale(1.05);
255246
opacity: 1;
256247
}
257248
}
258249

259250
@keyframes cloudsMove {
260-
0% {
251+
from {
261252
transform: translateX(-10%);
262253
}
263-
100% {
254+
to {
264255
transform: translateX(10%);
265256
}
266257
}
267258

268259
@keyframes rainFall {
269-
0% {
260+
from {
270261
background-position-y: 0;
271262
}
272-
100% {
263+
to {
273264
background-position-y: 100%;
274265
}
275266
}

apps/web/hooks/useWeather.ts

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,47 @@
22

33
import { useEffect, useState } from "react";
44

5-
type WeatherType = "clear" | "clouds" | "rain" | "night";
5+
export type Weather =
6+
| "clear"
7+
| "clouds"
8+
| "rain"
9+
| "night"
10+
| "sunrise"
11+
| "sunset";
612

7-
export function useWeather(): WeatherType {
8-
const [weather, setWeather] = useState<WeatherType>("clear");
13+
export function useWeather(): Weather {
14+
const [weather, setWeather] = useState<Weather>("clear");
915

1016
useEffect(() => {
11-
async function loadWeather() {
17+
async function load() {
1218
try {
13-
// Localização por IP (sem permissão do usuário)
14-
const locRes = await fetch("https://ipapi.co/json/");
15-
const loc = await locRes.json();
19+
const hour = new Date().getHours();
1620

17-
const weatherRes = await fetch(
18-
`https://api.open-meteo.com/v1/forecast?latitude=${loc.latitude}&longitude=${loc.longitude}&current_weather=true`
19-
);
20-
const data = await weatherRes.json();
21+
if (hour >= 5 && hour <= 7) {
22+
setWeather("sunrise");
23+
return;
24+
}
2125

22-
const code = data.current_weather.weathercode;
23-
const hour = new Date().getHours();
26+
if (hour >= 17 && hour <= 19) {
27+
setWeather("sunset");
28+
return;
29+
}
2430

25-
// Noite (prioridade)
26-
if (hour >= 19 || hour <= 6) {
31+
if (hour >= 20 || hour <= 4) {
2732
setWeather("night");
2833
return;
2934
}
3035

31-
// Mapeamento simples e robusto
36+
const locRes = await fetch("https://ipapi.co/json/");
37+
const loc = await locRes.json();
38+
39+
const res = await fetch(
40+
`https://api.open-meteo.com/v1/forecast?latitude=${loc.latitude}&longitude=${loc.longitude}&current_weather=true`
41+
);
42+
const data = await res.json();
43+
44+
const code = data?.current_weather?.weathercode;
45+
3246
if (code <= 1) setWeather("clear");
3347
else if (code <= 3) setWeather("clouds");
3448
else setWeather("rain");
@@ -37,7 +51,7 @@ export function useWeather(): WeatherType {
3751
}
3852
}
3953

40-
loadWeather();
54+
load();
4155
}, []);
4256

4357
return weather;

0 commit comments

Comments
 (0)