migrate from Pico CSS to Tailwind CSS v4
Replace Pico CSS CDN with Tailwind v4 standalone CLI (no Node.js). Brand theme with navy/electric/accent palette, component classes, self-hosted Commit Mono font. Docker multi-stage CSS build. Logo links to dashboard when logged in. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Before Width: | Height: | Size: 412 KiB After Width: | Height: | Size: 266 KiB |
|
Before Width: | Height: | Size: 335 KiB After Width: | Height: | Size: 280 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 48 KiB |
@@ -116,7 +116,7 @@ def test_landing_light_background(live_server, page):
|
||||
page.goto(live_server)
|
||||
page.wait_for_load_state("networkidle")
|
||||
|
||||
# Pico sets background on <html>, body may be transparent
|
||||
# Tailwind sets background on body via base layer
|
||||
bg_color = page.evaluate("""
|
||||
(() => {
|
||||
const html_bg = getComputedStyle(document.documentElement).backgroundColor;
|
||||
@@ -185,14 +185,14 @@ def test_landing_nav_no_overlap(live_server, page):
|
||||
page.goto(live_server)
|
||||
page.wait_for_load_state("networkidle")
|
||||
|
||||
# Get bounding boxes of all nav <li> items in the right <ul>
|
||||
# Get bounding boxes of direct children in the nav's right-side flex container
|
||||
boxes = page.evaluate("""
|
||||
(() => {
|
||||
const uls = document.querySelectorAll('nav ul');
|
||||
if (uls.length < 2) return [];
|
||||
const items = uls[1].querySelectorAll('li');
|
||||
return Array.from(items).map(li => {
|
||||
const r = li.getBoundingClientRect();
|
||||
const navDiv = document.querySelector('nav > div');
|
||||
if (!navDiv) return [];
|
||||
const items = navDiv.children;
|
||||
return Array.from(items).map(el => {
|
||||
const r = el.getBoundingClientRect();
|
||||
return {top: r.top, bottom: r.bottom, left: r.left, right: r.right};
|
||||
});
|
||||
})()
|
||||
@@ -207,6 +207,32 @@ def test_landing_nav_no_overlap(live_server, page):
|
||||
)
|
||||
|
||||
|
||||
def test_landing_cards_have_colored_borders(live_server, page):
|
||||
"""Verify landing page cards have a visible left border accent."""
|
||||
page.goto(live_server)
|
||||
page.wait_for_load_state("networkidle")
|
||||
|
||||
border_widths = page.evaluate("""
|
||||
Array.from(document.querySelectorAll('.card')).map(
|
||||
el => parseFloat(getComputedStyle(el).borderLeftWidth)
|
||||
)
|
||||
""")
|
||||
assert len(border_widths) > 0, "No .card elements found"
|
||||
cards_with_accent = [w for w in border_widths if w >= 4]
|
||||
assert len(cards_with_accent) >= 10, (
|
||||
f"Expected >=10 cards with 4px left border, got {len(cards_with_accent)}"
|
||||
)
|
||||
|
||||
|
||||
def test_landing_logo_links_to_landing(live_server, page):
|
||||
"""Verify logo links to landing page when not logged in."""
|
||||
page.goto(live_server)
|
||||
page.wait_for_load_state("networkidle")
|
||||
|
||||
href = page.locator("nav a").first.get_attribute("href")
|
||||
assert href == "/", f"Expected logo to link to /, got {href}"
|
||||
|
||||
|
||||
def test_landing_teaser_light_theme(live_server, page):
|
||||
"""Verify teaser calculator has white/light background."""
|
||||
page.goto(live_server)
|
||||
@@ -262,7 +288,7 @@ def test_mobile_nav_no_overflow(live_server, browser):
|
||||
})()
|
||||
""")
|
||||
page.close()
|
||||
# Pico's nav may wrap on mobile, which is fine — just verify no JS errors
|
||||
# Nav may wrap on mobile, which is fine — just verify no JS errors
|
||||
|
||||
|
||||
def test_landing_no_dark_remnants(live_server, page):
|
||||
|
||||