2828 --border-dim : rgba (151 , 174 , 196 , 0.18 );
2929 --volcano : # ff4444 ;
3030 --drought : # ff9500 ;
31- --purple : # 9c27b0 ;
31+ --purple : # 6EB6FF ;
3232 --wildfire : # ff6f00 ;
3333 --font-display : 'Inter' , sans-serif;
3434 --font-body : 'Inter' , sans-serif;
4040
4141 body {
4242 font-family : 'Inter' , sans-serif;
43- background : var ( --bgcolor ) ;
43+ background : transparent ;
4444 color : var (--text );
4545 overflow-x : hidden;
4646 overflow-y : auto;
5353 margin : 0 auto;
5454 }
5555
56- .overview-header {
56+ /* ---------- Top bar ---------- */
57+ .top-bar {
58+ position : fixed;
59+ top : 0 ; left : 0 ; right : 0 ;
60+ z-index : 100 ;
61+ height : 74px ;
62+ padding : 0 26px 0 50px ;
5763 display : flex;
64+ align-items : center;
5865 justify-content : space-between;
66+ background : rgb (12 , 17 , 22 );
67+ }
68+ .brand {
69+ font-family : 'Cormorant Garamond' , serif;
70+ font-size : 16px ;
71+ font-weight : 300 ;
72+ color : var (--text );
73+ white-space : nowrap;
74+ flex-shrink : 0 ;
75+ }
76+ .brand a { color : inherit; text-decoration : none; }
77+ .brand-earth { font-style : italic; }
78+ .brand-dim { color : rgba (255 , 255 , 255 , 0.6 ); font-style : italic; }
79+
80+ .breadcrumb {
81+ display : flex;
5982 align-items : center;
60- margin-bottom : 40px ;
83+ justify-content : center;
84+ font-family : 'Inter' , sans-serif;
85+ font-size : 11px ;
86+ font-style : italic;
87+ font-weight : 300 ;
88+ letter-spacing : 0.2em ;
89+ text-transform : uppercase;
90+ color : rgba (255 , 255 , 255 , 0.6 );
91+ white-space : nowrap;
6192 }
93+ .breadcrumb a { color : rgba (255 , 255 , 255 , 0.6 ); text-decoration : none; }
94+ .breadcrumb a : hover { color : rgba (255 , 255 , 255 , 0.9 ); }
95+ .breadcrumb .sep { margin : 0 10px ; opacity : 0.5 ; }
6296
63- .back-button {
64- background : var (--exhibit );
65- border : 1px solid var (--border-dim );
66- color : var (--text-mid );
67- padding : 12px 24px ;
68- border-radius : 8px ;
69- font-family : var (--font-body );
70- font-size : 0.9rem ;
97+ .pill-btn {
98+ display : inline-flex;
99+ align-items : center;
100+ gap : 10px ;
101+ padding : 9px 28px ;
102+ border : 1px solid rgba (255 , 255 , 255 , 0.5 );
103+ border-radius : 999px ;
104+ color : var (--text );
105+ background : rgba (12 , 17 , 22 , 0.2 );
106+ font-family : 'Inter' , sans-serif;
107+ font-size : 16px ;
108+ font-weight : 400 ;
71109 cursor : pointer;
72- transition : all 0.3s ;
73110 text-decoration : none;
74- display : inline-block;
111+ transition : background 0.3s ease, border-color 0.3s ease;
112+ }
113+ .pill-btn : hover {
114+ background : rgba (255 , 255 , 255 , 0.1 );
115+ border-color : rgba (255 , 255 , 255 , 0.8 );
75116 }
117+ .pill-btn .arrow { transition : transform .3s ease; }
118+ .pill-btn : hover .arrow { transform : translateX (3px ); }
76119
77- .back-button : hover {
78- background : var (--bgcolor );
79- color : var (--text-bright );
120+ .pie-legend-html {
121+ display : grid;
122+ grid-template-columns : repeat (3 , 1fr );
123+ width : 100% ;
124+ padding : 4px 16px 12px ;
125+ gap : 4px 20px ;
80126 }
81127
82- .timeline-link {
83- background : transparent;
84- border : 1px solid var (--bluesky );
85- color : var (--bluesky );
86- padding : 12px 24px ;
87- border-radius : 8px ;
88- font-family : var (--font-body );
89- font-size : 0.9rem ;
128+ .pie-legend-item {
129+ display : flex;
130+ align-items : center;
131+ gap : 8px ;
132+ font-size : 10px ;
133+ letter-spacing : 0.08em ;
134+ text-transform : uppercase;
135+ color : var (--text-mid );
136+ padding : 6px 0 ;
137+ border-bottom : 1px solid rgba (151 , 174 , 196 , 0.10 );
90138 cursor : pointer;
91- transition : all 0.3s ;
92- text-decoration : none;
93- display : inline-block;
94139 }
95140
96- .timeline-link : hover {
97- background : var (--bluesky );
98- color : var (--bgcolor );
141+ .pie-legend-swatch {
142+ width : 8px ;
143+ height : 8px ;
144+ border-radius : 2px ;
145+ flex-shrink : 0 ;
146+ }
147+
148+ .pie-legend-label { flex : 1 ; }
149+
150+ .pie-legend-count {
151+ margin-left : auto;
152+ color : var (--text );
153+ font-family : 'Cormorant Garamond' , serif;
154+ font-style : italic;
155+ font-size : 16px ;
156+ font-weight : 400 ;
99157 }
100158
101159 .hidden {
102160 display : none !important ;
103161 }
162+
163+ # overviewStarfield {
164+ position : fixed;
165+ inset : 0 ;
166+ z-index : -1 ;
167+ pointer-events : none;
168+ }
104169</ style >
105170</ head >
106171
107172< body >
108- < div class ="overview-container ">
109- < div class ="overview-header ">
110- < a href ="globe.html " class ="back-button "> ← Back to Globe</ a >
111- < a href ="country_timeline.html " class ="timeline-link " id ="timelineLink "> View Timeline →</ a >
112- </ div >
173+
174+ < canvas id ="overviewStarfield "> </ canvas >
175+
176+ < header class ="top-bar ">
177+ < div class ="brand ">
178+ < a href ="curators.html "> < span class ="brand-earth "> Earth</ span > Natural Disaster Museum< span class ="brand-dim "> · est. 2026</ span > </ a >
179+ </ div >
180+ < nav class ="breadcrumb ">
181+ < a href ="globe.html "> The Globe: Earth</ a >
182+ < span class ="sep "> /</ span >
183+ < a id ="timelineLink " href ="country_timeline.html "> < span id ="breadcrumbCountry "> —</ span > Timeline</ a >
184+ < span class ="sep "> /</ span >
185+ < span > Overview</ span >
186+ </ nav >
187+ < a id ="returnTimelineBtn " href ="country_timeline.html " class ="pill-btn ">
188+ < svg width ="16 " height ="16 " viewBox ="0 0 16 16 " fill ="none " xmlns ="http://www.w3.org/2000/svg ">
189+ < path d ="M10 8H2M2 8L6 4M2 8L6 12 " stroke ="currentColor " stroke-width ="1.4 " stroke-linecap ="round " stroke-linejoin ="round "/>
190+ </ svg >
191+ Return to Timeline
192+ </ a >
193+ </ header >
194+
195+ < div class ="overview-container " style ="padding-top: 114px; ">
113196
114197 <!-- Top Section: Name/Text Left, Stats Grid Right -->
115198 < div class ="overview-top-section ">
@@ -153,15 +236,15 @@ <h1 class="overview-country-title" id="overviewCountryName">
153236 < div class ="overview-middle-section ">
154237 < div class ="overview-card overview-card-composition ">
155238 < div class ="overview-card-header ">
156- < div class ="overview-card-series "> SERIES 01 — COMPOSITION</ div >
239+ < div class ="overview-card-series "> SERIES 01 · COMPOSITION</ div >
157240 < h3 > Disaster < em > composition</ em > </ h3 >
158241 </ div >
159242 < div class ="overview-viz " id ="overviewComposition "> </ div >
160243 </ div >
161244
162245 < div class ="overview-card overview-card-evolution ">
163246 < div class ="overview-card-header ">
164- < div class ="overview-card-series "> SERIES 02 — FREQUENCY</ div >
247+ < div class ="overview-card-series "> SERIES 02 · FREQUENCY</ div >
165248 < h3 > Disaster per < em > type & year</ em > </ h3 >
166249 </ div >
167250 < div class ="overview-viz " id ="overviewTypeEvolution "> </ div >
@@ -172,16 +255,16 @@ <h3>Disaster per <em>type & year</em></h3>
172255 < div class ="overview-bottom-section ">
173256 < div class ="overview-card ">
174257 < div class ="overview-card-header ">
175- < div class ="overview-card-series "> SERIES 03 — IMPACT & MORTALITY</ div >
176- < h3 > Total < em > deaths & affected</ em > </ h3 >
258+ < div class ="overview-card-series "> SERIES 03 · IMPACT & MORTALITY</ div >
259+ < h3 > Total < em style =" color: var(--orange); " > deaths & affected</ em > </ h3 >
177260 < span class ="overview-card-peak-label " id ="deathsAffectedPeakLabel "> PEAK YEAR — 2011</ span >
178261 </ div >
179262 < div class ="overview-viz " id ="overviewDeathsAffected "> </ div >
180263 </ div >
181264
182265 < div class ="overview-card ">
183266 < div class ="overview-card-header ">
184- < div class ="overview-card-series "> SERIES 04 — COST (USD Millions)</ div >
267+ < div class ="overview-card-series "> SERIES 04 · COST (USD Millions)</ div >
185268 < h3 > Total < em > damage</ em > </ h3 >
186269 < span class ="overview-card-peak-label " id ="damagePeakLabel "> PEAK YEAR — 2011</ span >
187270 </ div >
@@ -199,11 +282,15 @@ <h3>Total <em>damage</em></h3>
199282 const countryISO = urlParams . get ( 'iso' ) ;
200283
201284 if ( countryISO && typeof Scene5 !== 'undefined' ) {
202- // Update timeline link
285+ // Update timeline links with ISO
203286 const timelineLink = document . getElementById ( 'timelineLink' ) ;
204287 if ( timelineLink ) {
205288 timelineLink . href = `country_timeline.html?iso=${ countryISO } ` ;
206289 }
290+ const returnTimelineBtn = document . getElementById ( 'returnTimelineBtn' ) ;
291+ if ( returnTimelineBtn ) {
292+ returnTimelineBtn . href = `country_timeline.html?iso=${ countryISO } ` ;
293+ }
207294
208295 // Wait for data to load, then render overview
209296 async function loadAndRender ( ) {
@@ -239,5 +326,98 @@ <h1 style="color: var(--text-mid);">No country selected</h1>
239326 ` ;
240327 }
241328 </ script >
329+
330+ <!-- Starfield background -->
331+ < script >
332+ ( function ( ) {
333+ const canvas = document . getElementById ( 'overviewStarfield' ) ;
334+ const ctx = canvas . getContext ( '2d' ) ;
335+
336+ let stars = [ ] , bgGrad , vigGrad , w , h , animId ;
337+
338+ function rng ( seed ) {
339+ let s = seed ;
340+ return function ( ) {
341+ s = ( s ^ ( s << 13 ) ) >>> 0 ;
342+ s = ( s ^ ( s >>> 17 ) ) >>> 0 ;
343+ s = ( s ^ ( s << 5 ) ) >>> 0 ;
344+ return s / 0xffffffff ;
345+ } ;
346+ }
347+
348+ function init ( ) {
349+ const dpr = window . devicePixelRatio || 1 ;
350+ w = window . innerWidth ;
351+ h = window . innerHeight ;
352+ canvas . width = w * dpr ;
353+ canvas . height = h * dpr ;
354+ canvas . style . width = w + 'px' ;
355+ canvas . style . height = h + 'px' ;
356+ ctx . setTransform ( dpr , 0 , 0 , dpr , 0 , 0 ) ;
357+
358+ bgGrad = ctx . createRadialGradient ( w * 0.4 , h * 0.5 , 0 , w * 0.5 , h * 0.5 , Math . max ( w , h ) * 0.85 ) ;
359+ bgGrad . addColorStop ( 0 , '#0f1e30' ) ;
360+ bgGrad . addColorStop ( 0.2 , '#0b1622' ) ;
361+ bgGrad . addColorStop ( 1 , '#060a0f' ) ;
362+
363+ vigGrad = ctx . createRadialGradient ( w / 2 , h / 2 , h * 0.2 , w / 2 , h / 2 , h * 0.9 ) ;
364+ vigGrad . addColorStop ( 0 , 'rgba(12,17,22,0)' ) ;
365+ vigGrad . addColorStop ( 1 , 'rgba(12,17,22,0.55)' ) ;
366+
367+ const rand = rng ( 42 ) ;
368+ const count = Math . round ( w * h / 1400 ) ;
369+ stars = [ ] ;
370+ for ( let i = 0 ; i < count ; i ++ ) {
371+ stars . push ( {
372+ x : rand ( ) * w ,
373+ y : rand ( ) * h ,
374+ size : rand ( ) * 1.4 + 0.3 ,
375+ baseAlpha : rand ( ) * 0.55 + 0.15 ,
376+ twinklePhase : rand ( ) * Math . PI * 2 ,
377+ twinkleSpeed : rand ( ) * 0.003 + 0.001 , /* 2 – 6 s period */
378+ twinkleAmp : rand ( ) * 0.35 + 0.1 ,
379+ driftPhaseX : rand ( ) * Math . PI * 2 ,
380+ driftPhaseY : rand ( ) * Math . PI * 2 ,
381+ driftSpeedX : rand ( ) * 0.0001 + 0.00003 , /* 60 – 200 s period */
382+ driftSpeedY : rand ( ) * 0.0001 + 0.00003 ,
383+ driftAmpX : rand ( ) * 1.5 + 0.5 , /* ± 0.5 – 2 px */
384+ driftAmpY : rand ( ) * 1.5 + 0.5 ,
385+ } ) ;
386+ }
387+ }
388+
389+ function animate ( ts ) {
390+ ctx . fillStyle = bgGrad ;
391+ ctx . fillRect ( 0 , 0 , w , h ) ;
392+
393+ for ( const s of stars ) {
394+ const alpha = Math . max ( 0.05 , Math . min ( 0.9 ,
395+ s . baseAlpha + Math . sin ( ts * s . twinkleSpeed + s . twinklePhase ) * s . twinkleAmp
396+ ) ) ;
397+ const x = s . x + Math . sin ( ts * s . driftSpeedX + s . driftPhaseX ) * s . driftAmpX ;
398+ const y = s . y + Math . sin ( ts * s . driftSpeedY + s . driftPhaseY ) * s . driftAmpY ;
399+
400+ ctx . beginPath ( ) ;
401+ ctx . arc ( x , y , s . size , 0 , Math . PI * 2 ) ;
402+ ctx . fillStyle = `rgba(255,255,255,${ alpha . toFixed ( 2 ) } )` ;
403+ ctx . fill ( ) ;
404+ }
405+
406+ ctx . fillStyle = vigGrad ;
407+ ctx . fillRect ( 0 , 0 , w , h ) ;
408+
409+ animId = requestAnimationFrame ( animate ) ;
410+ }
411+
412+ init ( ) ;
413+ animId = requestAnimationFrame ( animate ) ;
414+
415+ window . addEventListener ( 'resize' , ( ) => {
416+ cancelAnimationFrame ( animId ) ;
417+ init ( ) ;
418+ animId = requestAnimationFrame ( animate ) ;
419+ } ) ;
420+ } ) ( ) ;
421+ </ script >
242422</ body >
243423</ html >
0 commit comments