From 691cebbfeed90abb05b3c21682cef25836a946c3 Mon Sep 17 00:00:00 2001 From: "user.email" Date: Fri, 3 Apr 2026 08:09:52 -0700 Subject: [PATCH 1/2] Add color vars and redesign hero section --- web/index.html | 228 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 169 insertions(+), 59 deletions(-) diff --git a/web/index.html b/web/index.html index b3cb60c..a7bcac5 100644 --- a/web/index.html +++ b/web/index.html @@ -18,6 +18,9 @@ --accent: #1a7f37; --code-bg: #f5f5f5; --border: #ddd; + --yellow: #9a7200; + --install-bg: #f0faf2; + --install-border: #c5e4cc; } @media (prefers-color-scheme: dark) { @@ -31,83 +34,172 @@ --accent: #4ec966; --code-bg: #111; --border: #222; + --yellow: #e5b567; + --install-bg: #0d1a10; + --install-border: #1a3d20; } } - html { font-size: 16px; } - body { background: var(--bg); color: var(--fg); font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', 'JetBrains Mono', 'Menlo', 'Consolas', monospace; line-height: 1.6; - padding: 0 1.5rem; - max-width: 680px; + padding: 0 24px; + max-width: 900px; margin: 0 auto; -webkit-font-smoothing: antialiased; } + /* ---- Hero ---- */ header { - padding: 6rem 0 2.5rem; + padding: 64px 0 0; } h1 { - font-size: 2.5rem; - font-weight: 700; + font-size: 64px; + font-weight: 800; color: var(--bright); - letter-spacing: -0.03em; + letter-spacing: -0.04em; + line-height: 1; + display: flex; + align-items: baseline; } - h1 span { + h1 .dollar { color: var(--accent); + margin-right: 10px; } - .tagline { - font-size: 1.1rem; + + .subtitle { + font-size: 20px; color: var(--dim); - margin-top: 0.5rem; + margin-top: 8px; + font-weight: 400; } + /* ---- Install ---- */ .install { - margin-top: 2rem; - display: inline-block; + margin-top: 32px; + display: flex; + align-items: center; + justify-content: space-between; + background: var(--install-bg); + border: 1px solid var(--install-border); + padding: 11px 11px 11px 19px; + border-radius: 8px; + font-size: 14px; + color: var(--bright); + } + + .install code { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .install .prompt { color: var(--dim); } + .install .cmd { color: var(--bright); } + + .copy-btn { + background: var(--accent); + color: #fff; + border: none; + padding: 7px 14px; + border-radius: 5px; + font-family: inherit; + font-size: 12px; + font-weight: 600; + cursor: pointer; + white-space: nowrap; + transition: opacity 0.15s; + flex-shrink: 0; + margin-left: 16px; + } + + @media (prefers-color-scheme: dark) { + .copy-btn { color: #0a0a0a; } + } + + .copy-btn:hover { + opacity: 0.85; + } + + /* ---- "Write a test" box ---- */ + .hero-section { + padding: 40px 0 24px; + } + + .write-box { background: var(--code-bg); border: 1px solid var(--border); - padding: 0.6rem 1.2rem; - border-radius: 4px; - font-size: 0.9rem; - color: var(--bright); - cursor: pointer; - position: relative; - transition: border-color 0.15s; + border-radius: 8px; + padding: 20px; + padding-top: 16px; } - .install:hover { - border-color: var(--accent); + .two-col { + display: grid; + grid-template-columns: 1fr 1.4fr; + gap: 32px; + align-items: start; } - .install .hint { - color: var(--dim); - font-size: 0.75rem; - margin-left: 1rem; + .two-col .explain h2 { + margin-bottom: 16px; + color: var(--fg); } + .two-col .explain p { + margin-bottom: 14px; + font-size: 15px; + } + + .two-col .explain .feature { + margin-bottom: 11px; + font-size: 14px; + } + + .two-col .explain .feature code { + padding: 2px 6px; + border-radius: 3px; + font-size: 13px; + } + + .write-box pre { + background: var(--bg); + margin-bottom: 0; + } + + @media (max-width: 680px) { + .two-col { + grid-template-columns: 1fr; + gap: 24px; + } + .write-box { + padding: 19px; + } + } + + /* ---- Sections ---- */ section { - padding: 0 0 2em 0; + padding: 0 0 32px 0; } h2 { - font-size: 0.85rem; + font-size: 13px; font-weight: 600; color: var(--dim); text-transform: uppercase; letter-spacing: 0.1em; - margin-bottom: 1.5rem; + margin-bottom: 24px; } + p { - margin-bottom: 1rem; - font-size: 0.95rem; + margin-bottom: 16px; + font-size: 15px; } .bright { color: var(--bright); } @@ -118,19 +210,19 @@ pre { background: var(--code-bg); border: 1px solid var(--border); - border-radius: 4px; - padding: 1.2rem 1.4rem; + border-radius: 6px; + padding: 19px 22px; overflow-x: auto; - font-size: 0.85rem; + font-size: 13px; line-height: 1.7; - margin-bottom: 1.5rem; + margin-bottom: 24px; } pre code { color: var(--fg); } - .prompt { color: var(--dim); } + .prompt { color: var(--yellow); } .cmd { color: var(--bright); } .output { color: var(--fg); } .comment { color: var(--dim); font-style: italic; } @@ -138,12 +230,11 @@ .exit-code { color: var(--red); } .pass { color: var(--green); } - footer { - padding: 3rem 0; + padding: 48px 0; border-top: 1px solid var(--border); color: var(--dim); - font-size: 0.8rem; + font-size: 13px; } footer a { @@ -165,27 +256,38 @@ } @media (max-width: 520px) { - header { padding: 3rem 0 2rem; } - h1 { font-size: 2rem; } - section { padding: 2rem 0; } + header { padding: 40px 0 0; } + h1 { font-size: 44px; } + .subtitle { font-size: 16px; } + section { padding: 24px 0; } }
-

