# Weather Widget Architecture

## Overview
The Weather Widget is a server-rendered web application built with Node.js. It receives HTTP GET requests specifying `city` and `units` query parameters, processes weather datasets, and returns styled HTML pages.

```
       +------------------+
       |   HTTP Client    |
       +--------+---------+
                | GET /?city=rome&units=f
                v
       +------------------+
       |   HTTP Server    |
       |  (handleRequest) |
       +--------+---------+
                |
    +-----------+-----------+
    |                       |
    v                       v
+-------+               +-------+
|  City |               | Unit  |
| Lookup|               | Convert|
+---+---+               +---+---+
    |                       |
    +-----------+-----------+
                |
                v
      +-------------------+
      |   View Renderers  |
      | (renderWeatherPage|
      |  renderUnknown)   |
      +---------+---------+
                |
                v
      +-------------------+
      |   HTML Response   |
      +-------------------+
```

---

## Component Ownership & Responsibilities

### 1. HTTP Server & Request Handler (`server.js`)
* **Functions**: `createServer()`, `handleRequest()`, `pickPort()`
* **Ownership**: Manages the HTTP server lifecycle, listes on specified port, extracts URL query parameters (`city`, `units`), and coordinates request handling to send UTF-8 HTML responses.

### 2. Data Store & Lookup Layer (`CITIES`, `findCity`)
* **Functions / Data**: `CITIES` object dictionary, `findCity()` lookup helper.
* **Ownership**: Stores the static weather dataset for the four supported cities (`nyc`, `sao-paulo`, `bangkok`, `rome`). `findCity()` normalizes city names (handling case-insensitivity, hyphens, and common aliases like `New York`).

### 3. Unit Conversion & Formatting Engine (`convertTemp`, `formatWind`, `normalizeUnits`)
* **Functions**: `convertTemp()`, `formatWind()`, `normalizeUnits()`
* **Ownership**: Encapsulates temperature conversion logic ($F = \text{round}(C \times 9 / 5 + 32)$) and unit formatting for speed ($kph$ vs $mph$). Ensures consistent metric outputs across weather cards and 3-day forecast rows.

### 4. View Rendering Layer (`renderWeatherPage`, `renderUnknownPage`, `renderLayout`, `renderStyles`)
* **Functions**: `renderWeatherPage()`, `renderUnknownPage()`, `renderLayout()`, `renderStyles()`, `renderSearchForm()`, `renderQuickPicks()`
* **Ownership**: Constructs responsive, glassmorphic HTML components. Handles both successful weather views and polite unknown-city fallback states (`"unknown city"`).

---

## Data Flow

1. **Request Reception**: An incoming HTTP request arrives at `handleRequest()`.
2. **Parameter Parsing**: `URL` search parameters `city` and `units` are parsed and normalized.
3. **Data Retrieval**: `findCity(rawCity)` queries the `CITIES` data store.
   * If `city` is empty/omitted, defaults to `rome`.
   * If city is not found (e.g., `atlantis`), returns `null`.
4. **View Assembly**:
   * **Success Path**: `renderWeatherPage()` formats current temperature, condition, wind metrics, and 3-day forecast using `convertTemp()`, returning a full HTML layout.
   * **Fallback Path**: `renderUnknownPage()` renders a polite error view containing `"unknown city"` along with quick-pick chips for supported cities.
5. **Response Delivery**: `handleRequest()` writes the generated HTML string with `200 OK` status and `text/html; charset=utf-8` header.
