Documentation v1.0

SkyCast — Advanced Weather Intelligence

A full-featured, real-time weather progressive web application built with vanilla HTML, CSS, and JavaScript. No frameworks. No build tools. Just clean, well-structured code.

Year: 2025–2026
Version: 1.0
Size: ~3 files
Stack: Vanilla JS + CSS

Developer

Susovon Jana, Ph.D.

Researcher, developer, and designer of SkyCast. Passionate about combining scientific rigour with intuitive, beautiful interface design. The project was created as a demonstration of what is possible with pure browser technologies — no React, no Vue, no bundlers.

Features

GPS Location

Automatically detects the user's precise location using the browser Geolocation API, with graceful fallback to city search.

Live Weather

Fetches real-time temperature, feels-like, humidity, wind, pressure, UV index, and visibility from Open-Meteo.

24-Hour Forecast

Hourly breakdown for the next 24 hours including rain probability and weather icon per hour.

14-Day Forecast

Extended 14-day daily forecast with high/low temperatures, rain probability, and average humidity.

Air Quality Index

US AQI with animated ring gauge, PM2.5, PM10, NO₂ and O₃ pollutant bars, and health advice text.

City Compare

Side-by-side weather comparison of any two cities worldwide with instant API look-up.

Saved Favorites

Up to 8 locations can be saved to browser localStorage for quick one-tap access.

Sun Progress Bar

Animated sunrise-to-sunset arc showing real-time sun position based on local timezone data.

File Structure

The production version is 3 files for simplicity and portability.

skycast/
  ├── index.html ← full HTML structure
  ├── styles.css ← ALL styles merged
  ├── app.js ← ALL JavaScript merged
  └── documentation.html ← this file

Data Flow

SkyCast follows a simple, linear data pipeline from user action to rendered UI.

1

User Action

User opens the app, clicks a city chip, types a search, or presses the GPS button.

2

Geocoding

Open-Meteo Geocoding API converts a city name to latitude/longitude coordinates. For GPS, Nominatim (OSM) does the reverse — coords → human-readable location name.

3

Parallel API Fetch

Two API calls fire simultaneously via Promise.all(): the Open-Meteo weather API (current + hourly + daily) and the Open-Meteo Air Quality API (AQI + pollutants).

4

Data Normalisation

Raw API responses are transformed into a single currentWeatherData object. Hourly data is sliced to the next 24 hours; daily data is iterated into 14 day objects with computed average humidity.

5

Render

renderDashboard() calls each sub-renderer in order: hero → metrics → AQI → hourly → 14-day forecast. All DOM writes use setEl() to safely update elements by ID.

APIs Used

Open-Meteo Weather API Free · No Key

Provides current conditions (temperature, humidity, wind, pressure, UV, cloud cover, visibility, precipitation), plus hourly and 14-day daily forecasts. open-meteo.com

Open-Meteo Air Quality API Free · No Key

Returns US AQI, PM2.5, PM10, nitrogen dioxide (NO₂) and ozone (O₃) for any coordinates. air-quality-api.open-meteo.com

Open-Meteo Geocoding API Free · No Key

Converts city names to latitude/longitude. Used for city search and the global capitals dropdown. geocoding-api.open-meteo.com

Nominatim / OpenStreetMap Free · No Key

Reverse geocoding — converts GPS coordinates to a human-readable location name (village, district, state, country). nominatim.openstreetmap.org

Zero API keys required. SkyCast intentionally uses only free, open APIs with no authentication requirement. This means it can be deployed and run by anyone without signing up for any service.

Local Setup

SkyCast requires no build tools, no npm, no Node.js. All you need is a browser and a local static file server (to satisfy browser CORS restrictions on the Geolocation API).

Option A — VS Code Live Server (Recommended)

Install the Live Server extension in VS Code, right-click index.html and choose Open with Live Server.

Option B — Python HTTP Server

# Navigate to the project folder
cd skycast/

# Python 3
python -m http.server 8080

# Then open http://localhost:8080 in your browser

Option C — Node.js serve

npx serve .
# Then open the URL shown in terminal

Note: GPS will not work if you open index.html directly as a file:// URL. A local server is required for the Geolocation API to function correctly.

Deployment