$ shout

-

shell output tester

-
- $ curl -fsSL https://because.sh/shout | sh - click to copy +

$shout

+

shell output tester

+
+ $ curl -fsSL https://because.sh/shout | sh +
-
-

Write a test

-

A .shout file is just a shell session. Commands start with $, everything else is expected output.

-
$ echo hello
+
+
+
+
+

✓ Write a test

+

A .shout file is a shell session.

+

Commands start with $.

+

Everything else is the expected output.

+

... matches anything — inline or across lines.

+

[1] asserts the exit code. Default expects 0.

+

Lines starting with # are comments.

+
+
+
$ echo hello
 hello
 
 $ ls missing
@@ -193,16 +295,16 @@
 [1]
 
 $ brew --version
-Homebrew 5...
-

... matches anything — inline or across lines.

-

[1] asserts the exit code.

-

$# starts a comment line — not executed, no output expected.

-
$# start the server
+Homebrew 5...
+
+# start the server
 $ my-server &
-$# now test it
 $ curl localhost:8080
 OK
-
+ + + +

Setup & teardown

@@ -281,5 +383,13 @@ Options: GitHub · npm + + From 6fe643bf1953dcc6d5c542282ac6ce9883e9e28b Mon Sep 17 00:00:00 2001 From: "user.email" Date: Fri, 3 Apr 2026 09:59:08 -0700 Subject: [PATCH 2/2] Refactor sections to use consistent box styling --- web/index.html | 131 ++++++++++++++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 51 deletions(-) diff --git a/web/index.html b/web/index.html index a7bcac5..6a254dd 100644 --- a/web/index.html +++ b/web/index.html @@ -11,7 +11,7 @@ :root { --bg: #fff; --fg: #444; - --bright: #1a1a1a; + --bright: #000; --green: #1a7f37; --red: #cf222e; --dim: #888; @@ -64,6 +64,7 @@ line-height: 1; display: flex; align-items: baseline; + vertical-align: baseline; } h1 .dollar { @@ -126,17 +127,14 @@ opacity: 0.85; } - /* ---- "Write a test" box ---- */ - .hero-section { - padding: 40px 0 24px; - } - - .write-box { + /* ---- Section boxes ---- */ + .section-box { background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; padding: 20px; padding-top: 16px; + margin-bottom: 24px; } .two-col { @@ -148,7 +146,6 @@ .two-col .explain h2 { margin-bottom: 16px; - color: var(--fg); } .two-col .explain p { @@ -162,41 +159,48 @@ } .two-col .explain .feature code { - padding: 2px 6px; + padding: 2px 0px; border-radius: 3px; font-size: 13px; } - .write-box pre { + .section-box pre { background: var(--bg); margin-bottom: 0; } + .section-box pre + pre { + margin-top: 12px; + } + + .section-box p:last-child { + margin-bottom: 0; + } + @media (max-width: 680px) { .two-col { grid-template-columns: 1fr; gap: 24px; } - .write-box { + .section-box { padding: 19px; } } - /* ---- Sections ---- */ - section { - padding: 0 0 32px 0; - } - h2 { font-size: 13px; font-weight: 600; - color: var(--dim); + color: var(--fg); text-transform: uppercase; letter-spacing: 0.1em; - margin-bottom: 24px; + margin-bottom: 16px; } + section { + padding: 0 0 32px 0; + } + p { margin-bottom: 16px; font-size: 15px; @@ -259,7 +263,6 @@ header { padding: 40px 0 0; } h1 { font-size: 44px; } .subtitle { font-size: 16px; } - section { padding: 24px 0; } } @@ -274,17 +277,18 @@ -
-
+
+

✓ Write a test

-

A .shout file is a shell session.

-

Commands start with $.

-

Everything else is the expected output.

+

Each .shout file is a session.

+

Commands start with $.

+

Everything else is expected output.

... matches anything — inline or across lines.

[1] asserts the exit code. Default expects 0.

Lines starting with # are comments.

+

(\# matches output starting with #.)

$ echo hello
@@ -306,43 +310,68 @@
   
-
-

Setup & teardown

-

Use @setup to share commands across test files. Use @teardown to clean up after tests — it runs regardless of pass/fail.

-
# setup.shout
+
+
+
+

✓ Setup & teardown

+

Use @setup to share commands across test files.

+

Use @teardown to clean up after tests — it runs regardless of pass/fail.

+

@teardown can appear in both .shout files and setup files. Teardown failures produce warnings but don't affect test results.

+
+
+
# setup.shout
 export DB_URL=sqlite:data/test.db
 @teardown rm -f "$SHOUT_PROJECT_DIR/data/test.db"
-
@setup setup.shout
+      
@setup setup.shout
 @teardown rm -f /tmp/extra-cleanup
 
 $ create-db && run-tests
 ...
-

@teardown can appear in both .shout files and setup files. Teardown failures produce warnings but don't affect test results.

-
+
+
+
-
-

Macros

-

Use @def to define reusable command macros.

-
@def greet echo "hello world"
+
+
+
+

✓ Macros

+

Use @def to define reusable command macros.

+

If a command matches a macro name exactly, the body is substituted. Use \ for multi-line bodies. Macros from setup files are inherited; user-file macros override them.

+
+
+
@def greet echo "hello world"
 
 $ greet
 hello world
-

If a command matches a macro name exactly, the body is substituted. Use \ for multi-line bodies — the body can start on the same line or on the next continuation line. Macros from setup files are inherited; user-file macros override them.

-
+
+ + -
-

Run it

-
$ shout test
+
+
+
+

✓ Run it

+

Each file gets a fresh temp directory and its own /bin/sh session. State carries between commands within a file.

+
+
+
$ shout test
 ...............
 15 passed in 23ms
-

Each file gets a fresh temp directory and its own /bin/sh session. State carries between commands within a file.

-
+ + + -
-

Update expectations

-
$ shout test --update
-

Rewrites your .shout files with the actual output. No more copy-pasting from the terminal.

-
+
+
+
+

✓ Update expectations

+

Rewrites your .shout files with the actual output. No more copy-pasting from the terminal.

+
+
+
$ shout test --update
+
+
+

Usage

@@ -370,12 +399,12 @@ Options:

Environment

Shout sets these variables before running your commands:

-
HOME       temp directory for this test file
-SHOUT_DIR       same temp directory
+  
HOME               temp directory for this test file
+SHOUT_DIR          same temp directory
 SHOUT_SOURCE_DIR   directory containing the .shout file
 SHOUT_PROJECT_DIR  directory where shout was invoked
-PORT            auto-assigned from 5400 (or --port-from), increments per file
-PATH            prepended with --path dirs, if any
+PORT auto-assigned from 5400 (or --port-from), increments per file +PATH prepended with --path dirs, if any

Each file runs in its own temp directory. --clean-env starts with an empty environment instead of inheriting yours.