feat: add temperature unit preference

This commit is contained in:
zv
2026-06-13 21:05:01 +02:00
parent 66ead03f49
commit cb113714f9
24 changed files with 150 additions and 51 deletions

View File

@@ -5,6 +5,8 @@ import { Card } from "@/components/ui/card";
import { CHART_COLORS } from "@/lib/chart-theme";
import { useI18n } from "@/lib/i18n";
import { formatForecastRainfall, formatForecastTemperature } from "@/lib/forecast-utils";
import { useWeatherStore } from "@/lib/store";
import { convertTemperature, formatTemperatureValue, getTemperatureUnitLabel } from "@/lib/weather-utils";
import type { HourlyForecast } from "@/types/forecast";
const INITIAL_CHART_DIMENSION = { width: 1, height: 1 };
@@ -15,13 +17,15 @@ function formatHour(value: string) {
export function DayForecastCharts({ hours }: { hours: HourlyForecast[] }) {
const { language, t } = useI18n();
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const rows = hours.map((hour) => ({
time: formatHour(hour.time),
temperature: hour.temperature,
feelsLike: hour.feelsLike,
temperature: hour.temperature === null ? null : convertTemperature(hour.temperature, temperatureUnit),
feelsLike: hour.feelsLike === null ? null : convertTemperature(hour.feelsLike, temperatureUnit),
precipitation: hour.precipitation,
precipitationProbability: hour.precipitationProbability,
}));
const temperatureUnitLabel = getTemperatureUnitLabel(temperatureUnit);
return (
<div className="grid gap-3 lg:grid-cols-2">
@@ -33,10 +37,14 @@ export function DayForecastCharts({ hours }: { hours: HourlyForecast[] }) {
<ComposedChart data={rows} margin={{ left: -20, right: 8, top: 8 }}>
<CartesianGrid stroke={CHART_COLORS.grid} strokeDasharray="4 4" vertical={false} />
<XAxis dataKey="time" axisLine={false} tickLine={false} interval={3} tick={{ fill: "currentColor", fontSize: 11 }} />
<YAxis axisLine={false} tickLine={false} tick={{ fill: "currentColor", fontSize: 11 }} unit="°" />
<YAxis axisLine={false} tickLine={false} tick={{ fill: "currentColor", fontSize: 11 }} unit={temperatureUnitLabel} />
<Tooltip
contentStyle={{ borderRadius: 14, border: `1px solid ${CHART_COLORS.tooltipBorder}`, background: CHART_COLORS.tooltipBackground, color: CHART_COLORS.tooltipText }}
formatter={(value) => [formatForecastTemperature(typeof value === "number" ? value : null, language)]}
formatter={(value) => [
typeof value === "number"
? formatTemperatureValue(value, language, temperatureUnit)
: formatForecastTemperature(null, language, temperatureUnit),
]}
/>
<Legend wrapperStyle={{ fontSize: "0.72rem" }} />
<Line type="monotone" dataKey="temperature" name={t("forecast.temperature")} stroke={CHART_COLORS.temperature} strokeWidth={3} dot={false} connectNulls />

View File

@@ -20,17 +20,18 @@ export function WeatherBriefCard({ latitude, longitude, locationName }: { latitu
const { data: warnings = [] } = useWarnings();
const selectedStationId = useWeatherStore((state) => state.selectedStationId);
const selectedLocation = useWeatherStore((state) => state.selectedLocation);
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
const province = getProvinceForSelection(selectedLocation?.province, selectedStationId ?? DEFAULT_STATION_ID);
const brief = useMemo(() => {
if (!forecast) return null;
return buildWeatherBrief({ forecast, warnings, province, countyTeryt: selectedLocation?.countyTeryt, locationName, language, windSpeedUnit });
}, [forecast, language, locationName, province, selectedLocation?.countyTeryt, warnings, windSpeedUnit]);
return buildWeatherBrief({ forecast, warnings, province, countyTeryt: selectedLocation?.countyTeryt, locationName, language, temperatureUnit, windSpeedUnit });
}, [forecast, language, locationName, province, selectedLocation?.countyTeryt, temperatureUnit, warnings, windSpeedUnit]);
const tomorrowBrief = useMemo(() => {
if (!forecast) return null;
return buildTomorrowWeatherBrief({ forecast, warnings, province, countyTeryt: selectedLocation?.countyTeryt, locationName, language, windSpeedUnit });
}, [forecast, language, locationName, province, selectedLocation?.countyTeryt, warnings, windSpeedUnit]);
return buildTomorrowWeatherBrief({ forecast, warnings, province, countyTeryt: selectedLocation?.countyTeryt, locationName, language, temperatureUnit, windSpeedUnit });
}, [forecast, language, locationName, province, selectedLocation?.countyTeryt, temperatureUnit, warnings, windSpeedUnit]);
if (!Number.isFinite(latitude) || !Number.isFinite(longitude) || isPending) {
return <LoadingSkeleton className="h-48" />;

View File

@@ -54,6 +54,7 @@ export function DayForecastModal({
onClose: () => void;
}) {
const { language, locale, t } = useI18n();
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
const closeButtonRef = useRef<HTMLButtonElement>(null);
const portalRoot = typeof document === "undefined" ? null : document.body;
@@ -131,8 +132,8 @@ export function DayForecastModal({
<p className="text-sm text-muted">{getForecastCondition(day.weatherCode, language)}</p>
<div className="mt-2 flex items-end gap-4">
<ForecastIcon code={day.weatherCode} className="mb-2 size-14 text-accent" />
<p className="text-6xl font-semibold tracking-[-0.08em] sm:text-7xl">{formatForecastTemperature(day.temperatureMax, language)}</p>
<p className="mb-2 text-2xl text-muted">{formatForecastTemperature(day.temperatureMin, language)}</p>
<p className="text-6xl font-semibold tracking-[-0.08em] sm:text-7xl">{formatForecastTemperature(day.temperatureMax, language, temperatureUnit)}</p>
<p className="mb-2 text-2xl text-muted">{formatForecastTemperature(day.temperatureMin, language, temperatureUnit)}</p>
</div>
</div>
<div className="grid grid-cols-2 gap-2 sm:min-w-[22rem]">
@@ -156,7 +157,7 @@ export function DayForecastModal({
>
<p className="text-xs font-medium text-muted">{formatHour(hour.time)}</p>
<ForecastIcon code={hour.weatherCode} className="mx-auto my-3 size-6 text-accent" />
<p className="text-lg font-semibold tracking-tight">{formatForecastTemperature(hour.temperature, language)}</p>
<p className="text-lg font-semibold tracking-tight">{formatForecastTemperature(hour.temperature, language, temperatureUnit)}</p>
<p className="mt-2 flex items-center justify-center gap-1 text-[0.66rem] text-accent">
<Droplets className="size-3" />
{hour.precipitationProbability === null ? "—" : `${hour.precipitationProbability}%`}

View File

@@ -60,6 +60,7 @@ function HourlySummaryMetric({ icon: Icon, label, value }: { icon: LucideIcon; l
function HourlyForecastSummary({ hours }: { hours: HourlyForecast[] }) {
const { language, t } = useI18n();
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
const minimumTemperature = getMinimum(hours.map((hour) => hour.temperature));
const maximumTemperature = getMaximum(hours.map((hour) => hour.temperature));
@@ -68,7 +69,7 @@ function HourlyForecastSummary({ hours }: { hours: HourlyForecast[] }) {
const maximumRainfallProbability = getMaximum(hours.map((hour) => hour.precipitationProbability));
const temperatureRange = minimumTemperature === null || maximumTemperature === null
? "—"
: `${formatForecastTemperature(minimumTemperature, language)} / ${formatForecastTemperature(maximumTemperature, language)}`;
: `${formatForecastTemperature(minimumTemperature, language, temperatureUnit)} / ${formatForecastTemperature(maximumTemperature, language, temperatureUnit)}`;
return (
<div className="mt-auto hidden border-t border-border/70 pt-4 lg:block">
@@ -85,6 +86,7 @@ function HourlyForecastSummary({ hours }: { hours: HourlyForecast[] }) {
function DailyForecastRow({ day, index, onSelect }: { day: DailyForecast; index: number; onSelect: (day: DailyForecast) => void }) {
const { language, locale, t } = useI18n();
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const label = formatDay(day.date, locale, t("forecast.today"), index);
return (
<motion.li
@@ -106,7 +108,7 @@ function DailyForecastRow({ day, index, onSelect }: { day: DailyForecast; index:
<span className="truncate text-xs text-muted">{getForecastCondition(day.weatherCode, language)} · {formatForecastRainfall(day.precipitation, language)}</span>
</div>
<span className="hidden items-center gap-1 text-xs text-accent sm:flex"><Droplets className="size-3" />{day.precipitationProbability === null ? "—" : `${day.precipitationProbability}%`}</span>
<p className="whitespace-nowrap text-sm"><strong>{formatForecastTemperature(day.temperatureMax, language)}</strong><span className="ml-2 text-muted">{formatForecastTemperature(day.temperatureMin, language)}</span></p>
<p className="whitespace-nowrap text-sm"><strong>{formatForecastTemperature(day.temperatureMax, language, temperatureUnit)}</strong><span className="ml-2 text-muted">{formatForecastTemperature(day.temperatureMin, language, temperatureUnit)}</span></p>
<ChevronRight className="hidden size-4 text-muted sm:block" />
</motion.button>
</motion.li>
@@ -115,6 +117,7 @@ function DailyForecastRow({ day, index, onSelect }: { day: DailyForecast; index:
export function ForecastPanel({ latitude, longitude, locationName }: { latitude?: number; longitude?: number; locationName: string }) {
const { language, t } = useI18n();
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
const { data: forecast, isPending, isError, refetch } = useForecast(latitude, longitude);
const [selectedDay, setSelectedDay] = useState<DailyForecast | null>(null);
@@ -161,12 +164,12 @@ export function ForecastPanel({ latitude, longitude, locationName }: { latitude?
>
<p className="text-xs font-medium text-muted">{formatHour(hour.time)}</p>
<ForecastIcon code={hour.weatherCode} className="mx-auto my-3 size-6 text-accent" />
<p className="text-lg font-semibold tracking-tight">{formatForecastTemperature(hour.temperature, language)}</p>
<p className="text-lg font-semibold tracking-tight">{formatForecastTemperature(hour.temperature, language, temperatureUnit)}</p>
<p className="mt-2 flex items-center justify-center gap-1 text-[0.66rem] text-accent"><Droplets className="size-3" />{hour.precipitationProbability === null ? "—" : `${hour.precipitationProbability}%`}</p>
<div className="mt-3 hidden space-y-1.5 border-t border-border/65 pt-3 text-[0.66rem] text-muted lg:block">
<p className="flex items-center justify-center gap-1" title={t("forecast.apparentTemperature")}>
<ThermometerSun className="size-3 text-accent" />
{formatForecastTemperature(hour.feelsLike, language)}
{formatForecastTemperature(hour.feelsLike, language, temperatureUnit)}
</p>
<p className="flex items-center justify-center gap-1" title={t("weather.wind")}>
<Wind className="size-3 text-accent" />

View File

@@ -6,9 +6,11 @@ import type { HydroStation } from "@/types/imgw";
import { formatDateTime, formatFlow, formatTemperature, formatWaterLevel } from "@/lib/weather-utils";
import { Card } from "@/components/ui/card";
import { useI18n } from "@/lib/i18n";
import { useWeatherStore } from "@/lib/store";
export function HydroStationCard({ station, index = 0 }: { station: HydroStation; index?: number }) {
const { language, t } = useI18n();
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
return (
<motion.article initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: Math.min(index * 0.02, 0.3), duration: 0.3 }}>
<Card className="h-full p-4 transition duration-300 hover:-translate-y-1 hover:bg-surface-raised/90">
@@ -20,7 +22,7 @@ export function HydroStationCard({ station, index = 0 }: { station: HydroStation
</div>
<div className="mt-5 grid grid-cols-3 gap-2">
<HydroMetric icon={Droplets} label={t("hydro.level")} value={formatWaterLevel(station.waterLevel, language)} />
<HydroMetric icon={Thermometer} label={t("hydro.water")} value={formatTemperature(station.waterTemperature, language)} />
<HydroMetric icon={Thermometer} label={t("hydro.water")} value={formatTemperature(station.waterTemperature, language, temperatureUnit)} />
<HydroMetric icon={Activity} label={t("hydro.flow")} value={formatFlow(station.flow, language)} />
</div>
<p className="mt-4 text-[0.7rem] text-muted">{t("hydro.levelMeasurement", { date: formatDateTime(station.waterLevelMeasuredAt, language) })}</p>

View File

@@ -1,7 +1,7 @@
"use client";
import { useEffect, useMemo, useState } from "react";
import { Bell, BellRing, Clock3, Languages, MapPinned, Palette, Settings, Smartphone, Wind } from "lucide-react";
import { Bell, BellRing, Clock3, Languages, MapPinned, Palette, Settings, Smartphone, Thermometer, Wind } from "lucide-react";
import type { LucideIcon } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
@@ -15,9 +15,9 @@ import { locateSynopStations } from "@/lib/location-utils";
import { decodeBase64UrlKey, deletePushSubscription, fetchVapidPublicKey, savePushSubscription, sendTestPushNotification } from "@/lib/notification-api";
import { formatProvinceName, getProvinceForSelection, PROVINCES } from "@/lib/provinces";
import { useWeatherStore } from "@/lib/store";
import { WIND_SPEED_UNITS } from "@/lib/weather-utils";
import { TEMPERATURE_UNITS, WIND_SPEED_UNITS } from "@/lib/weather-utils";
import type { Province } from "@/types/province";
import type { WindSpeedUnit } from "@/types/units";
import type { TemperatureUnit, WindSpeedUnit } from "@/types/units";
type NotificationSupportStatus = "checking" | "unconfigured" | "unsupported" | "needs-install" | "default" | "denied" | "granted";
@@ -108,6 +108,11 @@ const windSpeedUnitKeys: Record<WindSpeedUnit, "settings.units.wind.ms" | "setti
mph: "settings.units.wind.mph",
};
const temperatureUnitKeys: Record<TemperatureUnit, "settings.units.temperature.c" | "settings.units.temperature.f"> = {
c: "settings.units.temperature.c",
f: "settings.units.temperature.f",
};
export function SettingsPage() {
const { language, t } = useI18n();
const [notificationStatus, setNotificationStatus] = useState<NotificationSupportStatus>("checking");
@@ -124,12 +129,14 @@ export function SettingsPage() {
const tomorrowBriefEnabled = useWeatherStore((state) => state.tomorrowBriefNotificationsEnabled);
const provinceMode = useWeatherStore((state) => state.warningNotificationProvinceMode);
const manualProvince = useWeatherStore((state) => state.warningNotificationProvince);
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
const setNotificationsEnabled = useWeatherStore((state) => state.setWarningNotificationsEnabled);
const setMorningBriefEnabled = useWeatherStore((state) => state.setMorningBriefNotificationsEnabled);
const setTomorrowBriefEnabled = useWeatherStore((state) => state.setTomorrowBriefNotificationsEnabled);
const setProvinceMode = useWeatherStore((state) => state.setWarningNotificationProvinceMode);
const setManualProvince = useWeatherStore((state) => state.setWarningNotificationProvince);
const setTemperatureUnit = useWeatherStore((state) => state.setTemperatureUnit);
const setWindSpeedUnit = useWeatherStore((state) => state.setWindSpeedUnit);
const selectedStation = stations?.find((station) => station.id === selectedStationId)
@@ -180,6 +187,7 @@ export function SettingsPage() {
longitude: notificationLongitude,
locationName: notificationLocationName,
countyTeryt: notificationCountyTeryt,
temperatureUnit,
windSpeedUnit,
}).catch(() => undefined);
}
@@ -188,7 +196,7 @@ export function SettingsPage() {
return () => {
cancelled = true;
};
}, [effectiveProvince, language, morningBriefEnabled, notificationCountyTeryt, notificationLatitude, notificationLocationName, notificationLongitude, notificationStatus, notificationsEnabled, tomorrowBriefEnabled, vapidPublicKey, windSpeedUnit]);
}, [effectiveProvince, language, morningBriefEnabled, notificationCountyTeryt, notificationLatitude, notificationLocationName, notificationLongitude, notificationStatus, notificationsEnabled, temperatureUnit, tomorrowBriefEnabled, vapidPublicKey, windSpeedUnit]);
const notificationStatusLabel = useMemo(() => {
switch (notificationStatus) {
@@ -247,6 +255,7 @@ export function SettingsPage() {
longitude: notificationLongitude,
locationName: notificationLocationName,
countyTeryt: notificationCountyTeryt,
temperatureUnit,
windSpeedUnit,
});
setNotificationsEnabled(true);
@@ -310,6 +319,7 @@ export function SettingsPage() {
longitude: notificationLongitude,
locationName: notificationLocationName,
countyTeryt: notificationCountyTeryt,
temperatureUnit,
windSpeedUnit,
});
} catch {
@@ -331,6 +341,7 @@ export function SettingsPage() {
longitude: notificationLongitude,
locationName: notificationLocationName,
countyTeryt: notificationCountyTeryt,
temperatureUnit,
windSpeedUnit,
});
} catch {
@@ -353,6 +364,26 @@ export function SettingsPage() {
<SettingsRow icon={Palette} title={t("settings.theme.title")} description={t("settings.theme.description")}>
<ThemeToggle />
</SettingsRow>
<SettingsRow icon={Thermometer} title={t("settings.units.temperature.title")} description={t("settings.units.temperature.description")}>
<div className="surface-control inline-flex rounded-full p-1" role="radiogroup" aria-label={t("settings.units.temperature.label")}>
{TEMPERATURE_UNITS.map((unit) => (
<button
key={unit}
type="button"
role="radio"
aria-checked={temperatureUnit === unit}
className={`min-w-14 rounded-full border px-3.5 py-1.5 text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent ${
temperatureUnit === unit
? "border-accent/45 bg-accent/10 text-accent shadow-soft"
: "border-transparent text-muted hover:bg-surface-muted/70 hover:text-foreground"
}`}
onClick={() => setTemperatureUnit(unit)}
>
{t(temperatureUnitKeys[unit])}
</button>
))}
</div>
</SettingsRow>
<SettingsRow icon={Wind} title={t("settings.units.wind.title")} description={t("settings.units.wind.description")}>
<div className="surface-control inline-flex rounded-full p-1" role="radiogroup" aria-label={t("settings.units.wind.label")}>
{WIND_SPEED_UNITS.map((unit) => (

View File

@@ -9,16 +9,17 @@ import { useWeatherStore } from "@/lib/store";
export function CurrentConditionsCard({ station }: { station: SynopStation }) {
const { language, t } = useI18n();
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
const feelsLike = calculateFeelsLike(station.temperature, station.humidity, station.windSpeed);
const metrics = [
{ icon: Thermometer, label: t("weather.feelsLike"), value: formatTemperature(feelsLike, language), detail: t("weather.feelsLikeDetail") },
{ icon: Thermometer, label: t("weather.feelsLike"), value: formatTemperature(feelsLike, language, temperatureUnit), detail: t("weather.feelsLikeDetail") },
{ icon: Droplets, label: t("weather.humidity"), value: formatHumidity(station.humidity, language), detail: t("weather.humidityDetail") },
{ icon: Gauge, label: t("weather.pressure"), value: formatPressure(station.pressure, language), detail: t("weather.pressureDetail") },
{ icon: Wind, label: t("weather.windSpeed"), value: formatWind(station.windSpeed, null, language, windSpeedUnit), detail: t("weather.windSpeedDetail") },
{ icon: Navigation, label: t("weather.windDirection"), value: station.windDirection === null ? t("common.noData") : `${station.windDirection}° ${getWindDirection(station.windDirection)}`, detail: t("weather.windDirectionDetail") },
{ icon: Umbrella, label: t("weather.rainfallTotal"), value: formatRainfall(station.rainfall, language), detail: t("weather.rainfallDetail") },
{ icon: CloudSun, label: t("weather.airTemperature"), value: formatTemperature(station.temperature, language), detail: t("weather.temperatureDetail") },
{ icon: CloudSun, label: t("weather.airTemperature"), value: formatTemperature(station.temperature, language, temperatureUnit), detail: t("weather.temperatureDetail") },
];
return (
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">

View File

@@ -14,6 +14,7 @@ export function FeaturedStationsSection({ stations }: { stations: SynopStation[]
const { language, t } = useI18n();
const selectedStationId = useWeatherStore((state) => state.selectedStationId);
const selectStation = useWeatherStore((state) => state.selectStation);
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const featured = featuredNames.flatMap((name) => stations.find((station) => station.name === name) ?? []);
return (
<section className="space-y-3">
@@ -33,7 +34,7 @@ export function FeaturedStationsSection({ stations }: { stations: SynopStation[]
>
<span className="min-w-0">
<span className="block truncate text-xs font-medium text-muted">{station.name}</span>
<span className="mt-1 block text-xl font-semibold tracking-tight">{formatTemperature(station.temperature, language)}</span>
<span className="mt-1 block text-xl font-semibold tracking-tight">{formatTemperature(station.temperature, language, temperatureUnit)}</span>
</span>
<WeatherIcon mood={getWeatherMoodFromData(station)} className="size-6 shrink-0 text-accent" />
</button>

View File

@@ -17,6 +17,7 @@ export function StationCard({ station, index = 0 }: { station: SynopStation; ind
const favorites = useWeatherStore((state) => state.favorites);
const toggleFavorite = useWeatherStore((state) => state.toggleFavorite);
const selectStation = useWeatherStore((state) => state.selectStation);
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
const favorite = favorites.includes(station.id);
const mood = getWeatherMoodFromData(station);
@@ -27,7 +28,7 @@ export function StationCard({ station, index = 0 }: { station: SynopStation; ind
<div className="flex items-start justify-between gap-2">
<Link href={`/station/${station.id}`} onClick={() => selectStation(station.id)} className="min-w-0 flex-1 rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent">
<p className="truncate text-sm font-semibold">{station.name}</p>
<p className="mt-3 text-4xl font-light tracking-[-0.08em]">{formatTemperature(station.temperature, language)}</p>
<p className="mt-3 text-4xl font-light tracking-[-0.08em]">{formatTemperature(station.temperature, language, temperatureUnit)}</p>
</Link>
<div className="flex flex-col items-end gap-2">
<WeatherIcon mood={mood} className="size-9 text-accent" />

View File

@@ -44,6 +44,7 @@ function readDevWeatherEffectOverride(): DevWeatherEffectOverride | null {
export function WeatherHero({ station, currentWeather, currentWeatherLoading = false, locationName, distanceKm }: { station: SynopStation; currentWeather?: ImgwCurrentWeather | null; currentWeatherLoading?: boolean; locationName?: string; distanceKm?: number }) {
const { language, t } = useI18n();
const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
const [devEffectOverride, setDevEffectOverride] = useState<DevWeatherEffectOverride | null>(null);
const displayedLocationName = locationName ?? station.name;
@@ -121,10 +122,10 @@ export function WeatherHero({ station, currentWeather, currentWeatherLoading = f
<div className="mt-8 flex items-end justify-between gap-3 sm:mt-10">
<div>
<div className="text-[5.8rem] font-semibold leading-[0.85] tracking-[-0.1em] sm:text-[8rem]">
{formatTemperature(displayedStation.temperature, language)}
{formatTemperature(displayedStation.temperature, language, temperatureUnit)}
</div>
<p className="mt-5 text-xl font-medium tracking-tight sm:text-2xl">{getWeatherDescription(displayedStation, language, currentWeather?.condition)}</p>
<p className="mt-1 text-sm text-muted">{t("weather.feelsLike")} {formatTemperature(feelsLike, language)} · {t("weather.measurement")} {formatDateTime(displayedStation.measuredAt, language)}</p>
<p className="mt-1 text-sm text-muted">{t("weather.feelsLike")} {formatTemperature(feelsLike, language, temperatureUnit)} · {t("weather.measurement")} {formatDateTime(displayedStation.measuredAt, language)}</p>
</div>
<WeatherIcon mood={mood} condition={currentWeather?.condition} className="mb-4 size-20 text-accent sm:size-28" />
</div>