From dc0c2a75df1409222736db09a4bcb5f6e0309457 Mon Sep 17 00:00:00 2001 From: Timmy Date: Fri, 3 Apr 2026 21:03:54 +0100 Subject: [PATCH] Updated styles --- server/src/main.rs | 11 +- website/husky.svg | 34 ++++ website/index.html | 137 ++++++++++++---- website/style.css | 397 +++++++++++++++++++++++++++++++++++---------- 4 files changed, 457 insertions(+), 122 deletions(-) create mode 100644 website/husky.svg diff --git a/server/src/main.rs b/server/src/main.rs index 68bdb760..a728e04c 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -577,9 +577,14 @@ async fn main() -> Result<(), std::io::Error> { let host = std::env::var("HUSKIES_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); let addr = format!("{host}:{port}"); - println!( - "\x1b[95;1m ____ _ _ ___ _ \n / ___|| |_ ___ _ __| | _|_ _| |_ \n \\___ \\| __/ _ \\| '__| |/ /| || __|\n ___) | || (_) | | | < | || |_ \n |____/ \\__\\___/|_| |_|\\_\\___|\\__|\n\x1b[0m" - ); + println!("\x1b[96;1m"); + println!(" ╱▔▔╲ \x1b[97;1m _ _ _ _ \x1b[96;1m"); + println!(" ( ◕ ◕) \x1b[97;1m| | | |_ _ ___| | _(_) ___ ___\x1b[96;1m"); + println!(" ╲ ▽ ╱ \x1b[97;1m| |_| | | | / __| |/ / |/ _ \\/ __|\x1b[96;1m"); + println!(" /| |\\ \x1b[97;1m| _ | |_| \\__ \\ <| | __/\\__ \\\x1b[96;1m"); + println!(" / | | \\\x1b[97;1m|_| |_|\\__,_|___/_|\\_\\_|\\___||___/\x1b[96;1m"); + println!(" ╱╱ ╲╲ \x1b[90mStory-driven development, powered by AI\x1b[0m"); + println!(); println!("HUSKIES_PORT={port}"); println!("\x1b[96;1mFrontend:\x1b[0m \x1b[94mhttp://{addr}\x1b[0m"); println!("\x1b[92;1mOpenAPI Docs:\x1b[0m \x1b[94mhttp://{addr}/docs\x1b[0m"); diff --git a/website/husky.svg b/website/husky.svg new file mode 100644 index 00000000..295bba47 --- /dev/null +++ b/website/husky.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/index.html b/website/index.html index db8184f4..bafd041f 100644 --- a/website/index.html +++ b/website/index.html @@ -5,63 +5,142 @@ Huskies — Story-Driven Development for AI Agents + + + -
+
-
-

huskies

-

Story-driven development, powered by AI agents.

+ +
+ +
-
-

What is Huskies?

-

Huskies is an autonomous development pipeline that turns user stories into tested, shipped code. You describe what you want. AI agents handle the rest — implementation, testing, code review, and merge.

-

Talk to it from your IDE, a chat room, or WhatsApp. Stories flow through a structured pipeline: backlog, current, QA, merge, done.

+ +
+
+ +
+

Story-driven development

+

You describe it.
Agents ship it.

+

An autonomous development pipeline that turns user stories into tested, merged code. AI agents handle implementation, testing, and deployment — you keep the final say.

+ + +
+
+ + Story +
+ +
+ + Implement +
+ +
+ + QA +
+ +
+ + Merge +
+ +
+ + Done +
+
-
-

How it works

+ +
+

How it works

    -
  1. You write a user story with acceptance criteria.
  2. -
  3. An AI agent picks it up, creates a feature branch, and implements the code.
  4. -
  5. A QA agent runs tests, linters, and quality gates automatically.
  6. -
  7. A merge agent resolves conflicts and lands it on your main branch.
  8. -
  9. You review the result. Accept or send it back.
  10. +
  11. + 01 +
    +

    Write a story

    +

    Describe what you want with acceptance criteria. From your IDE, a chat room, or WhatsApp.

    +
    +
  12. +
  13. + 02 +
    +

    Agent picks it up

    +

    A coder agent creates a feature branch, implements the code, and writes tests against your criteria.

    +
    +
  14. +
  15. + 03 +
    +

    Quality gates run

    +

    Linters, tests, and compilation checks run automatically. Nothing moves forward until everything passes.

    +
    +
  16. +
  17. + 04 +
    +

    Merge & land

    +

    A merge agent resolves conflicts and squash-merges to your main branch. You review and accept.

    +
    +
-
-

Features

-
-
+ +
+

Features

+
+
+
+ +

Story-Driven Workflow

-

Stories define the change. Tests define the truth. Code defines the reality. No code ships without acceptance criteria.

+

Stories define the change. Tests define the truth. Code defines the reality. Nothing ships without acceptance criteria.

-
+
+
+ +

Multi-Agent Pipeline

Coder, QA, and merge agents work in parallel across isolated git worktrees. Configure agent count, models, and budgets.

-
+
+
+ +

Chat Anywhere

Control the pipeline from Matrix, WhatsApp, Slack, or the built-in web UI. Create stories, start agents, check status.

-
-

Full Autonomy, Your Oversight

+
+
+ +
+

Your Oversight

Agents implement, test, and merge independently. You approve what ships. Every story is traceable from request to release.

-
-

Get in touch

-

Huskies is built by Crashlabs. Interested in early access or have questions? Reach out at hello@huskies.dev.

+ +
+

Interested?

+

Huskies is built by Crash Labs. Get in touch at hello@huskies.dev.

-
diff --git a/website/style.css b/website/style.css index 04e45894..c927dc2e 100644 --- a/website/style.css +++ b/website/style.css @@ -1,140 +1,357 @@ :root { - --bg: #0a0a0a; - --fg: #e8e8e8; - --muted: #888; - --accent: #4f9cf7; - --surface: #141414; - --border: #222; - --max-w: 720px; + --bg: #080c15; + --surface: #0e1420; + --surface-hover: #131a28; + --border: #1a2235; + --text: #e8ecf4; + --text-secondary: #8892a8; + --text-dim: #4a5568; + --cyan: #22d3ee; + --cyan-dim: rgba(34, 211, 238, 0.07); + --cyan-glow: rgba(34, 211, 238, 0.15); + --display: 'Bricolage Grotesque', sans-serif; + --body: 'Karla', sans-serif; } * { margin: 0; padding: 0; box-sizing: border-box; } +html { scroll-behavior: smooth; } body { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-family: var(--body); background: var(--bg); - color: var(--fg); + color: var(--text); line-height: 1.6; + min-height: 100vh; + overflow-x: hidden; -webkit-font-smoothing: antialiased; } -a { color: var(--accent); text-decoration: none; } -a:hover { text-decoration: underline; } +a { color: var(--cyan); text-decoration: none; transition: opacity 0.2s; } +a:hover { opacity: 0.7; } -.container { - max-width: var(--max-w); +/* Animations */ +@keyframes fadeUp { + from { opacity: 0; transform: translateY(18px); } + to { opacity: 1; transform: translateY(0); } +} +@keyframes pulse { + 0%, 100% { box-shadow: 0 0 0 0 var(--cyan-glow); } + 50% { box-shadow: 0 0 12px 4px var(--cyan-glow); } +} + +.reveal { + opacity: 0; + animation: fadeUp 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards; +} +.r1 { animation-delay: 0.05s; } +.r2 { animation-delay: 0.15s; } +.r3 { animation-delay: 0.3s; } +.r4 { animation-delay: 0.5s; } +.r5 { animation-delay: 0.65s; } +.r6 { animation-delay: 0.8s; } +.r7 { animation-delay: 0.95s; } +.r8 { animation-delay: 1.1s; } + +/* Layout */ +.page { + max-width: 960px; margin: 0 auto; - padding: 0 24px; + padding: 0 3rem; } -/* ── Header ── */ +@media (max-width: 640px) { + .page { padding: 0 1.5rem; } +} + +/* Header */ header { - padding: 48px 0 32px; - border-bottom: 1px solid var(--border); + padding: 2rem 0; + display: flex; + justify-content: space-between; + align-items: center; } -header h1 { - font-size: 2rem; - font-weight: 700; - letter-spacing: -0.03em; -} - -header h1 span { color: var(--accent); } - -header p.tagline { - color: var(--muted); +.logo { + font-family: var(--display); font-size: 1.1rem; - margin-top: 8px; + font-weight: 800; + letter-spacing: -0.03em; + color: var(--text) !important; } -/* ── Sections ── */ -section { - padding: 48px 0; - border-bottom: 1px solid var(--border); +header nav { + display: flex; + align-items: center; + gap: 2rem; } -section:last-of-type { border-bottom: none; } +header nav a { + font-size: 0.82rem; + color: var(--text-dim); +} -section h2 { - font-size: 1.25rem; +header nav a:hover { color: var(--text); opacity: 1; } + +.nav-cta { + color: var(--cyan) !important; + font-weight: 500; +} + +/* Hero */ +.hero { + padding: 10vh 0 6vh; + text-align: center; +} + +.hero-graphic { + margin-bottom: 2.5rem; +} + +.hero-husky { + width: 120px; + height: 120px; + filter: drop-shadow(0 0 20px rgba(34, 211, 238, 0.1)); +} + +.hero-kicker { + font-family: var(--display); + font-size: 0.7rem; font-weight: 600; - margin-bottom: 16px; - letter-spacing: -0.02em; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--cyan); + margin-bottom: 2rem; } -section p { color: var(--muted); margin-bottom: 12px; } +.hero h1 { + font-family: var(--display); + font-size: clamp(2.5rem, 6vw, 4.2rem); + font-weight: 800; + line-height: 1.1; + letter-spacing: -0.03em; + margin-bottom: 1.8rem; + max-width: 700px; + margin-left: auto; + margin-right: auto; +} -/* ── Feature grid ── */ -.features { +.glow { + color: var(--cyan); + text-shadow: 0 0 30px var(--cyan-glow); +} + +.hero-sub { + font-size: 1.05rem; + font-weight: 300; + color: var(--text-secondary); + line-height: 1.8; + max-width: 520px; + margin: 0 auto; +} + +/* Pipeline visualisation */ +.pipeline { + display: flex; + align-items: center; + justify-content: center; + gap: 0; + margin-top: 4rem; + padding: 2rem 0; +} + +.pipe-stage { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.8rem; +} + +.pipe-dot { + width: 12px; + height: 12px; + border-radius: 50%; + border: 2px solid var(--border); + background: var(--surface); + transition: all 0.3s; +} + +.pipe-dot.active { + border-color: var(--cyan); + background: var(--cyan); + animation: pulse 2s ease-in-out infinite; +} + +.pipe-dot.done { + border-color: var(--text-dim); + background: var(--text-dim); +} + +.pipe-label { + font-family: var(--display); + font-size: 0.65rem; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--text-dim); +} + +.pipe-stage:has(.active) .pipe-label { + color: var(--cyan); +} + +.pipe-line { + width: 60px; + height: 1px; + background: var(--border); + margin: 0 0.5rem; + margin-bottom: 2rem; +} + +@media (max-width: 500px) { + .pipe-line { width: 30px; } + .pipe-label { font-size: 0.55rem; } +} + +/* Sections */ +.section-title { + font-family: var(--display); + font-size: 1.6rem; + font-weight: 700; + letter-spacing: -0.02em; + margin-bottom: 2.5rem; +} + +/* How it works */ +.how-section { + padding: 5rem 0; + border-top: 1px solid var(--border); +} + +.steps { + list-style: none; + display: flex; + flex-direction: column; + gap: 0; +} + +.step { + display: grid; + grid-template-columns: 56px 1fr; + gap: 1.5rem; + padding: 1.8rem 0; + border-bottom: 1px solid var(--border); + align-items: start; +} + +.step:first-child { + border-top: 1px solid var(--border); +} + +.step-num { + font-family: var(--display); + font-size: 0.75rem; + font-weight: 700; + color: var(--text-dim); + padding-top: 0.15rem; +} + +.step-body h3 { + font-family: var(--display); + font-size: 1rem; + font-weight: 600; + margin-bottom: 0.4rem; +} + +.step-body p { + font-size: 0.88rem; + font-weight: 300; + color: var(--text-secondary); + line-height: 1.7; +} + +/* Features */ +.features-section { + padding: 5rem 0; + border-top: 1px solid var(--border); +} + +.feature-grid { display: grid; grid-template-columns: 1fr 1fr; - gap: 24px; - margin-top: 16px; + gap: 1px; + background: var(--border); + border: 1px solid var(--border); } .feature { background: var(--surface); - border: 1px solid var(--border); - border-radius: 8px; - padding: 20px; + padding: 2rem; + transition: background 0.3s; +} + +.feature:hover { + background: var(--surface-hover); +} + +.feature-icon { + color: var(--cyan); + margin-bottom: 1.2rem; + opacity: 0.8; } .feature h3 { + font-family: var(--display); font-size: 0.95rem; font-weight: 600; - margin-bottom: 6px; + margin-bottom: 0.5rem; } .feature p { - font-size: 0.875rem; - color: var(--muted); - margin: 0; + font-size: 0.82rem; + font-weight: 300; + color: var(--text-secondary); + line-height: 1.7; } -/* ── How it works ── */ -.steps { - list-style: none; - counter-reset: step; - margin-top: 16px; +@media (max-width: 600px) { + .feature-grid { grid-template-columns: 1fr; } } -.steps li { - counter-increment: step; - padding: 12px 0; - padding-left: 36px; - position: relative; - color: var(--muted); - font-size: 0.95rem; -} - -.steps li::before { - content: counter(step); - position: absolute; - left: 0; - top: 12px; - width: 24px; - height: 24px; - background: var(--surface); - border: 1px solid var(--border); - border-radius: 50%; - font-size: 0.75rem; - font-weight: 600; - display: flex; - align-items: center; - justify-content: center; - color: var(--accent); -} - -/* ── Footer ── */ -footer { - padding: 32px 0; - color: var(--muted); - font-size: 0.8rem; +/* CTA */ +.cta-section { + padding: 5rem 0; + border-top: 1px solid var(--border); text-align: center; } -/* ── Responsive ── */ -@media (max-width: 540px) { - .features { grid-template-columns: 1fr; } - header h1 { font-size: 1.5rem; } +.cta-section h2 { + font-family: var(--display); + font-size: 1.8rem; + font-weight: 700; + letter-spacing: -0.02em; + margin-bottom: 1rem; } + +.cta-section p { + font-size: 0.95rem; + color: var(--text-secondary); + font-weight: 300; +} + +/* Footer */ +footer { + padding: 2rem 0; + border-top: 1px solid var(--border); + display: flex; + justify-content: space-between; + align-items: center; + font-size: 0.75rem; + color: var(--text-dim); +} + +footer a { + color: var(--text-dim); + font-size: 0.75rem; +} + +footer a:hover { color: var(--text-secondary); }