SkyCast is a fully static application — deploy it anywhere that serves static files. The live version runs on Cloudflare Pages at sky-cast.pages.dev.

Git Workflow

# First-time setup
git init
git remote add origin https://github.com/username/WeatherApp.git
git add .
git commit -m "First commit"
git branch -M main
git push -u origin main

# Subsequent pushes
git add .
git commit -m "update"
git push

Cloudflare Pages

Connect your GitHub repo to Cloudflare Pages. Set build command to none and output directory to /. Every push auto-deploys.

GitHub Pages

Enable GitHub Pages on the main branch in repository settings. The site will be live at username.github.io/WeatherApp.

JS Module Reference

FunctionModule (§)Description
CONFIG§1 ConfigGlobal app state: unit preference, favorites array, last location
WEATHER_CODES§1 ConfigMap of WMO weather codes to icon, color, and text description
AQI_LEVELS§1 ConfigArray of AQI thresholds with color and health advice
convertTemp()§2 UtilsConverts Celsius to °C or °F based on CONFIG.isMetric
showToast()§2 UtilsDisplays a transient notification message at screen bottom
getSunProgress()§2 UtilsReturns 0–1 fraction of daylight elapsed for sun progress bar
handleGPS()§3 APITriggers browser geolocation and calls reverseGeocode + weather
fetchCoordinates()§3 APIGeocodes a city name and loads weather for that location
getLiveWeatherData()§3 APIMain data-fetch: calls weather + AQI APIs in parallel
compareCities()§3 APIGeocodes two cities and fetches weather for both simultaneously
renderDashboard()§4 RenderMaster render that calls all sub-renderers in sequence
renderHero()§4 RenderUpdates location name, temperature, condition, sun bar
renderAQI()§4 RenderAnimates AQI ring, sets badge color, updates pollutant bars
startLocalClock()§4 RenderStarts a 1-second interval showing the location's local time
init()§5 AppEntry point: populates UI lists, binds events, fires GPS
setTheme()§5 AppToggles dark/light theme on <html> data-theme attribute

CSS Architecture

All styles are written in pure CSS3 using custom properties (variables) for theming and a CSS Grid layout system. There is no preprocessor (Sass/Less) and no utility framework (Tailwind).

SectionLines (approx.)Contents
§1 Variables~80Dark and light theme tokens: colors, glass, shadows, icons
§2 Reset~40Box-model reset, base typography, scrollbar styling, utilities
§3–4 Background/Loader~50Ambient orbs, loading screen with progress bar
§5–9 Layout~180App wrapper, sticky header, search bar, quick-nav, grid, footer
§10 Hero~110Temperature display, weather icon, sunrise/sunset bar
§11 Metrics~556-card metrics grid with icon wraps and bar charts
§12 AQI~70SVG ring gauge, pollutant bars, badge coloring
§13 Compare~55Input wraps, VS divider, compare results grid
§14 Forecast~80Hourly scroll and 14-day card scroll containers
§15 Animations~90All @keyframes, stagger delays, reduced-motion support
§16 Responsive~1506 breakpoints: 1200, 1024, 768, 480px + landscape + safe areas

The dark theme is the default (:root) and the light theme is applied via [data-theme="light"] on the <html> element, toggled by JavaScript and persisted to localStorage.

Configuration

All user-facing configuration is centralised in the CONFIG object and the static arrays at the top of app.js.

KeyTypeDefaultPurpose
CONFIG.isMetricbooleantrueTemperature unit: true = °C, false = °F
CONFIG.favoritesstring[][]Saved location strings from localStorage
CONFIG.lastLocationobjectnullMost recently loaded location (lat, lon, name)
INDIAN_CITIESstring[]15 citiesQuick-access city chips in the nav bar
GLOBAL_CAPITALSstring[]30 capitalsDropdown list of world capital cities

To add more Indian cities or global capitals, simply append to the INDIAN_CITIES or GLOBAL_CAPITALS arrays at the top of app.js.

// Example: add Siliguri to city chips
const INDIAN_CITIES = [
    "Kolkata", "Mumbai", ..., "Siliguri"
];

SkyCast Documentation — Built by Susovon Jana, Ph.D. · Live: sky-cast.pages.dev