Skip to content

W1.5: landing layout converged on demo-1 (hero band, alignment, section rhythm) - #429

Merged
pftg merged 3 commits into
masterfrom
course-landing-demo1-layout
Aug 1, 2026
Merged

W1.5: landing layout converged on demo-1 (hero band, alignment, section rhythm)#429
pftg merged 3 commits into
masterfrom
course-landing-demo1-layout

Conversation

@pftg

@pftg pftg commented Aug 1, 2026

Copy link
Copy Markdown
Member

Paul's feedback on the merged W1 page: "looks terrible, some parts modern, some parts not. Content is not aligned with the hero part." This wave fixes the three root causes, layout-only - zero copy changes.

Root causes → fixes

  • Hero had no weight → full-bleed ruby-tint band (rgba(204,52,45,.05)), 1080px two-col grid, H1 clamp 44-64px, and the spec-§4 obsidian course-window card: 48px chrome bar + mac dots, JetBrains-Mono ruby "FREE COURSE" eyebrow, 2-line white title "Idea to First Paying Customer" (sanctioned H1 variant, the only copy addition), mono meta "5 modules · 25 lessons".
  • Content misaligned with hero → one centered 1080px container for every section; prose keeps a 720px measure anchored to the container's left edge, so hero-left == heading-left == grid-left. Component grids span the full track.
  • Mixed eras → section-band rhythm (white → #FAFAFA full-bleed band around Module map → white → obsidian endcap island), H2s clamp 32-40 Space Grotesk, ~80px spacing, eyebrows gray-400 with ruby reserved for hero card/CTAs/mistake numerals.

Evidence

  • Before: docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.26-result-full.jpeg | After: 40.27-w15-result-full.jpeg | Reference: 40.26-reference-demo1-full.jpeg
  • 4-criteria visual scores 4×YES per changed region at 1280 AND 390 (card kept on mobile, stacked below CTAs); zero console errors, zero 404s, no horizontal scroll.

Gates

  • qtest green per commit (C1: 1 run; C2: 3 runs, 8 screenshots, no failures); hugo-build green; landing→lesson expander click-through green; macos landing baselines re-recorded in-commit.
  • All 8 anchors verified in DOM, stub H2s byte-identical, Mia + mistake deep links visible, zero JS, scope = layouts/course/list.html + course-list.css + _index.md wrapper hooks only.
  • Honest bin/dtest (main checkout, detached at tip): running - result lands as a comment before merge.

Known deferred (recorded): gradient H1 line (template doesn't own the line break), section-order interleave vs demo (order was W1-contracted, out of scope here).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Redesigned the course landing page with a full-width hero, course summary window, and clearer module and lesson details.
    • Added a dedicated module map section with improved visual separation and responsive layout.
    • Added updated typography, responsive two-column presentation, and refreshed calls to action.
  • Style

    • Refined article spacing, content width, headings, labels, and the course endcap for a more polished experience.

pftg and others added 3 commits August 1, 2026 19:05
Hero moves out of the 720px article into a full-bleed ruby-tint band
(demo-1 layout, spec 40.26 sect 3-4): left = clamp 44-64px Space Grotesk H1
+ lede + chips + CTA pair (secondary now white/hairline per spec sect 2);
right = obsidian course-window card - 48px chrome bar with mac dots at 80%,
JetBrains Mono ruby eyebrow, 2-line Space Grotesk title (sanctioned variant),
mono gray-300 meta from course_sequence.yaml. Body sections align on a
centered ~1080px container (3-track grid) with 720px prose measure; endcap
becomes the 896px radius-24 island with top-right glow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Module map section rides a full-bleed #FAFAFA band (wrapper div only -
copy untouched); section H2s scale to clamp 32-40px with ~80px section
spacing; section eyebrows drop from ruby to gray-400 so ruby stays
reserved for the hero-card eyebrow, CTAs, and mistake numerals
(merge-gate design-voter nit).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ayout

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The course page now uses a full-width hero, a browser-window summary card, a gray module-map band, and a centered article layout with a redesigned endcap.

Changes

Course landing page redesign

Layer / File(s) Summary
Landing structure and course window
layouts/course/list.html
The template adds the landing-page structure, loads JetBrains Mono, and replaces the artifact card with a course-window summary card.
Hero visual system
themes/beaver/assets/css/pages/course-list.css
The hero uses responsive typography, a tinted band, a two-column layout, updated CTA states, and browser-window styling.
Module map and article layout
content/course/tech-for-non-technical-founders-2026/_index.md, themes/beaver/assets/css/pages/course-list.css
The module map gains a gray wrapper. The article uses centered tracks, constrained prose, updated eyebrow labels, and a redesigned endcap.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main layout changes: hero band, alignment, and section rhythm.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch course-landing-demo1-layout

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pftg

pftg commented Aug 1, 2026

Copy link
Copy Markdown
Member Author

Honest bin/dtest verdict (main checkout, detached at branch tip; first attempt OOM-killed at exit 137 and discarded, this is the full re-run): 34 runs, 87 assertions, 3 failures - all 9 failing screenshots are the expected set: desktop+mobile course/landing (linux baselines stale on branch by design, CI update-baselines re-records post-merge) + the 7 known mobile-codeblock QEMU emulation diffs. Zero unexpected Linux regressions. Merging per the recorded plan - Paul had the before/after window and did not flag.

@pftg
pftg merged commit c9da2ea into master Aug 1, 2026
2 of 4 checks passed
@pftg
pftg deleted the course-landing-demo1-layout branch August 1, 2026 17:16
pftg added a commit that referenced this pull request Aug 1, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
themes/beaver/assets/css/pages/course-list.css (2)

22-26: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Scope the H2 display-font rule to .course-landing.

.blog .post-content h2 applies to every .blog page, while Space Grotesk is loaded only by layouts/course/list.html. This bundle currently ships only on the course list page, so there is no live regression. Scoping the selector prevents a fallback-font change if the bundle is ever reused.

♻️ Proposed scoping change
-.blog .post-content h2 {
+.course-landing .post-content h2 {
   font-family: "Space Grotesk", system-ui, sans-serif;
   font-weight: 700;
   letter-spacing: -0.02em;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@themes/beaver/assets/css/pages/course-list.css` around lines 22 - 26, Update
the H2 selector in the display-font rule to scope it to the `.course-landing`
container instead of all `.blog` pages, while preserving the existing
font-family, weight, and letter-spacing declarations.

413-421: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Confirm the light hairline border on the obsidian card.

border: 1px solid #f3f4f6`` draws a near-white outline around the #0d1117 card on the ruby-tinted band. Spec §4 describes the card as obsidian with radius 16 and a chrome bar, with no light border. If the border is not intended, remove it or use a low-alpha white edge.

🎨 Proposed border change
-  border: 1px solid `#f3f4f6`;
+  border: 1px solid rgba(255, 255, 255, 0.08);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@themes/beaver/assets/css/pages/course-list.css` around lines 413 - 421,
Update the .course-landing .course-window styling to remove the near-white 1px
border, or replace it with a subtle low-alpha white edge consistent with the
obsidian card specification; preserve the existing background, radius, shadow,
and layout properties.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@layouts/course/list.html`:
- Around line 20-22: Update the Google Fonts request in the course list markup
to load the JetBrains Mono 400 weight used by .course-window__meta, while
preserving the existing 600 weight for other uses; request both weights in the
existing font URL.

In `@themes/beaver/assets/css/pages/course-list.css`:
- Around line 532-539: Add overflow hiding to the base .course-landing
.course-endcap rule, ensuring its extended ::before radial glow is clipped
within the card while preserving the existing pseudo-element positioning and
styling.
- Line 240: Update the eyebrow text color at the reviewed declaration from
`#9ca3af` to a darker gray such as `#6b7280`, preserving the existing styling while
meeting WCAG AA contrast requirements for the 12px bold text.

---

Nitpick comments:
In `@themes/beaver/assets/css/pages/course-list.css`:
- Around line 22-26: Update the H2 selector in the display-font rule to scope it
to the `.course-landing` container instead of all `.blog` pages, while
preserving the existing font-family, weight, and letter-spacing declarations.
- Around line 413-421: Update the .course-landing .course-window styling to
remove the near-white 1px border, or replace it with a subtle low-alpha white
edge consistent with the obsidian card specification; preserve the existing
background, radius, shadow, and layout properties.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a3406c3-cfc7-4acf-8c50-da3effad15ee

📥 Commits

Reviewing files that changed from the base of the PR and between 1c28675 and 976c06b.

⛔ Files ignored due to path filters (3)
  • docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.27-w15-result-full.jpeg is excluded by !**/*.jpeg
  • test/fixtures/screenshots/macos/desktop/course/landing.png is excluded by !**/*.png
  • test/fixtures/screenshots/macos/mobile/course/landing.png is excluded by !**/*.png
📒 Files selected for processing (3)
  • content/course/tech-for-non-technical-founders-2026/_index.md
  • layouts/course/list.html
  • themes/beaver/assets/css/pages/course-list.css

Comment thread layouts/course/list.html
Comment on lines 20 to 22
<link
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap"
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&family=JetBrains+Mono:wght@600&display=swap"
rel="stylesheet" />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Load the JetBrains Mono weight that .course-window__meta uses.

The stylesheet request includes only JetBrains+Mono:wght@600. In themes/beaver/assets/css/pages/course-list.css lines 462-467, .course-window__meta sets font-family: "JetBrains Mono" without font-weight, so it resolves to 400. Only the 600 face is available, so the meta line renders at 600 or falls back. Request both weights, or set font-weight: 600 on .course-window__meta.

🎨 Proposed font request change
-    href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&family=JetBrains+Mono:wght@600&display=swap"
+    href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&family=JetBrains+Mono:wght@400;600&display=swap"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<link
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap"
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&family=JetBrains+Mono:wght@600&display=swap"
rel="stylesheet" />
<link
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&family=JetBrains+Mono:wght@400;600&display=swap"
rel="stylesheet" />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/course/list.html` around lines 20 - 22, Update the Google Fonts
request in the course list markup to load the JetBrains Mono 400 weight used by
.course-window__meta, while preserving the existing 600 weight for other uses;
request both weights in the existing font URL.

letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--color-ruby);
color: #9ca3af;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Compute WCAG contrast ratios for the eyebrow colors on white and `#fafafa`.
python3 - <<'PY'
def lin(c):
    c/=255
    return c/12.92 if c<=0.03928 else ((c+0.055)/1.055)**2.4
def L(h):
    h=h.lstrip('#')
    r,g,b=(int(h[i:i+2],16) for i in (0,2,4))
    return 0.2126*lin(r)+0.7152*lin(g)+0.0722*lin(b)
def ratio(a,b):
    la,lb=L(a),L(b)
    hi,lo=max(la,lb),min(la,lb)
    return (hi+0.05)/(lo+0.05)
for fg in ('`#9ca3af`','`#6b7280`'):
    for bg in ('`#ffffff`','`#fafafa`'):
        print(fg,bg,round(ratio(fg,bg),2))
PY

Repository: jetthoughts/jetthoughts.github.io

Length of output: 255


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="themes/beaver/assets/css/pages/course-list.css"
if [ -f "$file" ]; then
  wc -l "$file"
  sed -n '210,245p' "$file" | cat -n
else
  echo "missing $file"
  fd -i 'course-list.css' .
fi

python3 - <<'PY'
import re
from pathlib import Path
p = Path('themes/beaver/assets/css/pages/course-list.css')
text = p.read_text()
m = re.search(r'(\d{2,\d+})(?:px)?\s+\d*0\s+([A-Za-z]+)', text)
print("font-size-weight-variant:", m.group(0) if m else "not found")
print("`#9ca3af` occurrences:", text.count('`#9ca3af`'))
print("`#6b7280` occurrences:", text.count('`#6b7280`'))
PY

Repository: jetthoughts/jetthoughts.github.io

Length of output: 1705


Use a darker eyebrow color to meet WCAG AA contrast.

#9ca3af is on 12px bold text, so it needs 4.5:1 contrast and only reaches about 2.5:1 on white. Switch it to a darker gray such as #6b7280, which keeps the quiet look and passes AA.

🎨 Proposed color change
-  color: `#9ca3af`;
+  color: `#6b7280`;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
color: #9ca3af;
color: `#6b7280`;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@themes/beaver/assets/css/pages/course-list.css` at line 240, Update the
eyebrow text color at the reviewed declaration from `#9ca3af` to a darker gray
such as `#6b7280`, preserving the existing styling while meeting WCAG AA contrast
requirements for the 12px bold text.

Comment on lines +532 to +539
.course-landing .course-endcap::before {
left: auto;
right: -160px;
top: -140px;
width: 400px;
height: 400px;
transform: none;
background: radial-gradient(closest-side, rgba(204, 52, 45, 0.25), transparent);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Show all .course-endcap rules to confirm overflow and position handling.
rg -n -B2 -A12 '\.course-endcap\b' themes/beaver/assets/css/pages/course-list.css

Repository: jetthoughts/jetthoughts.github.io

Length of output: 2418


🏁 Script executed:

#!/bin/bash
# Check whether .course-landing .course-endcap matches either existing base rule by inspecting
# overflow declarations after these selectors in the stylesheet.
python3 - <<'PY'
from pathlib import Path
p = Path('themes/beaver/assets/css/pages/course-list.css')
text = p.read_text()
for i, line in enumerate(text.splitlines(), 1):
    if '.course-landing .course-endcap' in line:
        end = min(len(text.splitlines()), i + 25)
        chunk = '\n'.join(text.splitlines()[i-1:end])
        print(f'-- selector at line {i} --')
        print(chunk)
        print('contains overflow:', 'overflow' in chunk)
        print('contains explicit hidden:', 'overflow: hidden' in chunk)
PY

Repository: jetthoughts/jetthoughts.github.io

Length of output: 1736


Clip the extended endcap glow.

.course-landing .course-endcap does not set overflow: hidden, while ::before has right: -160px; top: -140px; width: 400px; height: 400px. Add overflow hiding on the base .course-landing .course-endcap rule so the radial glow cannot paint outside the card.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@themes/beaver/assets/css/pages/course-list.css` around lines 532 - 539, Add
overflow hiding to the base .course-landing .course-endcap rule, ensuring its
extended ::before radial glow is clipped within the card while preserving the
existing pseudo-element positioning and styling.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant