diff --git a/components.json b/components.json
new file mode 100644
index 0000000..f258682
--- /dev/null
+++ b/components.json
@@ -0,0 +1,16 @@
+{
+ "$schema": "https://shadcn-svelte.com/schema.json",
+ "tailwind": {
+ "css": "src/app.css",
+ "baseColor": "zinc"
+ },
+ "aliases": {
+ "components": "$lib/components",
+ "utils": "$lib/utils",
+ "ui": "$lib/components/ui",
+ "hooks": "$lib/hooks",
+ "lib": "$lib"
+ },
+ "typescript": true,
+ "registry": "https://shadcn-svelte.com/registry"
+}
diff --git a/national_weather_service_api.md b/national_weather_service_api.md
new file mode 100644
index 0000000..393f14c
--- /dev/null
+++ b/national_weather_service_api.md
@@ -0,0 +1,324 @@
+
+## Get Forecast
+`GET https://api.weather.gov/gridpoints/PQR/116,103/forecast`
+```json
+{
+ "@context": [
+ "https://geojson.org/geojson-ld/geojson-context.jsonld",
+ {
+ "@version": "1.1",
+ "wx": "https://api.weather.gov/ontology#",
+ "geo": "http://www.opengis.net/ont/geosparql#",
+ "unit": "http://codes.wmo.int/common/unit/",
+ "@vocab": "https://api.weather.gov/ontology#"
+ }
+ ],
+ "type": "Feature",
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -122.5566,
+ 45.5102
+ ],
+ [
+ -122.56280000000001,
+ 45.531
+ ],
+ [
+ -122.5926,
+ 45.5267
+ ],
+ [
+ -122.5864,
+ 45.505899899999996
+ ],
+ [
+ -122.5566,
+ 45.5102
+ ]
+ ]
+ ]
+ },
+ "properties": {
+ "units": "us",
+ "forecastGenerator": "BaselineForecastGenerator",
+ "generatedAt": "2025-06-26T01:32:44+00:00",
+ "updateTime": "2025-06-26T00:40:50+00:00",
+ "validTimes": "2025-06-25T18:00:00+00:00/P7DT10H",
+ "elevation": {
+ "unitCode": "wmoUnit:m",
+ "value": 85.9536
+ },
+ "periods": [
+ {
+ "number": 1,
+ "name": "Tonight",
+ "startTime": "2025-06-25T18:00:00-07:00",
+ "endTime": "2025-06-26T06:00:00-07:00",
+ "isDaytime": false,
+ "temperature": 58,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 31
+ },
+ "windSpeed": "2 to 6 mph",
+ "windDirection": "NNW",
+ "icon": "https://api.weather.gov/icons/land/night/ovc/rain,30?size=medium",
+ "shortForecast": "Cloudy then Chance Drizzle",
+ "detailedForecast": "A chance of drizzle after 5am. Cloudy, with a low around 58. North northwest wind 2 to 6 mph. Chance of precipitation is 30%."
+ },
+ {
+ "number": 2,
+ "name": "Thursday",
+ "startTime": "2025-06-26T06:00:00-07:00",
+ "endTime": "2025-06-26T18:00:00-07:00",
+ "isDaytime": true,
+ "temperature": 69,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 31
+ },
+ "windSpeed": "2 to 6 mph",
+ "windDirection": "SW",
+ "icon": "https://api.weather.gov/icons/land/day/rain,30/rain,20?size=medium",
+ "shortForecast": "Chance Drizzle",
+ "detailedForecast": "A chance of drizzle before 2pm. Mostly cloudy, with a high near 69. Southwest wind 2 to 6 mph. Chance of precipitation is 30%."
+ },
+ {
+ "number": 3,
+ "name": "Thursday Night",
+ "startTime": "2025-06-26T18:00:00-07:00",
+ "endTime": "2025-06-27T06:00:00-07:00",
+ "isDaytime": false,
+ "temperature": 56,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 8
+ },
+ "windSpeed": "2 to 6 mph",
+ "windDirection": "NW",
+ "icon": "https://api.weather.gov/icons/land/night/bkn?size=medium",
+ "shortForecast": "Mostly Cloudy",
+ "detailedForecast": "Mostly cloudy, with a low around 56. Northwest wind 2 to 6 mph."
+ },
+ {
+ "number": 4,
+ "name": "Friday",
+ "startTime": "2025-06-27T06:00:00-07:00",
+ "endTime": "2025-06-27T18:00:00-07:00",
+ "isDaytime": true,
+ "temperature": 73,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 3
+ },
+ "windSpeed": "2 to 6 mph",
+ "windDirection": "WNW",
+ "icon": "https://api.weather.gov/icons/land/day/bkn?size=medium",
+ "shortForecast": "Partly Sunny",
+ "detailedForecast": "Partly sunny, with a high near 73. West northwest wind 2 to 6 mph."
+ },
+ {
+ "number": 5,
+ "name": "Friday Night",
+ "startTime": "2025-06-27T18:00:00-07:00",
+ "endTime": "2025-06-28T06:00:00-07:00",
+ "isDaytime": false,
+ "temperature": 55,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 2
+ },
+ "windSpeed": "2 to 6 mph",
+ "windDirection": "NNW",
+ "icon": "https://api.weather.gov/icons/land/night/sct?size=medium",
+ "shortForecast": "Partly Cloudy",
+ "detailedForecast": "Partly cloudy, with a low around 55. North northwest wind 2 to 6 mph."
+ },
+ {
+ "number": 6,
+ "name": "Saturday",
+ "startTime": "2025-06-28T06:00:00-07:00",
+ "endTime": "2025-06-28T18:00:00-07:00",
+ "isDaytime": true,
+ "temperature": 80,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 0
+ },
+ "windSpeed": "2 to 9 mph",
+ "windDirection": "NNW",
+ "icon": "https://api.weather.gov/icons/land/day/few?size=medium",
+ "shortForecast": "Sunny",
+ "detailedForecast": "Sunny, with a high near 80."
+ },
+ {
+ "number": 7,
+ "name": "Saturday Night",
+ "startTime": "2025-06-28T18:00:00-07:00",
+ "endTime": "2025-06-29T06:00:00-07:00",
+ "isDaytime": false,
+ "temperature": 56,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 0
+ },
+ "windSpeed": "3 to 9 mph",
+ "windDirection": "NNW",
+ "icon": "https://api.weather.gov/icons/land/night/skc?size=medium",
+ "shortForecast": "Clear",
+ "detailedForecast": "Clear, with a low around 56."
+ },
+ {
+ "number": 8,
+ "name": "Sunday",
+ "startTime": "2025-06-29T06:00:00-07:00",
+ "endTime": "2025-06-29T18:00:00-07:00",
+ "isDaytime": true,
+ "temperature": 88,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 0
+ },
+ "windSpeed": "3 to 10 mph",
+ "windDirection": "NNW",
+ "icon": "https://api.weather.gov/icons/land/day/skc?size=medium",
+ "shortForecast": "Sunny",
+ "detailedForecast": "Sunny, with a high near 88."
+ },
+ {
+ "number": 9,
+ "name": "Sunday Night",
+ "startTime": "2025-06-29T18:00:00-07:00",
+ "endTime": "2025-06-30T06:00:00-07:00",
+ "isDaytime": false,
+ "temperature": 60,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 1
+ },
+ "windSpeed": "2 to 10 mph",
+ "windDirection": "NNW",
+ "icon": "https://api.weather.gov/icons/land/night/skc?size=medium",
+ "shortForecast": "Clear",
+ "detailedForecast": "Clear, with a low around 60."
+ },
+ {
+ "number": 10,
+ "name": "Monday",
+ "startTime": "2025-06-30T06:00:00-07:00",
+ "endTime": "2025-06-30T18:00:00-07:00",
+ "isDaytime": true,
+ "temperature": 90,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 7
+ },
+ "windSpeed": "2 to 10 mph",
+ "windDirection": "NNW",
+ "icon": "https://api.weather.gov/icons/land/day/few?size=medium",
+ "shortForecast": "Sunny",
+ "detailedForecast": "Sunny, with a high near 90."
+ },
+ {
+ "number": 11,
+ "name": "Monday Night",
+ "startTime": "2025-06-30T18:00:00-07:00",
+ "endTime": "2025-07-01T06:00:00-07:00",
+ "isDaytime": false,
+ "temperature": 61,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 7
+ },
+ "windSpeed": "2 to 10 mph",
+ "windDirection": "NW",
+ "icon": "https://api.weather.gov/icons/land/night/sct?size=medium",
+ "shortForecast": "Partly Cloudy",
+ "detailedForecast": "Partly cloudy, with a low around 61."
+ },
+ {
+ "number": 12,
+ "name": "Tuesday",
+ "startTime": "2025-07-01T06:00:00-07:00",
+ "endTime": "2025-07-01T18:00:00-07:00",
+ "isDaytime": true,
+ "temperature": 87,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 4
+ },
+ "windSpeed": "2 to 10 mph",
+ "windDirection": "NW",
+ "icon": "https://api.weather.gov/icons/land/day/sct?size=medium",
+ "shortForecast": "Mostly Sunny",
+ "detailedForecast": "Mostly sunny, with a high near 87."
+ },
+ {
+ "number": 13,
+ "name": "Tuesday Night",
+ "startTime": "2025-07-01T18:00:00-07:00",
+ "endTime": "2025-07-02T06:00:00-07:00",
+ "isDaytime": false,
+ "temperature": 59,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 4
+ },
+ "windSpeed": "2 to 10 mph",
+ "windDirection": "NW",
+ "icon": "https://api.weather.gov/icons/land/night/few?size=medium",
+ "shortForecast": "Mostly Clear",
+ "detailedForecast": "Mostly clear, with a low around 59."
+ },
+ {
+ "number": 14,
+ "name": "Wednesday",
+ "startTime": "2025-07-02T06:00:00-07:00",
+ "endTime": "2025-07-02T18:00:00-07:00",
+ "isDaytime": true,
+ "temperature": 83,
+ "temperatureUnit": "F",
+ "temperatureTrend": "",
+ "probabilityOfPrecipitation": {
+ "unitCode": "wmoUnit:percent",
+ "value": 3
+ },
+ "windSpeed": "2 to 9 mph",
+ "windDirection": "NW",
+ "icon": "https://api.weather.gov/icons/land/day/few?size=medium",
+ "shortForecast": "Sunny",
+ "detailedForecast": "Sunny, with a high near 83."
+ }
+ ]
+ }
+}
+```
diff --git a/package.json b/package.json
index d88b3a3..f5e3428 100644
--- a/package.json
+++ b/package.json
@@ -12,13 +12,18 @@
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
+ "@lucide/svelte": "^0.523.0",
"@sveltejs/adapter-auto": "^6.0.0",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/vite": "^4.0.0",
+ "clsx": "^2.1.1",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
+ "tailwind-merge": "^3.3.1",
+ "tailwind-variants": "^1.0.0",
"tailwindcss": "^4.0.0",
+ "tw-animate-css": "^1.3.4",
"typescript": "^5.0.0",
"vite": "^6.2.6"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 64a8ef6..fe04c9e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,6 +8,9 @@ importers:
.:
devDependencies:
+ '@lucide/svelte':
+ specifier: ^0.523.0
+ version: 0.523.0(svelte@5.34.8)
'@sveltejs/adapter-auto':
specifier: ^6.0.0
version: 6.0.1(@sveltejs/kit@2.22.0(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.30.1)))(svelte@5.34.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.30.1)))
@@ -20,15 +23,27 @@ importers:
'@tailwindcss/vite':
specifier: ^4.0.0
version: 4.1.10(vite@6.3.5(jiti@2.4.2)(lightningcss@1.30.1))
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
svelte:
specifier: ^5.0.0
version: 5.34.8
svelte-check:
specifier: ^4.0.0
version: 4.2.2(picomatch@4.0.2)(svelte@5.34.8)(typescript@5.8.3)
+ tailwind-merge:
+ specifier: ^3.3.1
+ version: 3.3.1
+ tailwind-variants:
+ specifier: ^1.0.0
+ version: 1.0.0(tailwindcss@4.1.10)
tailwindcss:
specifier: ^4.0.0
version: 4.1.10
+ tw-animate-css:
+ specifier: ^1.3.4
+ version: 1.3.4
typescript:
specifier: ^5.0.0
version: 5.8.3
@@ -214,6 +229,11 @@ packages:
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+ '@lucide/svelte@0.523.0':
+ resolution: {integrity: sha512-t6CNxUAC7to9IPQv+yaJD8OlpXVeEL7wT1nw5+lx62HoBnkO6//xYZSTkV8Ia3bqtoF4deI3Pjff/8cPyQjiCw==}
+ peerDependencies:
+ svelte: ^5
+
'@polka/url@1.0.0-next.29':
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
@@ -684,6 +704,18 @@ packages:
resolution: {integrity: sha512-TF+8irl7rpj3+fpaLuPRX5BqReTAqckp0Fumxa/mCeK3fo0/MnBb9W/Z2bLwtqj3C3r5Lm6NKIAw7YrgIv1Fwg==}
engines: {node: '>=18'}
+ tailwind-merge@3.0.2:
+ resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==}
+
+ tailwind-merge@3.3.1:
+ resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==}
+
+ tailwind-variants@1.0.0:
+ resolution: {integrity: sha512-2WSbv4ulEEyuBKomOunut65D8UZwxrHoRfYnxGcQNnHqlSCp2+B7Yz2W+yrNDrxRodOXtGD/1oCcKGNBnUqMqA==}
+ engines: {node: '>=16.x', pnpm: '>=7.x'}
+ peerDependencies:
+ tailwindcss: '*'
+
tailwindcss@4.1.10:
resolution: {integrity: sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==}
@@ -703,6 +735,9 @@ packages:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
+ tw-animate-css@1.3.4:
+ resolution: {integrity: sha512-dd1Ht6/YQHcNbq0znIT6dG8uhO7Ce+VIIhZUhjsryXsMPJQz3bZg7Q2eNzLwipb25bRZslGb2myio5mScd1TFg==}
+
typescript@5.8.3:
resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
engines: {node: '>=14.17'}
@@ -866,6 +901,10 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
+ '@lucide/svelte@0.523.0(svelte@5.34.8)':
+ dependencies:
+ svelte: 5.34.8
+
'@polka/url@1.0.0-next.29': {}
'@rollup/rollup-android-arm-eabi@4.44.0':
@@ -1282,6 +1321,15 @@ snapshots:
magic-string: 0.30.17
zimmerframe: 1.1.2
+ tailwind-merge@3.0.2: {}
+
+ tailwind-merge@3.3.1: {}
+
+ tailwind-variants@1.0.0(tailwindcss@4.1.10):
+ dependencies:
+ tailwind-merge: 3.0.2
+ tailwindcss: 4.1.10
+
tailwindcss@4.1.10: {}
tapable@2.2.2: {}
@@ -1302,6 +1350,8 @@ snapshots:
totalist@3.0.1: {}
+ tw-animate-css@1.3.4: {}
+
typescript@5.8.3: {}
vite@6.3.5(jiti@2.4.2)(lightningcss@1.30.1):
diff --git a/src/app.css b/src/app.css
index d4b5078..9067e16 100644
--- a/src/app.css
+++ b/src/app.css
@@ -1 +1,161 @@
-@import 'tailwindcss';
+@import "tailwindcss";
+
+@import "tw-animate-css";
+
+@custom-variant dark (&:is(.dark *));
+
+:root {
+ --radius: 0.625rem;
+ --background: oklch(1 0 0);
+ --foreground: oklch(0.129 0.042 264.695);
+ --card: oklch(1 0 0);
+ --card-foreground: oklch(0.129 0.042 264.695);
+ --popover: oklch(1 0 0);
+ --popover-foreground: oklch(0.129 0.042 264.695);
+ --primary: oklch(0.208 0.042 265.755);
+ --primary-foreground: oklch(0.984 0.003 247.858);
+ --secondary: oklch(0.968 0.007 247.896);
+ --secondary-foreground: oklch(0.208 0.042 265.755);
+ --muted: oklch(0.968 0.007 247.896);
+ --muted-foreground: oklch(0.554 0.046 257.417);
+ --accent: oklch(0.968 0.007 247.896);
+ --accent-foreground: oklch(0.208 0.042 265.755);
+ --destructive: oklch(0.577 0.245 27.325);
+ --border: oklch(0.929 0.013 255.508);
+ --input: oklch(0.929 0.013 255.508);
+ --ring: oklch(0.704 0.04 256.788);
+ --chart-1: oklch(0.646 0.222 41.116);
+ --chart-2: oklch(0.6 0.118 184.704);
+ --chart-3: oklch(0.398 0.07 227.392);
+ --chart-4: oklch(0.828 0.189 84.429);
+ --chart-5: oklch(0.769 0.188 70.08);
+ --sidebar: oklch(0.984 0.003 247.858);
+ --sidebar-foreground: oklch(0.129 0.042 264.695);
+ --sidebar-primary: oklch(0.208 0.042 265.755);
+ --sidebar-primary-foreground: oklch(0.984 0.003 247.858);
+ --sidebar-accent: oklch(0.968 0.007 247.896);
+ --sidebar-accent-foreground: oklch(0.208 0.042 265.755);
+ --sidebar-border: oklch(0.929 0.013 255.508);
+ --sidebar-ring: oklch(0.704 0.04 256.788);
+}
+
+.dark {
+ --background: oklch(0.129 0.042 264.695);
+ --foreground: oklch(0.984 0.003 247.858);
+ --card: oklch(0.208 0.042 265.755);
+ --card-foreground: oklch(0.984 0.003 247.858);
+ --popover: oklch(0.208 0.042 265.755);
+ --popover-foreground: oklch(0.984 0.003 247.858);
+ --primary: oklch(0.929 0.013 255.508);
+ --primary-foreground: oklch(0.208 0.042 265.755);
+ --secondary: oklch(0.279 0.041 260.031);
+ --secondary-foreground: oklch(0.984 0.003 247.858);
+ --muted: oklch(0.279 0.041 260.031);
+ --muted-foreground: oklch(0.704 0.04 256.788);
+ --accent: oklch(0.279 0.041 260.031);
+ --accent-foreground: oklch(0.984 0.003 247.858);
+ --destructive: oklch(0.704 0.191 22.216);
+ --border: oklch(1 0 0 / 10%);
+ --input: oklch(1 0 0 / 15%);
+ --ring: oklch(0.551 0.027 264.364);
+ --chart-1: oklch(0.488 0.243 264.376);
+ --chart-2: oklch(0.696 0.17 162.48);
+ --chart-3: oklch(0.769 0.188 70.08);
+ --chart-4: oklch(0.627 0.265 303.9);
+ --chart-5: oklch(0.645 0.246 16.439);
+ --sidebar: oklch(0.208 0.042 265.755);
+ --sidebar-foreground: oklch(0.984 0.003 247.858);
+ --sidebar-primary: oklch(0.488 0.243 264.376);
+ --sidebar-primary-foreground: oklch(0.984 0.003 247.858);
+ --sidebar-accent: oklch(0.279 0.041 260.031);
+ --sidebar-accent-foreground: oklch(0.984 0.003 247.858);
+ --sidebar-border: oklch(1 0 0 / 10%);
+ --sidebar-ring: oklch(0.551 0.027 264.364);
+}
+
+.dark {
+ --background: oklch(0.141 0.005 285.823);
+ --foreground: oklch(0.985 0 0);
+ --card: oklch(0.21 0.006 285.885);
+ --card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.21 0.006 285.885);
+ --popover-foreground: oklch(0.985 0 0);
+ --primary: oklch(0.92 0.004 286.32);
+ --primary-foreground: oklch(0.21 0.006 285.885);
+ --secondary: oklch(0.274 0.006 286.033);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.274 0.006 286.033);
+ --muted-foreground: oklch(0.705 0.015 286.067);
+ --accent: oklch(0.274 0.006 286.033);
+ --accent-foreground: oklch(0.985 0 0);
+ --destructive: oklch(0.704 0.191 22.216);
+ --border: oklch(1 0 0 / 10%);
+ --input: oklch(1 0 0 / 15%);
+ --ring: oklch(0.552 0.016 285.938);
+ --chart-1: oklch(0.488 0.243 264.376);
+ --chart-2: oklch(0.696 0.17 162.48);
+ --chart-3: oklch(0.769 0.188 70.08);
+ --chart-4: oklch(0.627 0.265 303.9);
+ --chart-5: oklch(0.645 0.246 16.439);
+ --sidebar: oklch(0.21 0.006 285.885);
+ --sidebar-foreground: oklch(0.985 0 0);
+ --sidebar-primary: oklch(0.488 0.243 264.376);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.274 0.006 286.033);
+ --sidebar-accent-foreground: oklch(0.985 0 0);
+ --sidebar-border: oklch(1 0 0 / 10%);
+ --sidebar-ring: oklch(0.552 0.016 285.938);
+}
+
+@theme inline {
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+ --radius-xl: calc(var(--radius) + 4px);
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --color-chart-1: var(--chart-1);
+ --color-chart-2: var(--chart-2);
+ --color-chart-3: var(--chart-3);
+ --color-chart-4: var(--chart-4);
+ --color-chart-5: var(--chart-5);
+ --color-sidebar: var(--sidebar);
+ --color-sidebar-foreground: var(--sidebar-foreground);
+ --color-sidebar-primary: var(--sidebar-primary);
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
+ --color-sidebar-accent: var(--sidebar-accent);
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
+ --color-sidebar-border: var(--sidebar-border);
+ --color-sidebar-ring: var(--sidebar-ring);
+}
+
+@layer base {
+ * {
+ @apply border-border outline-ring/50;
+ }
+ body {
+ @apply bg-background text-foreground min-h-screen;
+ }
+}
+
+@layer utilities {
+ .container {
+ @apply max-w-7xl;
+ }
+}
diff --git a/src/lib/components/LocationButton.svelte b/src/lib/components/LocationButton.svelte
new file mode 100644
index 0000000..370e6d7
--- /dev/null
+++ b/src/lib/components/LocationButton.svelte
@@ -0,0 +1,16 @@
+
+
+
diff --git a/src/lib/components/WeatherCard.svelte b/src/lib/components/WeatherCard.svelte
new file mode 100644
index 0000000..2b4fc58
--- /dev/null
+++ b/src/lib/components/WeatherCard.svelte
@@ -0,0 +1,84 @@
+
+
+ {period.shortForecast}
+ {period.detailedForecast}
+
+ {@render children?.()} +
diff --git a/src/lib/components/ui/card/card-footer.svelte b/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 0000000..cf43353 --- /dev/null +++ b/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,20 @@ + + +Visit svelte.dev/docs/kit to read the documentation
+ + ++ Get current weather conditions and forecasts from the National Weather Service +
+{error}
+