# RadioStation — KMountain Flower A static Angular boilerplate for a community radio station website. The app showcases a broadcast schedule, upcoming events, donation tiers, an about page, and a contact form — all styled with a warm mountain/nature aesthetic. ## Architecture ``` src/ ├── app/ # Angular application root │ ├── app.ts # Root component (shell layout) │ ├── app.config.ts # Application config: providers + router │ ├── app.html # Shell template: navbar + + footer │ ├── app.routes.ts # Route definitions (lazy-loaded components) │ ├── app.scss # Root component styles │ ├── hero/ # Landing page (home route) │ ├── about/ # About the station page │ ├── schedule/ # Program schedule (data-driven table) │ ├── donate/ # Donation tiers (data-driven cards) │ ├── events/ # Upcoming events (data-driven cards) │ ├── contact/ # Contact form (two-way binding via FormsModule) │ ├── navbar/ # Top navigation bar (responsive hamburger menu) │ └── footer/ # Site footer ├── styles/ # Global SCSS design tokens │ ├── _variables.scss # Color palette, spacing, breakpoints, z-index scale │ ├── _mixins.scss # Reusable SCSS mixins (cards, buttons, responsiveness) │ ├── _themes.scss # Maps SCSS vars → CSS custom properties on :root │ └── index.scss # Global entry: reset + utility classes + theme import ├── assets/ │ └── svg/ # Decorative SVGs (mountain dividers, floral accents) ├── main.ts # App bootstrap entry point └── index.html # HTML shell ( mount point) ``` ### Key architectural decisions - **Standalone components** — Every component is standalone (no NgModules). This is Angular 21's default and keeps imports explicit. - **Lazy-loaded routes** — Each page is code-splitted via `loadComponent()` in [app.routes.ts](src/app/app.routes.ts). The router imports each component on first navigation. - **Data-driven pages** — `ScheduleComponent`, `DonateComponent`, and `EventsComponent` all hold their content as readonly arrays (`readonly programs: Program[]`, etc.). To update content, edit these arrays in the component TypeScript files. - **Design tokens in SCSS** — All colors, spacing, breakpoints, and typography live in [src/styles/_variables.scss](src/styles/_variables.scss). Change these once and every component inherits the new values via [_themes.scss](src/styles/_themes.scss) (which exposes them as CSS custom properties) and the mixins in [_mixins.scss](src/styles/_mixins.scss). - **SCSS preprocessor paths** — [angular.json](angular.json) adds `src/styles/` to the include path, so any component can `@use 'variables'` without a relative path. ## Pages | Route | Component | Description | | -------- | --------------- | -------------------------------------------- | | `/` | HeroComponent | Hero landing section | | `/about` | AboutComponent | Station mission & info | | `/schedule` | ScheduleComponent | Program schedule, rendered from `programs[]` | | `/donate` | DonateComponent | Donation tiers, rendered from `tiers[]` | | `/events` | EventsComponent | Upcoming events, rendered from `upcomingEvents[]` | | `/contact` | ContactComponent | Contact form with submission handler | ## Customization guide ### Re-skinning the color palette 1. Edit the color variables in [src/styles/_variables.scss](src/styles/_variables.scss). The primary palette (blue) and accent palette (orange) control the entire site. 2. That's it — [_themes.scss](src/styles/_themes.scss) automatically maps them to CSS custom properties used by every component. ### Changing typography Edit `$font-primary`, `$font-heading`, and `$font-mono` in [src/styles/_variables.scss](src/styles/_variables.scss). ### Adding a new page 1. Create a new folder under `src/app/` with a `*.component.ts`, `*.component.html`, and `*.component.scss`. 2. Export a `@Component` decorated class. 3. Add a route in [app.routes.ts](src/app/app.routes.ts) using `loadComponent()` to lazy-load it. 4. (Optional) Add a `RouterLink` in [navbar.component.html](src/app/navbar/navbar.component.html). ### Updating schedule / events / donation content Edit the `readonly` arrays directly in their respective component files: - [schedule.component.ts](src/app/schedule/schedule.component.ts) — `programs` - [events.component.ts](src/app/events/events.component.ts) — `upcomingEvents` - [donate.component.ts](src/app/donate/donate.component.ts) — `tiers` Each interface (`Program`, `Event`, `Tier`) is defined in the component file. Modify the interfaces and data together. ## Getting started ### Prerequisites - Node.js 20+ (or use the dev container) - npm 11+ ### Quick start ```bash npm install ng serve ``` Open [http://localhost:4200](http://localhost:4200). ### Development server ```bash ng serve # Start dev server (hot reload enabled) ng serve --port 8080 # Custom port ``` ### Building ```bash ng build # Production build → dist/ ng build --configuration development # With source maps ``` ### Code style This project uses [Prettier](https://prettier.io/) (configured in [.prettierrc](.prettierrc)). Run: ```bash npx prettier --write . ``` ### Testing ```bash ng test # Run unit tests (Vitest) ``` ## Dev container This project ships with a [.devcontainer/](.devcontainer/) for VS Code. Open the repo in VS Code → "Reopen in Container" to get a pre-configured environment with Angular CLI, Node.js, Python 3, and Git. ## Project tech stack - **Framework:** Angular 21 (standalone components, signals-ready) - **Language:** TypeScript 5.9 - **Styling:** SCSS with design tokens (variables → mixins → CSS custom properties) - **Routing:** Angular Router with lazy loading - **Form handling:** FormsModule (two-way binding) - **Linting/formatting:** Prettier - **Testing:** Vitest (via Angular CLI) - **Package manager:** npm 11.11