HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>天气奇观:行为艺术</title>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Lobster&family=Pacifico&family=Press+Start+2P&display=swap" rel="stylesheet">
<style>
/* --- 基础与字体 --- */
:root {
--glow-color-1: #ff00ff;
--glow-color-2: #00ffff;
--glow-color-3: #ffff00;
}
body {
margin: 0;
padding: 0;
font-family: 'Orbitron', 'Press Start 2P', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden;
background-color: #000;
color: #fff;
perspective: 2000px; /* For 3D effects on children */
}
/* --- 1. 扭曲的宇宙背景层 --- */
.cosmic-void-background {
position: fixed;
top: -50%; left: -50%;
width: 200%; height: 200%;
background: linear-gradient(125deg,
#000011, #000022, #110033,
var(--glow-color-1), var(--glow-color-2),
#330011, #002200, #001122);
background-size: 1200% 1200%;
filter: blur(100px) brightness(0.7);
animation: cosmicDrift 180s cubic-bezier(0.42, 0, 0.58, 1) infinite alternate,
hueRotateBackground 90s linear infinite;
z-index: -2;
}
@keyframes cosmicDrift {
0% { transform: translate(0%, 0%) rotate(0deg) scale(1); }
100% { transform: translate(15%, 10%) rotate(720deg) scale(1.2); }
}
@keyframes hueRotateBackground {
0% { filter: blur(100px) brightness(0.7) hue-rotate(0deg); }
100% { filter: blur(100px) brightness(0.7) hue-rotate(360deg); }
}
/* --- 2. 悬浮的新拟态“控制台”框架 --- */
.neumorphic-console-frame {
position: relative;
padding: 30px; /* Reduced padding for more content space */
border-radius: 60px;
background: rgba(20, 20, 35, 0.2);
box-shadow:
inset 15px 15px 30px rgba(0,0,0,0.6),
inset -15px -15px 30px rgba(80,80,100,0.25),
30px 30px 60px rgba(0,0,0,0.8),
-30px -30px 60px rgba(50,50,70,0.15),
0 0 100px rgba(var(--glow-color-1), 0.3),
0 0 150px rgba(var(--glow-color-2), 0.3);
backdrop-filter: blur(18px) saturate(180%);
border: 3px solid rgba(255,255,255,0.05);
transform: rotateY(5deg) rotateX(3deg);
animation: frameFloat 12s ease-in-out infinite alternate;
transition: transform 0.2s ease-out; /* For mouse interaction */
}
@keyframes frameFloat {
0% { transform: rotateY(7deg) rotateX(4deg) translateY(-15px) scale(0.98); }
100% { transform: rotateY(-5deg) rotateX(-2deg) translateY(15px) scale(1.02); }
}
/* --- 3. 主天气卡片 --- */
.weather-card-dimension-X {
position: relative;
width: 420px;
height: 750px;
background: transparent;
border-radius: 40px;
overflow: hidden;
box-shadow: 0 0 80px rgba(var(--glow-color-2), 0.6), 0 0 120px rgba(var(--glow-color-1), 0.6), inset 0 0 30px rgba(var(--glow-color-3),0.3);
transform-style: preserve-3d;
border-width: 4px;
border-style: solid;
border-image-slice: 1;
border-image-source: conic-gradient(from 0deg, var(--glow-color-1), var(--glow-color-2), var(--glow-color-3), var(--glow-color-1));
animation: cardBreathing 4s ease-in-out infinite alternate, borderShine 6s linear infinite;
}
@keyframes borderShine {
0% { border-image-source: conic-gradient(from 0deg, var(--glow-color-1), var(--glow-color-2), var(--glow-color-3), var(--glow-color-1)); }
25% { border-image-source: conic-gradient(from 90deg, var(--glow-color-1), var(--glow-color-2), var(--glow-color-3), var(--glow-color-1)); }
50% { border-image-source: conic-gradient(from 180deg, var(--glow-color-1), var(--glow-color-2), var(--glow-color-3), var(--glow-color-1)); }
75% { border-image-source: conic-gradient(from 270deg, var(--glow-color-1), var(--glow-color-2), var(--glow-color-3), var(--glow-color-1)); }
100% { border-image-source: conic-gradient(from 360deg, var(--glow-color-1), var(--glow-color-2), var(--glow-color-3), var(--glow-color-1)); }
}
@keyframes cardBreathing {
from { transform: scale(0.97) rotateZ(-1deg); box-shadow: 0 0 70px rgba(var(--glow-color-2), 0.5), 0 0 110px rgba(var(--glow-color-1), 0.5), inset 0 0 20px rgba(var(--glow-color-3),0.2); }
to { transform: scale(1.03) rotateZ(1deg); box-shadow: 0 0 100px rgba(var(--glow-color-2), 0.7), 0 0 150px rgba(var(--glow-color-1), 0.7), inset 0 0 40px rgba(var(--glow-color-3),0.4); }
}
/* 3.1 卡片动态毛玻璃背景 */
.card-frosted-glass-aurora {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background-image:
radial-gradient(ellipse at 20% 20%, rgba(var(--glow-color-1),0.6) 0%, transparent 60%),
radial-gradient(ellipse at 80% 30%, rgba(var(--glow-color-2),0.6) 0%, transparent 60%),
radial-gradient(ellipse at 50% 80%, rgba(var(--glow-color-3),0.5) 0%, transparent 70%);
animation: auroraShift 15s cubic-bezier(0.68, -0.55, 0.27, 1.55) infinite alternate;
backdrop-filter: blur(30px) saturate(250%) brightness(1.3);
opacity: 0.85;
z-index: -1;
transform: scale(1.1); /* Ensure blur covers edges */
}
@keyframes auroraShift {
0% { background-position: 0% 0%, 100% 50%, 50% 100%; opacity: 0.7;}
50% { background-position: 100% 100%, 0% 0%, 100% 0%; opacity: 1;}
100% { background-position: 0% 0%, 100% 50%, 50% 100%; opacity: 0.7;}
}
/* 3.2 故障艺术城市名称 + 赛博朋克时间 */
.glitch-city-header {
text-align: center;
padding: 25px 15px 15px 15px;
position: relative;
z-index: 10;
}
.city-name {
font-family: 'Press Start 2P', 'Orbitron', cursive;
font-size: 2.5em; /* Adjusted for longer text */
line-height: 1.1;
color: #fff;
text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 20px var(--glow-color-2), 0 0 30px var(--glow-color-2), 0 0 40px var(--glow-color-1);
position: relative;
animation: textGlitchMaster 3s infinite steps(1, end);
margin-bottom: 8px;
}
.city-name span {
position: relative;
z-index: 1;
}
.city-name::before, .city-name::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: transparent; /* Should match .card-frosted-glass-aurora or main card body for effect */
overflow: hidden;
clip: rect(0, 900px, 0, 0);
}
.city-name::before {
left: 3px;
text-shadow: -3px 0 var(--glow-color-1);
animation: glitchSkew1 2.5s infinite linear alternate-reverse;
}
.city-name::after {
left: -3px;
text-shadow: -3px 0 var(--glow-color-2), 3px 3px var(--glow-color-1);
animation: glitchSkew2 2s infinite linear alternate-reverse;
}
@keyframes textGlitchMaster {
0% { transform: translate(0,0) skew(0deg); opacity: 1;}
5% { transform: translate(-4px, 3px) skew(1deg); opacity: 0.7;}
10% { transform: translate(3px, -2px) skew(-0.5deg); opacity: 1;}
15% { transform: translate(-2px, 2px) skew(0.8deg); opacity: 0.6;}
20% { transform: translate(0,0) skew(0deg); opacity: 1;}
/* ... more steps for variety ... */
100% { transform: translate(0,0) skew(0deg); opacity: 1;}
}
@keyframes glitchSkew1 {
0% { clip: rect(12px, 9999px, 88px, 0); transform: skew(0.5deg); }
10% { clip: rect(3px, 9999px, 102px, 0); transform: skew(-0.3deg); }
20% { clip: rect(85px, 9999px, 4px, 0); transform: skew(0.8deg); }
30% { clip: rect(60px, 9999px, 70px, 0); transform: skew(-0.6deg); }
40% { clip: rect(22px, 9999px, 55px, 0); transform: skew(0.2deg); }
50% { clip: rect(90px, 9999px, 33px, 0); transform: skew(-0.4deg); }
60% { clip: rect(1px, 9999px, 80px, 0); transform: skew(0.7deg); }
70% { clip: rect(75px, 9999px, 25px, 0); transform: skew(-0.1deg); }
80% { clip: rect(40px, 9999px, 95px, 0); transform: skew(0.4deg); }
90% { clip: rect(10px, 9999px, 5px, 0); transform: skew(-0.8deg); }
100% { clip: rect(66px, 9999px, 48px, 0); transform: skew(0.1deg); }
}
@keyframes glitchSkew2 { /* similar to glitchSkew1 but with different values and timing */
0% { clip: rect(80px, 9999px, 15px, 0); transform: skew(-0.4deg); }
10% { clip: rect(5px, 9999px, 90px, 0); transform: skew(0.6deg); }
20% { clip: rect(70px, 9999px, 22px, 0); transform: skew(-0.2deg); }
30% { clip: rect(30px, 9999px, 85px, 0); transform: skew(0.9deg); }
40% { clip: rect(95px, 9999px, 10px, 0); transform: skew(-0.7deg); }
50% { clip: rect(50px, 9999px, 60px, 0); transform: skew(0.3deg); }
60% { clip: rect(20px, 9999px, 77px, 0); transform: skew(-0.5deg); }
70% { clip: rect(88px, 9999px, 3px, 0); transform: skew(0.1deg); }
80% { clip: rect(45px, 9999px, 65px, 0); transform: skew(-0.9deg); }
90% { clip: rect(18px, 9999px, 98px, 0); transform: skew(0.5deg); }
100% { clip: rect(72px, 9999px, 40px, 0); transform: skew(-0.3deg); }
}
.cyber-time {
font-family: 'Orbitron', monospace;
font-size: 1.1em;
color: var(--glow-color-2);
letter-spacing: 4px;
text-shadow: 0 0 10px var(--glow-color-2), 0 0 20px var(--glow-color-2);
animation: pulseNeon 1.5s infinite alternate;
}
@keyframes pulseNeon {
from { opacity: 0.6; text-shadow: 0 0 8px var(--glow-color-2), 0 0 15px var(--glow-color-2); }
to { opacity: 1; text-shadow: 0 0 15px var(--glow-color-2), 0 0 30px var(--glow-color-2), 0 0 5px #fff; }
}
/* 3.3 核心天气信息 */
.weather-core-explosion {
display: flex;
flex-direction: column;
align-items: center;
padding: 10px 0;
z-index: 5;
position: relative;
}
.temperature-supernova {
font-family: 'Lobster', 'Orbitron', cursive;
font-size: 7.5em; /* HUGE */
font-weight: 900;
position: relative;
background: linear-gradient(145deg, var(--glow-color-1), var(--glow-color-2), var(--glow-color-3), #ff60a0, var(--glow-color-1));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400% 400%;
animation: gradientTextShift 4s ease-in-out infinite alternate, tempPulseSupernova 1.2s infinite;
text-shadow: 0 0 10px rgba(255,255,255,0.3),
0 0 20px rgba(var(--glow-color-1),0.4),
0 0 35px rgba(var(--glow-color-2),0.4),
0 0 50px rgba(var(--glow-color-3),0.3);
}
.temperature-supernova .temp-unit {
font-size: 0.25em;
vertical-align: text-top;
display: inline-block;
transform: translateY(-15px);
background: linear-gradient(135deg, #eee, #fff, #ddd);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 0 5px #fff;
}
.temp-rings {
position: absolute;
width: 180%; height: 180%;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
z-index: -1;
}
.temp-rings::before, .temp-rings::after {
content: '';
position: absolute;
border-radius: 50%;
border-style: solid;
border-color: transparent;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.temp-rings::before { /* Outer ring */
width: 100%; height: 100%;
top: 0; left: 0;
border-width: 7px;
border-top-color: var(--glow-color-1);
border-right-color: var(--glow-color-1);
opacity: 0.8;
animation: spinRing 2.5s linear infinite;
}
.temp-rings::after { /* Inner ring */
width: 80%; height: 80%;
top: 10%; left: 10%;
border-width: 5px;
border-bottom-color: var(--glow-color-2);
border-left-color: var(--glow-color-2);
opacity: 0.6;
animation: spinRing 3.5s linear infinite reverse;
}
@keyframes gradientTextShift {
0% { background-position: 0% 50%; }
100% { background-position: 100% 50%; }
}
@keyframes tempPulseSupernova {
0%, 100% { transform: scale(1); filter: brightness(1); }
50% { transform: scale(1.08); filter: brightness(1.5) saturate(1.5); }
}
@keyframes spinRing {
to { transform: rotate(360deg); }
}
.weather-icon-portal {
width: 160px;
height: 160px;
margin: 0px 0;
animation: iconLevitateDistort 5s ease-in-out infinite alternate;
filter: drop-shadow(0 0 10px var(--glow-color-2)) drop-shadow(0 0 20px var(--glow-color-1));
}
#extremeWeatherIcon { width: 100%; height: 100%; }
/* SVG specific animations for paths/circles inside JS or specific CSS */
@keyframes iconLevitateDistort {
0% { transform: translateY(-12px) rotateZ(-8deg) scale(0.9) skewX(5deg); }
50% { transform: translateY(12px) rotateZ(8deg) scale(1.1) skewX(-5deg); }
100% { transform: translateY(-12px) rotateZ(-8deg) scale(0.9) skewX(5deg); }
}
.weather-description-hyperbole {
font-family: 'Pacifico', 'Lobster', cursive;
font-size: 1.6em;
text-align: center;
padding: 0 20px;
margin-top: -5px;
color: #f0f0f0;
text-shadow: 1px 1px 3px #000, 0 0 8px var(--glow-color-1), 0 0 15px var(--glow-color-1), 0 0 25px var(--glow-color-3);
animation: textMorphColor 12s linear infinite alternate;
line-height: 1.3;
}
@keyframes textMorphColor {
0%, 100% { opacity: 0.85; transform: scale(0.97) skewY(1deg); color: #ffccff; }
25% { opacity: 1; transform: scale(1.03) skewY(-1deg); color: #ccffff; }
50% { opacity: 0.9; transform: scale(1) skewY(0.5deg); color: #ffffcc; }
75% { opacity: 0.95; transform: scale(1.02) skewY(-0.5deg); color: #f0f0f0; }
}
/* 3.4 附加信息 - 新拟态按钮 + 动态条 */
.additional-info-matrix {
display: grid;
grid-template-columns: 1fr 1fr; /* Two columns */
gap: 18px;
padding: 20px;
margin-top: 10px;
}
.info-pod {
padding: 12px;
border-radius: 20px;
text-align: center;
font-size: 0.9em;
background: rgba(30, 30, 55, 0.5);
box-shadow:
inset 3px 3px 6px rgba(0,0,0,0.6),
inset -3px -3px 6px rgba(100,100,120,0.3),
3px 3px 8px rgba(0,0,0,0.4);
transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
position: relative;
overflow: hidden; /* For inner shine effect */
}
.info-pod::before { /* Shine effect */
content: '';
position: absolute;
top: -50%; left: -50%;
width: 200%; height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.2) 0%, transparent 40%);
transform: rotate(0deg);
opacity: 0;
transition: opacity 0.4s ease, transform 0.4s ease;
}
.info-pod:hover::before {
opacity: 1;
transform: rotate(15deg) scale(0.8);
}
.info-pod:hover {
transform: translateY(-8px) scale(1.08);
box-shadow:
inset 4px 4px 8px rgba(0,0,0,0.7),
inset -4px -4px 8px rgba(110,110,130,0.35),
8px 8px 15px rgba(0,0,0,0.6),
0 0 25px var(--glow-color-3), 0 0 15px var(--glow-color-2);
}
.info-pod.full-width { /* For the third item */
grid-column: 1 / -1;
}
.info-label {
display: block;
font-size: 0.75em;
color: #bbb;
margin-bottom: 6px;
font-family: 'Press Start 2P';
text-transform: uppercase;
letter-spacing: 1px;
}
.info-value {
font-size: 1.2em;
font-weight: bold;
color: #fff;
margin-bottom: 5px;
font-family: 'Orbitron';
}
.dynamic-bar {
width: 90%;
height: 12px;
background: rgba(0,0,0,0.4);
border-radius: 6px;
margin: 8px auto 5px auto;
position: relative;
overflow: hidden;
border: 1px solid rgba(255,255,255,0.1);
}
.dynamic-bar span { /* The actual bar fill */
position: absolute;
left: 0; top: 0; height: 100%;
background: linear-gradient(90deg, var(--glow-color-2), var(--glow-color-1), var(--glow-color-3));
background-size: 300% 100%;
border-radius: 6px;
box-shadow: 0 0 8px var(--glow-color-2), 0 0 15px var(--glow-color-1);
transition: width 2.5s cubic-bezier(0.165, 0.84, 0.44, 1);
animation: barShine 3s linear infinite;
}
@keyframes barShine {
0% { background-position: 0% 50%; }
100% { background-position: 100% 50%; }
}
.info-icon {
font-size: 1.8em;
display: inline-block;
margin-top: 8px;
color: var(--glow-color-3);
text-shadow: 0 0 5px var(--glow-color-3);
}
.wind-vortex { animation: spinTurbulent 1.2s linear infinite; }
.humidity-nexus { animation: pulseDrip 1.8s ease-in-out infinite; }
.reality-glitch { animation: glitchTextSmall 0.7s steps(2, end) infinite; color: var(--glow-color-1); }
@keyframes spinTurbulent {
0% { transform: rotate(0deg) scale(1); }
50% { transform: rotate(180deg) scale(1.1); }
100% { transform: rotate(360deg) scale(1); }
}
@keyframes pulseDrip {
0%,100% {transform: scale(1) translateY(0); opacity: 0.7;}
50% {transform: scale(1.25) translateY(-3px); opacity: 1; color: var(--glow-color-2);}
}
@keyframes glitchTextSmall {
0% { transform: translate(0,0); }
25% { transform: translate(2px, -1px) skewX(5deg); }
50% { transform: translate(-1px, 2px) skewY(-3deg); }
75% { transform: translate(1px, 1px) skewX(-2deg); }
100% { transform: translate(0,0); }
}
/* 3.5 未来几小时预报 */
.forecast-continuum {
display: flex;
justify-content: space-around;
padding: 15px 10px;
border-top: 2px dashed rgba(255,255,255,0.25);
margin-top: 20px;
background: rgba(0,0,0,0.2);
}
.forecast-capsule {
padding: 12px 8px;
border-radius: 15px;
background: rgba(255,255,255,0.03);
backdrop-filter: blur(8px) brightness(1.2);
text-align: center;
font-size: 0.85em;
width: 85px;
transition: transform 0.35s ease, box-shadow 0.35s ease;
animation: forecastWobble 6s ease-in-out infinite alternate;
animation-delay: calc(var(--i, 0) * 0.3s);
border: 1px solid rgba(255,255,255,0.1);
box-shadow: 0 5px 10px rgba(0,0,0,0.3);
}
.forecast-capsule:hover {
transform: translateY(-12px) rotateZ(7deg) scale(1.1);
box-shadow: 0 12px 25px rgba(0,0,0,0.5), 0 0 20px var(--glow-color-1), 0 0 10px #fff;
background: rgba(255,255,255,0.08);
}
.time-slice { display: block; margin-bottom: 4px; font-weight: bold; color: #ccc; font-size: 0.9em; }
.temp-future { display: block; margin-bottom: 4px; font-size: 1.3em; font-weight: bold; color: #fff; }
.icon-future { font-size: 2em; line-height: 1; animation: iconPulseSimple 2s infinite; display: inline-block; }
@keyframes forecastWobble {
from { transform: translateY(0px) rotateZ(-2deg); }
to { transform: translateY(-6px) rotateZ(2deg); }
}
@keyframes iconPulseSimple {
0%, 100% { transform: scale(1); opacity: 0.8; }
50% { transform: scale(1.15); opacity: 1; }
}
/* 3.6 底部装饰性“能量核心” */
.energy-core-pulsar {
width: 60%;
height: 15px;
background: linear-gradient(90deg, var(--glow-color-1), var(--glow-color-2), var(--glow-color-3), var(--glow-color-1));
background-size: 300% 100%;
margin: 20px auto 15px;
border-radius: 10px;
box-shadow: 0 0 10px var(--glow-color-1), 0 0 20px var(--glow-color-2), 0 0 30px var(--glow-color-3), inset 0 0 8px rgba(255,255,255,0.6);
animation: corePulseShiftColor 2.5s linear infinite;
}
@keyframes corePulseShiftColor {
0% { background-position: 0% 50%; filter: brightness(0.8) hue-rotate(0deg); }
50% { background-position: 150% 50%; filter: brightness(1.5) hue-rotate(180deg); }
100% { background-position: 300% 50%; filter: brightness(0.8) hue-rotate(360deg); }
}
/* --- 4. 周围漂浮的装饰性几何体/粒子 --- */
.floating-particle {
position: fixed; /* Changed to fixed to float around the screen */
border-radius: 50%;
background: radial-gradient(circle, rgba(var(--glow-color-2),0.9) 0%, rgba(var(--glow-color-1),0.9) 100%);
box-shadow: 0 0 8px var(--glow-color-2), 0 0 15px var(--glow-color-1), 0 0 5px #fff;
filter: blur(1.5px);
animation: particleDanceScreen 10s infinite ease-in-out;
z-index: -1; /* Behind console frame but above background */
}
.particle-1 { width: 25px; height: 25px; top: 15%; left: 8%; animation-duration: 12s; opacity: 0.7; }
.particle-2 { width: 35px; height: 35px; top: 75%; left: 92%; animation-duration: 9s; animation-delay: -4s; opacity: 0.8; }
.particle-3 { width: 18px; height: 18px; top: 40%; left: 2%; animation-duration: 16s; animation-delay: -8s; opacity: 0.6; }
.particle-4 { width: 30px; height: 30px; top: 20%; left: 85%; animation-duration: 10s; animation-delay: -2s; opacity: 0.75; }
.particle-5 { width: 22px; height: 22px; top: 85%; left: 10%; animation-duration: 14s; animation-delay: -6s; opacity: 0.65; }
@keyframes particleDanceScreen {
0%, 100% { transform: translate(0,0) scale(1) rotate(0deg); opacity: 0.4; filter: blur(2px) brightness(0.8); }
25% { transform: translate(40px, -60px) scale(1.3) rotate(120deg); opacity: 1; filter: blur(0.5px) brightness(1.2); }
50% { transform: translate(-30px, 50px) scale(0.7) rotate(240deg); opacity: 0.6; filter: blur(1.5px) brightness(1); }
75% { transform: translate(60px, 30px) scale(1.15) rotate(360deg); opacity: 0.9; filter: blur(1px) brightness(1.1); }
}
/* --- 5. 行为艺术家的“满意度”计量条 --- */
.artist-satisfaction-meter {
position: fixed;
bottom: 25px;
left: 50%;
transform: translateX(-50%);
width: 350px;
height: 35px;
background: rgba(10,0,10,0.8);
border: 3px solid;
border-image-slice: 1;
border-image-source: linear-gradient(to right, var(--glow-color-1), var(--glow-color-2));
border-radius: 20px;
padding: 5px;
box-shadow: 0 0 20px var(--glow-color-1), 0 0 10px #fff;
z-index: 1000;
overflow: hidden;
}
.meter-bar {
width: 0%;
height: 100%;
background: linear-gradient(90deg, #00ff00, #ffff00, #ffaa00, #ff0000, #cc00ff);
background-size: 200% 100%;
border-radius: 12px;
display: flex;
justify-content: center;
align-items: center;
color: #000;
font-family: 'Press Start 2P';
font-size: 0.9em;
transition: width 5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 1s;
overflow: hidden;
white-space: nowrap;
text-shadow: 1px 1px 0px #fff, -1px -1px 0px #fff, 1px -1px 0px #fff, -1px 1px 0px #fff; /* Better text visibility */
}
.meter-bar span {
/* mix-blend-mode: difference; /* Can be problematic with complex gradients */
/* color: white; Fallback/Primary color */
animation: meterTextPulse 1s infinite;
}
@keyframes meterTextPulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
</style>
</head>
<body>
<!-- 1. 扭曲的宇宙背景层 - 动态模糊渐变 -->
<div class="cosmic-void-background"></div>
<!-- 2. 悬浮的新拟态“控制台”框架 - 毛玻璃效果之上 -->
<div class="neumorphic-console-frame">
<!-- 3. 主天气卡片 - 核心冲击区域 -->
<div class="weather-card-dimension-X">
<!-- 3.1 卡片动态毛玻璃背景层 -->
<div class="card-frosted-glass-aurora"></div>
<!-- 3.2 故障艺术城市名称 + 赛博朋克时间 -->
<header class="glitch-city-header">
<h1 class="city-name" data-text="湮灭之都 XYLOS"><span>湮灭之都 XYLOS</span></h1>
<p class="cyber-time">[CYBER_TIME]</p>
</header>
<!-- 3.3 核心天气信息 - 巨大,动态,视觉爆炸 -->
<main class="weather-core-explosion">
<div class="temperature-supernova">
<span class="temp-value">NaN</span><span class="temp-unit">°C</span>
<div class="temp-rings"></div>
</div>
<div class="weather-icon-portal">
<svg id="extremeWeatherIcon" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="iconGradientMain" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:var(--glow-color-1);stop-opacity:1" />
<stop offset="100%" style="stop-color:var(--glow-color-2);stop-opacity:1" />
</linearGradient>
<linearGradient id="iconGradientAlt" x1="0%" y1="100%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:var(--glow-color-3);stop-opacity:1" />
<stop offset="100%" style="stop-color:#00ff88;stop-opacity:1" />
</linearGradient>
<filter id="iconGlow">
<feGaussianBlur stdDeviation="3.5" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<g filter="url(#iconGlow)">
<!-- Pulsating Core Star -->
<polygon points="100,10 40,198 190,78 10,78 160,198" fill="url(#iconGradientMain)">
<animateTransform attributeName="transform" type="rotate" from="0 100 100" to="360 100 100" dur="10s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="0.6;1;0.6" dur="3s" repeatCount="indefinite"/>
</polygon>
<!-- Inner Chaotic Shape -->
<path d="M100,50 Q80,80 100,100 Q120,80 100,50 Z M80,100 L100,120 L120,100 Z" fill="url(#iconGradientAlt)" opacity="0.7">
<animateTransform attributeName="transform" type="scale" values="1;1.2;0.8;1.1;1" dur="4s" repeatCount="indefinite" additive="sum"/>
<animateTransform attributeName="transform" type="rotate" from="0 100 100" to="-720 100 100" dur="7s" repeatCount="indefinite" additive="sum"/>
</path>
<!-- Orbiting Sparks -->
<circle cx="100" cy="20" r="7" fill="#FFF">
<animateMotion dur="3s" repeatCount="indefinite" path="M0,0 A80,80 0 1,1 0,-0.1 Z" />
<animate attributeName="fill" values="var(--glow-color-1);var(--glow-color-2);var(--glow-color-3);var(--glow-color-1)" dur="3s" repeatCount="indefinite"/>
</circle>
<circle cx="100" cy="20" r="5" fill="#FFF">
<animateMotion dur="4s" repeatCount="indefinite" path="M0,0 A70,70 0 1,0 0,-0.1 Z" />
<animate attributeName="fill" values="var(--glow-color-3);var(--glow-color-1);var(--glow-color-2);var(--glow-color-3)" dur="4s" repeatCount="indefinite"/>
</circle>
</g>
</svg>
</div>
<p class="weather-description-hyperbole">多重宇宙熵增警报!现实结构完整性告急!</p>
</main>
<!-- 3.4 附加信息 - 新拟态按钮 + 动态条 -->
<section class="additional-info-matrix">
<div class="info-pod">
<span class="info-label">奇点风暴</span>
<div class="dynamic-bar wind-bar"><span style="width: 95%;"></span></div>
<span class="info-value wind-value">超越光速 Σ(c)</span>
</div>
<div class="info-pod">
<span class="info-label">虚空湿度</span>
<div class="dynamic-bar humidity-bar"><span style="width: 100%;"></span></div>
<span class="info-value humidity-value">不可測 %</span>
</div>
<div class="info-pod full-width"> <!-- Spans full width -->
<span class="info-label">体感悖论</span>
<span class="info-value feels-like-value">因果律紊乱</span>
<span class="info-icon reality-glitch">🌀</span>
</div>
</section>
<!-- 3.5 未来几小时预报 - 滚动/翻转的小型毛玻璃卡片 -->
<footer class="forecast-continuum">
<!-- JS will populate this -->
</footer>
<!-- 3.6 底部装饰性“能量核心” -->
<div class="energy-core-pulsar"></div>
</div>
<!-- 4. 周围漂浮的装饰性几何体/粒子 - 增加沉浸感 -->
<div class="floating-particle particle-1"></div>
<div class="floating-particle particle-2"></div>
<div class="floating-particle particle-3"></div>
<div class="floating-particle particle-4"></div>
<div class="floating-particle particle-5"></div>
</div>
<!-- 5. 行为艺术家的“满意度”计量条 (纯粹为了好玩) -->
<div class="artist-satisfaction-meter">
<div class="meter-bar">
<span>视觉冲击力评估中...</span>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const weatherData = {
city: "湮灭之都 XYLOS",
timePrefix: "LOG_TIME::",
timeSuffix: "_STATUS::CRITICAL",
temperature: "NaN",
description: "多重宇宙熵增警报!现实结构完整性告急!",
windSpeedValue: "超越光速 Σ(c)",
windSpeedBar: 95, // percentage
humidityValue: "不可測 %",
humidityBar: 100, // percentage
feelsLike: "因果律紊乱",
forecast: [
{ time: "Ω-1", temp: "🔥", icon: "☣️" },
{ time: "α+∞", temp: "❄️", icon: "🌌" },
{ time: "UNDEFINED", temp: "⚡", icon: "💀" },
]
};
// Update time dynamically
const cyberTimeEl = document.querySelector('.cyber-time');
function updateTime() {
const now = new Date();
const timeString = now.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3, hour12: false }).replace(/:/g, '::');
cyberTimeEl.textContent = `${weatherData.timePrefix}${timeString}${weatherData.timeSuffix}`;
}
setInterval(updateTime, 50); // Update very frequently for chaotic effect
updateTime(); // Initial call
// Update other static data
const cityNameEl = document.querySelector('.city-name');
cityNameEl.querySelector('span').textContent = weatherData.city;
cityNameEl.setAttribute('data-text', weatherData.city);
document.querySelector('.temperature-supernova .temp-value').textContent = weatherData.temperature;
document.querySelector('.weather-description-hyperbole').textContent = weatherData.description;
document.querySelector('.wind-value').textContent = weatherData.windSpeedValue;
document.querySelector('.wind-bar span').style.width = weatherData.windSpeedBar + '%';
document.querySelector('.humidity-value').textContent = weatherData.humidityValue;
document.querySelector('.humidity-bar span').style.width = weatherData.humidityBar + '%';
document.querySelector('.feels-like-value').textContent = weatherData.feelsLike;
// Future forecast
const forecastContainer = document.querySelector('.forecast-continuum');
forecastContainer.innerHTML = '';
weatherData.forecast.forEach((f, index) => {
const capsule = document.createElement('div');
capsule.classList.add('forecast-capsule');
capsule.style.setProperty('--i', index);
capsule.innerHTML = `
<span class="time-slice">${f.time}</span>
<span class="temp-future">${f.temp}</span>
<span class="icon-future">${f.icon}</span>
`;
forecastContainer.appendChild(capsule);
});
// Satisfaction meter animation
setTimeout(() => {
const meterBar = document.querySelector('.artist-satisfaction-meter .meter-bar');
if (meterBar) {
meterBar.style.width = '100%';
const meterTextSpan = meterBar.querySelector('span');
// Wait for width transition to almost finish before changing text
// CSS transition is 5s with 1s delay. Total 6s.
setTimeout(() => {
meterTextSpan.style.opacity = 0; // Fade out old text
setTimeout(() => {
meterTextSpan.textContent = "!!视 觉 核 爆!!";
meterTextSpan.style.opacity = 1; // Fade in new text
}, 300); // short delay for fade effect
}, 5500); // Just before the bar fully extends
}
}, 500); // Slightly shorter delay to start the process
// Mouse Parallax effect for the console frame
const consoleFrame = document.querySelector('.neumorphic-console-frame');
if (consoleFrame) {
const body = document.body; // Cache body
body.addEventListener('mousemove', (e) => {
const xAxis = (window.innerWidth / 2 - e.pageX) / 60; // Reduced sensitivity
const yAxis = (window.innerHeight / 2 - e.pageY) / 80; // Reduced sensitivity
// Combine with existing float animation's base transform
const baseTransform = getComputedStyle(consoleFrame).transform;
// This is tricky to combine with CSS animation transforms.
// A simpler approach is to just override the rotate part.
// For full combination, one would need to parse matrix or use JS for all transforms.
// For now, just adding the mouse-based rotation.
// The float animation has translateY which we need to preserve.
// Let's make the mouse effect more subtle and additive if possible.
// Currently, frameFloat's rotateX/Y will conflict. We'll prioritize mouse.
consoleFrame.style.transition = 'transform 0.1s linear'; // faster transition for mouse
consoleFrame.style.transform = `rotateY(${5 + xAxis}deg) rotateX(${3 - yAxis}deg) translateY(calc(${-yAxis / 2}px - 5px)) scale(${1 + Math.abs(xAxis + yAxis) / 500})`;
});
body.addEventListener('mouseleave', () => {
// Reset to a neutral state or let CSS animation take over again
consoleFrame.style.transition = 'transform 0.5s ease-out';
consoleFrame.style.transform = ''; // Reverts to CSS defined transform
});
}
});
</script>
</body>
</html>