Compare commits
7
Commits
029fb48ca6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59c607ef77 | ||
|
|
ca3ad5e246 | ||
|
|
8ec1678210 | ||
|
|
dd8e6d44de | ||
|
|
b4fcad6dcd | ||
|
|
ccb0d53bdc | ||
|
|
9b66ceb862 |
No files matched your search
@@ -1,86 +1,51 @@
|
|||||||
# FlowerCMS — Marketing Screenshots
|
# FlowerCMS
|
||||||
|
|
||||||
White-label CMS demo sites for broadcasters. Two stations, one platform.
|
Marketing website for **FlowerCMS** — white-label content management for small
|
||||||
|
radio and internet broadcasters. One platform, every channel: a branded public
|
||||||
|
website, an admin dashboard, native mobile apps, an always-on live stream
|
||||||
|
player, event and sponsor tools, and a hosted LibreTime studio.
|
||||||
|
|
||||||
---
|
This repository is the marketing site itself plus the screenshot assets that
|
||||||
|
demonstrate the product. It is a static HTML site.
|
||||||
|
|
||||||
## Sites
|
## Production info
|
||||||
|
Visit https://www.flowercms.cloud/
|
||||||
|
|
||||||
| # | Station | Brand Name | URL | Local Port |
|
## What's in this repo
|
||||||
|---|---|---|---|---|
|
|
||||||
| 1 | **KMTN** | KMountain Flower Radio | http://kmtn.westerntechnologies.duckdns.org | http://localhost:4200 |
|
|
||||||
| 2 | **KRY2** | Fire FM | http://staylit.westerntechnologies.duckdns.org | http://localhost:4201 |
|
|
||||||
|
|
||||||
Both sites run via Docker Compose behind Nginx Proxy Manager.
|
- **`index.html`** — the FlowerCMS marketing landing page. Sections:
|
||||||
|
- **Hero** — "Your station, your brand, one powerful CMS."
|
||||||
|
- **White-Label Showcase** — two demo stations, *KMountain Flower Radio* and
|
||||||
|
*Fire FM*, built on the same platform.
|
||||||
|
- **Features** — program schedule, station pages, event management, contact &
|
||||||
|
engagement, media player, smart color picker, mobile build server,
|
||||||
|
white-label mobile app, sponsor carousel & takeover modal, hosted LibreTime
|
||||||
|
studio, worldwide MP3 streaming.
|
||||||
|
- **Pricing** — single flat plan.
|
||||||
|
- **CTA / footer** — contact sales.
|
||||||
|
- **`site-screenshots.html`** — a gallery of screenshots of the
|
||||||
|
*KMountain Flower Radio* site (public pages and admin dashboard).
|
||||||
|
- **`convert.py`** — resizes full-res `.png` screenshots down to the 500px-wide
|
||||||
|
JPEGs used on the showcase.
|
||||||
|
- **`server.py`** — tiny static file server for viewing the site locally.
|
||||||
|
- **`*.jpg` / `*.png`** — screenshot and screenshot-source assets used by the
|
||||||
|
pages above.
|
||||||
|
|
||||||
## Admin Access
|
## View locally
|
||||||
|
|
||||||
**Login page:** append `/admin` to any site URL (e.g. `http://kmtn.westerntechnologies.duckdns.org/admin`)
|
The site is static — open `index.html` directly, or serve the folder:
|
||||||
|
|
||||||
| Field | Value |
|
|
||||||
|---|---|
|
|
||||||
| Username | `admin` |
|
|
||||||
| Password | `123` |
|
|
||||||
|
|
||||||
Admin dashboard tabs: **Shows · Events · History · Team · Community · Station · Theme · Underwriters · Mobile Builds · Stats**
|
|
||||||
|
|
||||||
## Docker Services
|
|
||||||
|
|
||||||
| Container | Image | Ports |
|
|
||||||
|---|---|---|
|
|
||||||
| `kmtnflower-frontend-1` | kmtnflower-frontend | 0.0.0.0:4200 → 80 |
|
|
||||||
| `kmtnflower-api-1` | kmtnflower-api | 8000 (internal) |
|
|
||||||
| `kmtnflower-db-1` | postgres:16-alpine | 5432 (internal) |
|
|
||||||
| `kmtnflower-build-1` | kmtnflower-build | 22 (internal) |
|
|
||||||
| `kryz-frontend-1` | kryz-frontend | 0.0.0.0:4201 → 80 |
|
|
||||||
| `kryz-api-1` | kryz-api | 8000 (internal) |
|
|
||||||
| `kryz-db-1` | postgres:16-alpine | 5432 (internal) |
|
|
||||||
| `kryz-build-1` | kryz-build | 22 (internal) |
|
|
||||||
|
|
||||||
## Screenshot Files
|
|
||||||
|
|
||||||
All images are 500px wide, JPEG, captured at 1.5× zoom.
|
|
||||||
|
|
||||||
| File | Source | Used In |
|
|
||||||
|---|---|---|
|
|
||||||
| `homepage.jpg` | KMTN public homepage | marketing.html (hero + player) |
|
|
||||||
| `schedule.jpg` | KMTN schedule page | marketing.html |
|
|
||||||
| `about.jpg` | KMTN about page | marketing.html |
|
|
||||||
| `events.jpg` | KMTN events page | marketing.html |
|
|
||||||
| `contact.jpg` | KMTN contact page | marketing.html |
|
|
||||||
| `admin_dashboard.jpg` | KMTN admin — Shows tab | marketing.html |
|
|
||||||
| `admin_theme.jpg` | KMTN admin — Theme tab | marketing.html |
|
|
||||||
| `admin_mobile_builds.jpg` | KMTN admin — Mobile Builds tab | marketing.html |
|
|
||||||
| `kmtn_homepage.jpg` | KMTN homepage (white-label showcase) | marketing.html |
|
|
||||||
| `staylit_homepage.jpg` | Fire FM homepage (white-label showcase) | marketing.html |
|
|
||||||
|
|
||||||
## How to Recapture Screenshots
|
|
||||||
|
|
||||||
1. Open site in browser at the URL above.
|
|
||||||
2. Sign in at `/admin` with `admin` / `123`.
|
|
||||||
3. In DevTools Console, set zoom:
|
|
||||||
```js
|
|
||||||
document.body.style.zoom = '1.5';
|
|
||||||
document.documentElement.style.zoom = '1.5';
|
|
||||||
```
|
|
||||||
4. Click the desired admin tab.
|
|
||||||
5. Capture screenshot (browser_vision or OS screencapture).
|
|
||||||
6. Resize to 500px wide, convert to JPEG:
|
|
||||||
```bash
|
|
||||||
sips --resampleWidth 500 input.png --out tmp.png
|
|
||||||
sips -s format jpeg tmp.png --out output.jpg
|
|
||||||
```
|
|
||||||
|
|
||||||
## Serving Locally
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd "/Users/kyle/Desktop/kmtnflower shots"
|
python3 server.py # http://localhost:8899
|
||||||
|
# or, equivalently:
|
||||||
python3 -m http.server 8899
|
python3 -m http.server 8899
|
||||||
# Open http://localhost:8899
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Project Root
|
## Recapture a screenshot asset
|
||||||
|
|
||||||
```
|
`convert.py` turns a full-resolution `.png` into the 500px-wide JPEG used on the
|
||||||
/Users/kyle/Documents/kmtnflower/
|
showcase. Add file names to the `names` list at the top of the script, then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 convert.py
|
||||||
```
|
```
|
||||||
+31
-29
@@ -6,17 +6,19 @@
|
|||||||
<title>FlowerCMS — White-Label CMS for Broadcasters</title>
|
<title>FlowerCMS — White-Label CMS for Broadcasters</title>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--bg: #0a0a0a;
|
/* Theme: "On Air" — bright, high-energy broadcast. Vermillion + sky-cyan. */
|
||||||
--surface: #141414;
|
--bg: #fff8f5; /* warm off-white, not stark */
|
||||||
--card: #1a1a1a;
|
--surface: #fff2ea; /* faint coral wash for section bands */
|
||||||
--border: #2a2a2a;
|
--card: #ffffff;
|
||||||
--text: #e8e8e8;
|
--border: #f0e2d9;
|
||||||
--muted: #888;
|
--text: #1a1410; /* warm near-black */
|
||||||
--accent: #6366f1;
|
--muted: #6b6259;
|
||||||
--accent-light: #818cf8;
|
--accent: #f5333f; /* "on air" vermillion */
|
||||||
--accent-dark: #4f46e5;
|
--accent-light: #ff6b6b;
|
||||||
--success: #22c55e;
|
--accent-dark: #c81c2c;
|
||||||
--gradient: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%);
|
--cyan: #0ea5e9; /* sky-cyan secondary */
|
||||||
|
--success: #16a34a; /* "yes/online" green */
|
||||||
|
--gradient: linear-gradient(135deg, #ff5470 0%, #f5333f 40%, #0ea5e9 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
@@ -41,7 +43,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
background: rgba(10,10,10,0.8);
|
background: rgba(255,248,245,0.85);
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
padding: 16px 40px;
|
padding: 16px 40px;
|
||||||
@@ -78,7 +80,7 @@
|
|||||||
}
|
}
|
||||||
nav .cta:hover {
|
nav .cta:hover {
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 4px 20px rgba(99,102,241,0.4);
|
box-shadow: 0 4px 20px rgba(245,51,63,0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HERO */
|
/* HERO */
|
||||||
@@ -97,13 +99,13 @@
|
|||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
width: 600px;
|
width: 600px;
|
||||||
height: 600px;
|
height: 600px;
|
||||||
background: radial-gradient(circle, rgba(99,102,241,0.15) 0%, transparent 70%);
|
background: radial-gradient(circle, rgba(245,51,63,0.15) 0%, transparent 70%);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.hero .badge {
|
.hero .badge {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background: rgba(99,102,241,0.1);
|
background: rgba(245,51,63,0.1);
|
||||||
border: 1px solid rgba(99,102,241,0.3);
|
border: 1px solid rgba(245,51,63,0.3);
|
||||||
color: var(--accent-light);
|
color: var(--accent-light);
|
||||||
padding: 6px 16px;
|
padding: 6px 16px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
@@ -149,7 +151,7 @@
|
|||||||
}
|
}
|
||||||
.hero .btn-primary:hover {
|
.hero .btn-primary:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 8px 30px rgba(99,102,241,0.4);
|
box-shadow: 0 8px 30px rgba(245,51,63,0.4);
|
||||||
}
|
}
|
||||||
.hero .btn-secondary {
|
.hero .btn-secondary {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@@ -174,7 +176,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
box-shadow: 0 20px 60px rgba(0,0,0,0.5);
|
box-shadow: 0 20px 50px rgba(46,30,20,0.16);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FEATURES */
|
/* FEATURES */
|
||||||
@@ -252,7 +254,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: rgba(34,197,94,0.1);
|
background: rgba(22,163,74,0.12);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -260,7 +262,7 @@
|
|||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
box-shadow: 0 10px 40px rgba(0,0,0,0.3);
|
box-shadow: 0 10px 40px rgba(46,30,20,0.10);
|
||||||
}
|
}
|
||||||
.feature-image img {
|
.feature-image img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -310,7 +312,7 @@
|
|||||||
.grid-card .icon {
|
.grid-card .icon {
|
||||||
width: 44px;
|
width: 44px;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
background: rgba(99,102,241,0.1);
|
background: rgba(245,51,63,0.1);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -359,7 +361,7 @@
|
|||||||
}
|
}
|
||||||
.cta-section .btn-primary:hover {
|
.cta-section .btn-primary:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 8px 30px rgba(99,102,241,0.4);
|
box-shadow: 0 8px 30px rgba(245,51,63,0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FOOTER */
|
/* FOOTER */
|
||||||
@@ -445,7 +447,7 @@
|
|||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 1px solid rgba(255,255,255,0.1);
|
border: 1px solid rgba(0,0,0,0.08);
|
||||||
}
|
}
|
||||||
.showcase-card-body p {
|
.showcase-card-body p {
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
@@ -508,7 +510,7 @@
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 48px 40px;
|
padding: 48px 40px;
|
||||||
margin-bottom: 60px;
|
margin-bottom: 60px;
|
||||||
box-shadow: 0 0 60px rgba(99,102,241,0.15);
|
box-shadow: 0 0 60px rgba(245,51,63,0.15);
|
||||||
}
|
}
|
||||||
.pricing-header {
|
.pricing-header {
|
||||||
margin-bottom: 36px;
|
margin-bottom: 36px;
|
||||||
@@ -559,7 +561,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: rgba(34,197,94,0.1);
|
background: rgba(22,163,74,0.12);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -583,7 +585,7 @@
|
|||||||
}
|
}
|
||||||
.pricing-cta .btn-primary:hover {
|
.pricing-cta .btn-primary:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 8px 30px rgba(99,102,241,0.4);
|
box-shadow: 0 8px 30px rgba(245,51,63,0.4);
|
||||||
}
|
}
|
||||||
.pricing-cta .btn-contact {
|
.pricing-cta .btn-contact {
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
@@ -652,10 +654,10 @@
|
|||||||
}
|
}
|
||||||
.vs-col:last-child { border-right: none; }
|
.vs-col:last-child { border-right: none; }
|
||||||
.vs-col.live365 {
|
.vs-col.live365 {
|
||||||
background: rgba(255,255,255,0.02);
|
background: rgba(0,0,0,0.02);
|
||||||
}
|
}
|
||||||
.vs-col.flowercms {
|
.vs-col.flowercms {
|
||||||
background: rgba(99,102,241,0.05);
|
background: rgba(245,51,63,0.05);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.vs-col.highlight .yes {
|
.vs-col.highlight .yes {
|
||||||
@@ -725,7 +727,7 @@
|
|||||||
<p>White-label content management for small radio and internet broadcasters. Professional websites, custom branding, and native mobile apps — all from one dashboard.</p>
|
<p>White-label content management for small radio and internet broadcasters. Professional websites, custom branding, and native mobile apps — all from one dashboard.</p>
|
||||||
<div class="hero-cta">
|
<div class="hero-cta">
|
||||||
<a href="mailto:sales@flowercms.cloud" class="btn-primary">Contact Sales</a>
|
<a href="mailto:sales@flowercms.cloud" class="btn-primary">Contact Sales</a>
|
||||||
<button class="btn-secondary">See Demo</button>
|
<a href="mailto:sales@flowercms.cloud?subject=Demo%20request" class="btn-secondary">Book a Demo</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user