@@ -20,9 +20,15 @@ const props = defineProps<{
2020const { current, isFavourite, toggleFavourite } = useLocation ();
2121const starred = computed (() => isFavourite (current .value ));
2222
23- const { formatTemp, formatPercent } = useUnits ();
23+ const { temp, formatTemp, formatPercent } = useUnits ();
2424
25- const currentTemp = computed (() => props .raw .current .temperature_2m ?? null );
25+ const tempUnitLetter = computed (() => (temp .value === " f" ? " F" : " C" ));
26+
27+ const currentTemp = computed (() => {
28+ const t = props .raw .current .temperature_2m ;
29+ if (t == null ) return null ;
30+ return temp .value === " f" ? (t * 9 ) / 5 + 32 : t ;
31+ });
2632const currentCode = computed (() => Number (props .raw .current .weather_code ?? 0 ));
2733const currentIsDay = computed (() => (props .raw .current .is_day ?? 1 ) === 1 );
2834const todayHigh = computed (() => props .daily .series .temperature_2m_max [0 ]?.value ?? null );
@@ -54,52 +60,111 @@ const dayLength = computed(() => {
5460 const m = totalMin % 60 ;
5561 return ` ${h }h ${m .toString ().padStart (2 , " 0" )}m ` ;
5662});
63+
64+ // Decimal portion of the current temperature is rendered smaller so the
65+ // huge serif number reads as a typographic display rather than a flat number.
66+ const tempWhole = computed (() => {
67+ const t = currentTemp .value ;
68+ if (t == null || ! Number .isFinite (t )) return " —" ;
69+ return ` ${Math .round (t )} ` ;
70+ });
5771 </script >
5872
5973<template >
60- <section class =" rounded-2xl bg-slate-900/60 p-6 ring-1 ring-slate-800 sm:p-8" >
61- <div class =" flex flex-col gap-6 sm:flex-row sm:items-center sm:justify-between" >
62- <div class =" flex items-center gap-5" >
63- <WeatherIcon :code =" currentCode " :is-day =" currentIsDay " size="4.5rem " />
64- <div >
65- <div class =" flex items-center gap-1.5" >
66- <div class =" text-sm tracking-wider text-slate-400 uppercase" >{{ locationName }}</div >
67- <button
68- type =" button"
69- class =" -m-1 rounded-md p-1 text-base leading-none transition-colors"
70- :class =" starred ? 'text-amber-300 hover:text-amber-200' : 'text-slate-500 hover:text-amber-300'"
71- :title =" starred ? 'Remove from favourites' : 'Save as favourite'"
72- :aria-pressed =" starred"
73- @click =" toggleFavourite(current)"
74- >
75- {{ starred ? "★" : "☆" }}
76- </button >
74+ <section class =" border-ink-700 bg-ink-900/60 border p-4 sm:p-5" >
75+ <!-- Header bar: same eyebrow + hairline-divider pattern as the chart
76+ card below, so the two stack as a single typographic system. -->
77+ <div class =" border-ink-700 mb-3 flex items-center justify-between gap-3 border-b pb-3" >
78+ <h2 class =" eyebrow" >Current conditions</h2 >
79+ <span class =" text-paper-400 font-mono text-[10px] tracking-[0.12em] whitespace-nowrap tabular-nums" >
80+ <span class =" text-sodium-300" >●</span >
81+ {{ lastUpdated.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) }}
82+ <span class =" hidden sm:inline" >
83+ <span class =" text-paper-500" >·</span >
84+ {{ lastUpdated.toLocaleDateString([], { day: "2-digit", month: "short" }) }}
85+ </span >
86+ </span >
87+ </div >
88+
89+ <!-- Location ---------------------------------------------------- - -->
90+ <div class =" flex items-center gap-1.5" >
91+ <span class =" text-paper-100 text-sm font-medium tracking-wide" >{{ locationName }}</span >
92+ <button
93+ type =" button"
94+ class =" -m-1 p-1 text-sm leading-none transition-colors"
95+ :class =" starred ? 'text-sodium-300 hover:text-sodium-200' : 'text-paper-400 hover:text-sodium-300'"
96+ :title =" starred ? 'Remove from favourites' : 'Save as favourite'"
97+ :aria-pressed =" starred"
98+ @click =" toggleFavourite(current)"
99+ >
100+ {{ starred ? "★" : "☆" }}
101+ </button >
102+ </div >
103+
104+ <!-- Reading + readouts ------------------------------------------ -->
105+ <div class =" mt-2 grid gap-4 sm:mt-3 sm:grid-cols-[1fr_auto] sm:items-center sm:gap-8" >
106+ <div class =" flex items-center gap-4 sm:gap-5" >
107+ <div class =" relative shrink-0" >
108+ <!-- A halo behind the weather icon so it reads as a "lit" panel
109+ element. -->
110+ <div class =" bg-sodium-300/10 absolute inset-0 -m-2 rounded-full blur-2xl" aria-hidden =" true" />
111+ <WeatherIcon :code =" currentCode " :is-day =" currentIsDay " size="2.75rem " class="relative" />
112+ </div >
113+
114+ <div class =" min-w-0" >
115+ <div class =" flex items-baseline gap-1" >
116+ <span class =" sodium-glow text-paper-50 font-mono text-5xl leading-none font-light tabular-nums sm:text-6xl" >
117+ {{ tempWhole }}
118+ </span >
119+ <span class =" text-sodium-300 font-mono text-xl leading-none font-light tabular-nums sm:text-2xl" > °{{ tempUnitLetter }} </span >
77120 </div >
78- <div class =" mt-0.5 flex items-baseline gap-3" >
79- <div class =" text-5xl font-semibold tabular-nums sm:text-6xl" >{{ formatTemp(currentTemp, 0) }}</div >
80- <div class =" hidden text-slate-300 sm:block" >{{ weatherLabel(currentCode) }}</div >
121+ <div class =" text-paper-200 mt-1.5 font-mono text-xs tracking-wide" >
122+ {{ weatherLabel(currentCode) }}
81123 </div >
82- <div class =" mt-1 text-sm text-slate-300 sm:hidden" >{{ weatherLabel(currentCode) }}</div >
83124 </div >
84125 </div >
85126
86- <div class =" flex flex-col items-start gap-2 sm:items-end" >
127+ <!-- Two instrument modules: temperature/precip and the solar block.
128+ They sit side by side when the card is wide enough and stack
129+ otherwise. -->
130+ <div class =" flex flex-col gap-2.5 sm:items-end" >
87131 <ConfidenceBadge :value =" todayConfidence " />
88- <div class =" text-sm text-slate-300 tabular-nums" >
89- <span class =" text-rose-300" >{{ formatTemp(todayHigh, 0) }}</span >
90- <span class =" mx-2 text-slate-500" >·</span >
91- <span class =" text-sky-300" >{{ formatTemp(todayLow, 0) }}</span >
92- <template v-if =" todayPrecipProb != null && todayPrecipProb > 0 " >
93- <span class =" mx-2 text-slate-500" >·</span >
94- <span >💧 {{ formatPercent(todayPrecipProb) }}</span >
95- </template >
96- </div >
97- <div v-if =" sunrise || sunset" class =" flex items-center gap-3 text-xs text-slate-400 tabular-nums" >
98- <span title =" Sunrise" ><span class =" text-amber-300" >↑</span > {{ formatClock(sunrise) }}</span >
99- <span title =" Sunset" ><span class =" text-orange-400" >↓</span > {{ formatClock(sunset) }}</span >
100- <span v-if =" dayLength" class =" text-slate-500" title =" Day length" >· {{ dayLength }}</span >
132+
133+ <div class =" flex flex-col gap-2.5 sm:flex-row sm:gap-3" >
134+ <!-- High / Low / Precip -->
135+ <div class =" border-ink-700 bg-ink-950/60 grid grid-cols-3 gap-x-4 gap-y-1 border px-3 py-2 font-mono tabular-nums" >
136+ <div class =" flex flex-col gap-0.5" >
137+ <span class =" text-paper-400 text-[10px] tracking-wide" >High</span >
138+ <span class =" text-heat-300 text-sm" >{{ formatTemp(todayHigh, 0) }}</span >
139+ </div >
140+ <div class =" flex flex-col gap-0.5" >
141+ <span class =" text-paper-400 text-[10px] tracking-wide" >Low</span >
142+ <span class =" text-cold-300 text-sm" >{{ formatTemp(todayLow, 0) }}</span >
143+ </div >
144+ <div class =" flex flex-col gap-0.5" >
145+ <span class =" text-paper-400 text-[10px] tracking-wide" >Precip</span >
146+ <span class =" text-sm" :class =" todayPrecipProb != null && todayPrecipProb > 0 ? 'text-rain-300' : 'text-paper-400'" >
147+ {{ todayPrecipProb != null && todayPrecipProb > 0 ? formatPercent(todayPrecipProb) : "—" }}
148+ </span >
149+ </div >
150+ </div >
151+
152+ <!-- Sunrise / Sunset / Total sun -->
153+ <div v-if =" sunrise || sunset" class =" border-ink-700 bg-ink-950/60 grid grid-cols-3 gap-x-4 gap-y-1 border px-3 py-2 font-mono tabular-nums" >
154+ <div class =" flex flex-col gap-0.5" >
155+ <span class =" text-paper-400 text-[10px] tracking-wide" >Sunrise</span >
156+ <span class =" text-sodium-300 text-sm" >{{ formatClock(sunrise) }}</span >
157+ </div >
158+ <div class =" flex flex-col gap-0.5" >
159+ <span class =" text-paper-400 text-[10px] tracking-wide" >Sunset</span >
160+ <span class =" text-heat-300 text-sm" >{{ formatClock(sunset) }}</span >
161+ </div >
162+ <div class =" flex flex-col gap-0.5" >
163+ <span class =" text-paper-400 text-[10px] tracking-wide" >Total sun</span >
164+ <span class =" text-paper-200 text-sm" >{{ dayLength ?? "—" }}</span >
165+ </div >
166+ </div >
101167 </div >
102- <div class =" text-xs text-slate-500" :title =" lastUpdated.toString()" >Updated {{ lastUpdated.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) }}</div >
103168 </div >
104169 </div >
105170 </section >
0 commit comments