Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,21 @@ complete.

Use [FTW's vision](https://github.com/srcfl/ftw/blob/master/VISION.md) and
[roadmap](https://github.com/srcfl/ftw/blob/master/docs/roadmap.md) when writing product copy.
Explain mixed-equipment coordination, simple defaults, local control and
visible outcomes. Clearly distinguish implemented capabilities from goals
such as cloud MCP. Do not publish predicted savings as measured results.
Explain FTW as a fast local energy core for people, agents and other software.
Show the current iPhone beta, webapp, Home Assistant app and ChatGPT integration.
Keep preview integrations and planned features distinct from public releases.
Do not publish predicted savings as measured results.

Product screenshots come from the public FTW webapp demo. Label them as
simulated data. They show the interface, not measured savings or a worker
benchmark. Keep their dimensions in HTML in step with the image files.
Product screenshots show the complete app viewport, without cropping or
changing the interface. Use the public webapp demo and the iOS app's built-in
demo. Label simulated homes. These show the interface, not measured savings
or a worker benchmark. Keep HTML dimensions in step with the image files.

Current images: `assets/ftw-webapp-now.webp` comes from the public demo at
430 × 932 CSS pixels; `assets/ftw-ios-now.webp` comes from the iPhone 17 Pro
simulator, built from `srcfl/ftw-app` commit `4448968`. Both use simulated data.
`home.css` holds homepage styles; the shared stylesheet also serves the
support, privacy and ChatGPT pages.

Sourceful maintains the product; Fredrik owns its direction. PRs are welcome,
preferably based on [issues](https://github.com/srcfl/ftw-web/issues). Share a
Expand All @@ -44,6 +52,14 @@ physical SD-card swap before install commands. Present same-host Docker as a
separate option for people who can manage its services, not the next step
after a failed native install.

## Public entry points

- iPhone beta: https://testflight.apple.com/join/E4Japad7
- Webapp and interactive demo: https://app.ftw.energy/
- Home Assistant app: https://github.com/srcfl/ftw/blob/master/docs/home-assistant-app.md
- ChatGPT integration and its availability: `/chatgpt`
- Anonymous project statistics: https://stats.ftw.energy/

## Local dev

```bash
Expand Down
Binary file added assets/ftw-ios-now.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/ftw-webapp-now.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
152 changes: 152 additions & 0 deletions home.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
.home { --max: 1280px; }
.home section[id], .home article[id] { scroll-margin-top: 88px; }
.home h1 { font-size: clamp(3.3rem, 5.3vw, 5.4rem); line-height: 1.02; letter-spacing: -.045em; }
.home h2 { font-size: clamp(2.5rem, 4.5vw, 4.5rem); line-height: 1.06; letter-spacing: -.035em; }
.home h3 { letter-spacing: -.02em; }
.home .section-kicker, .home .cap-number { font-size: 11px; }
.home .hero-layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 64px; min-height: auto; padding-block: 76px 52px; }
.home .hero-lede { max-width: 500px; font-size: 20px; line-height: 1.55; }
.home .project-state { font-size: 11px; letter-spacing: .1em; }
.hero-footnote { margin: 24px 0 0; color: var(--muted); font-size: 14px; }
.hero-footnote a { color: var(--ink); text-underline-offset: 4px; text-decoration-color: var(--signal); }
.hero-facts { display: flex; flex-wrap: wrap; gap: 12px 20px; margin-top: 36px; padding-top: 20px; border-top: 1px solid var(--line); color: var(--muted); font-size: 12px; }
.app-pair { display: grid; grid-template-columns: 1fr 1fr; align-items: start; gap: 20px; max-width: 510px; justify-self: end; }
.app-pair figure { margin: 0; min-width: 0; }
.app-pair figure:nth-child(2) { padding-top: 42px; }
.app-pair figure > a { display: block; }
.app-pair img { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: 18px; background: var(--ink); }
.app-pair figcaption { padding-top: 16px; color: var(--muted); font-size: 13px; }
.app-pair figcaption span { display: block; margin-bottom: 4px; color: var(--ink); font: 10px 'JetBrains Mono', monospace; letter-spacing: .06em; }
.image-note { grid-column: 1 / -1; margin: 0; color: var(--muted); font-size: 11px; }
.product-routes { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--line); }
.product-routes a { position: relative; padding: 24px 32px 26px 0; text-decoration: none; font-size: 14px; }
.product-routes a + a { padding-left: 24px; border-left: 1px solid var(--line); }
.product-routes a:hover { color: var(--signal); }
.product-routes span { display: block; margin-bottom: 6px; color: var(--muted); font: 10px 'JetBrains Mono', monospace; letter-spacing: .08em; text-transform: uppercase; }
.product-routes b { position: absolute; right: 20px; top: 45px; color: var(--signal); font-weight: 400; }
.story-heading { display: grid; grid-template-columns: 1fr 2fr; gap: 64px; margin-bottom: 56px; }
.story-heading .section-kicker { margin-top: 12px; }
.story-heading h2 { margin-bottom: 28px; }
.story-heading .section-intro { max-width: 660px; margin-bottom: 0; }
.core-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; }
.core-steps article { padding-top: 24px; border-top: 1px solid var(--line); }
.core-steps h3 { margin: 24px 0 14px; font-size: 24px; font-weight: 500; }
.core-steps p { margin-bottom: 0; color: var(--muted); }
.core-links { display: flex; flex-wrap: wrap; gap: 16px 32px; padding-top: 36px; }
.core-links a, .agent-contract a { text-decoration-color: var(--signal); text-underline-offset: 5px; font-size: 14px; }
.ai-story { background: var(--ink); color: var(--cream); }
.ai-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 100px; }
.ai-story h2 { color: var(--cream); }
.ai-layout > div > p:not(.section-kicker):not(.availability) { max-width: 540px; color: rgba(245,242,225,.74); }
.ai-lede { font-size: 20px; line-height: 1.55; }
.ai-story .btn { margin-top: 16px; }
.availability { margin: 18px 0 0; color: rgba(245,242,225,.56); font-size: 12px; }
.agent-examples { padding-top: 6px; }
.example-label { margin-bottom: 24px; color: rgba(245,242,225,.5); font: 11px 'JetBrains Mono', monospace; letter-spacing: .1em; }
.agent-examples ul { padding: 0; margin: 0; list-style: none; }
.agent-examples li { padding: 21px 0; border-top: 1px solid var(--line-dark); font-size: clamp(19px, 1.8vw, 25px); font-weight: 400; line-height: 1.4; }
.agent-examples li:last-child { border-bottom: 1px solid var(--line-dark); }
.agent-contract { padding-top: 32px; }
.agent-contract h3 { margin-bottom: 12px; color: var(--cream); font-size: 22px; font-weight: 500; }
.agent-contract p { color: rgba(245,242,225,.64); }
.ai-privacy { display: flex; flex-wrap: wrap; gap: 8px 20px; margin-top: 48px; padding-top: 20px; border-top: 1px solid var(--line-dark); color: rgba(245,242,225,.56); font-size: 12px; }
.ai-privacy a { text-underline-offset: 4px; }
.app-details { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; }
.app-details article { padding-top: 24px; border-top: 1px solid var(--line); }
.app-details h3 { margin: 24px 0 16px; font-size: 28px; line-height: 1.2; font-weight: 500; }
.app-details p:not(.cap-number):not(.small-note) { max-width: 510px; color: var(--muted); }
.small-note { color: var(--muted); font-size: 13px; }
.app-details .small-note { margin: 22px 0 0; }
.home .text-link { white-space: normal; }
.plan-story { background: var(--cream); }
.plan-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; gap: 100px; }
.plan-layout h2 { margin-bottom: 28px; }
.plan-layout .check-list { margin-top: 28px; }
.plan-layout .product-note { font-size: 14px; }
.install-options { display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--line); }
.install-options article { padding: 36px 48px 24px 0; }
.install-options article + article { padding-left: 48px; border-left: 1px solid var(--line); }
.install-options h3 { margin: 28px 0 18px; font-size: 30px; font-weight: 500; }
.install-options article > p:not(.small-note) { max-width: 480px; color: var(--muted); }
.install-options .btn { margin-top: 12px; }
.install-options .small-note { margin: 18px 0 0; }
.install-notes { margin-top: 32px; padding-top: 20px; border-top: 1px solid var(--line); color: var(--muted); font-size: 14px; }
.install-notes a { text-decoration-color: var(--signal); text-underline-offset: 4px; }
.install-notes summary { cursor: pointer; color: var(--ink); }
.install-notes details p { max-width: 800px; margin-top: 16px; }
.community-story { background: var(--cream); }
.community-row { display: grid; grid-template-columns: 1fr 1fr; gap: 100px; }
.community-row h2 { margin-bottom: 0; }
.community-row > div:last-child > p:first-child { color: var(--muted); font-size: 18px; }
.community-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 22px; margin: 30px 0; }
.community-actions > a:not(.btn) { font-size: 14px; text-decoration-color: var(--signal); text-underline-offset: 4px; }
.community-row .small-note { line-height: 1.65; margin-bottom: 0; }
.home .footer-main { grid-template-columns: 1fr 1.6fr; gap: 64px; }
.home .footer-links { gap: 32px; }
.home .footer-links a { min-height: 32px; }

@media (max-width: 1100px) {
.home .hero-layout { gap: 36px; }
.home h1 { font-size: clamp(3.1rem, 5.3vw, 4.4rem); }
.home .hero-lede { font-size: 18px; }
.app-pair { gap: 14px; }
.story-heading { gap: 40px; }
.ai-layout, .plan-layout, .community-row { gap: 56px; }
}
@media (max-width: 860px) {
.home .hero-layout { display: grid; grid-template-columns: 1fr; padding-block: 52px 36px; gap: 44px; }
.home h1 { max-width: 700px; font-size: clamp(3.5rem, 9vw, 5.2rem); }
.home .hero-lede { max-width: 600px; }
.hero-facts { margin-top: 28px; }
.app-pair { max-width: 500px; justify-self: center; gap: 20px; }
.product-routes { grid-template-columns: 1fr 1fr; }
.product-routes a { border-bottom: 1px solid var(--line); }
.product-routes a:nth-child(3) { padding-left: 0; border-left: 0; }
.story-heading { grid-template-columns: 1fr; gap: 8px; margin-bottom: 40px; }
.story-heading .section-kicker { margin-top: 0; }
.core-steps { gap: 24px; }
.core-steps h3 { font-size: 21px; }
.ai-layout { grid-template-columns: 1fr; gap: 48px; }
.ai-layout > div > p:not(.section-kicker):not(.availability) { max-width: 650px; }
.agent-examples { padding-top: 0; }
.app-details { gap: 32px; }
.plan-layout { grid-template-columns: 1fr 1fr; gap: 36px; }
.plan-layout h2 { font-size: 2.8rem; }
.install-options article { padding-right: 28px; }
.install-options article + article { padding-left: 28px; }
.install-options h3 { font-size: 25px; }
.community-row, .home .footer-main { grid-template-columns: 1fr; gap: 40px; }
}
@media (max-width: 600px) {
.home .hero-layout { padding-top: 42px; }
.home h1 { font-size: clamp(2.95rem, 11.8vw, 4.1rem); }
.home h2 { font-size: clamp(2.3rem, 9vw, 3.2rem); }
.home .hero-actions .btn { flex: 0 1 auto; }
.hero-footnote { line-height: 1.7; }
.hero-footnote a { display: inline; }
.hero-facts { font-size: 11px; gap: 10px 14px; }
.app-pair { gap: 12px; width: 100%; }
.app-pair figure:nth-child(2) { padding-top: 28px; }
.app-pair img { border-radius: 10px; }
.app-pair figcaption { font-size: 11px; line-height: 1.5; padding-top: 12px; }
.app-pair figcaption span { font-size: 9px; }
.image-note { font-size: 10px; }
.product-routes a { padding-block: 20px; font-size: 12px; }
.product-routes a + a { padding-left: 16px; }
.product-routes a:nth-child(3) { padding-left: 0; }
.product-routes b { right: 10px; top: 42px; }
.product-routes span { font-size: 9px; }
.core-steps, .app-details, .plan-layout, .install-options { grid-template-columns: 1fr; }
.core-steps { gap: 28px; }
.core-steps h3 { margin-top: 18px; font-size: 23px; }
.ai-lede { font-size: 18px; }
.ai-privacy { margin-top: 32px; }
.app-details { gap: 40px; }
.app-details h3 { font-size: 25px; }
.plan-layout { gap: 40px; }
.install-options article, .install-options article + article { padding: 28px 0; border-left: 0; }
.install-options article + article { border-top: 1px solid var(--line); }
.install-options h3 { margin-top: 22px; }
.community-actions { gap: 20px; }
.home .footer-links { grid-template-columns: 1fr 1fr; gap: 36px 20px; }
}
Loading