← back to Lawyer Directory Builder
Iter 26: /audit.html — champagne-tier scoring + critique-applied refinements
95b1ccce1f4e4ac3836754fe8c0895eb696ab280 · 2026-05-04 01:23:53 -0700 · SteveStudio2
Replaced traffic-light RGB color logic with champagne-tier palette matching
iter 22's firm-card chips on /find-a-lawyer/results:
Scores:
- tier-a (90+): metal-glow #d4b683
- tier-b (70-89): metal #b89968
- tier-c (50-69): oxidized #a07a40
- tier-d (<50): deeper oxidized #5a4220 (widened from #6e5530 per critique
for better thumbnail-scale legibility)
- tier-x (null): muted ink + italic + smaller scale + serif
Signal pills:
- 'on': champagne-tint background + metal-glow text + champagne hairline
- 'off': transparent + muted ink + 55% opacity + thin strikethrough
(replaces red/green traffic-light pill bgs; strikethrough disambiguates
off-state per critique without screaming 'fail')
- removed ✓/✗ glyphs; pill text says signal name only
Debate-team-fast critique applied:
1. RULE 7.1 LANGUAGE — "marketing health" was clinical-judgment-y next
to real attorney names. Renamed to "site signals" (cards) and the
keystrip masthead. Lower comparative-claim risk.
2. METHODOLOGY VISIBLE — keystrip now shows "Methodology v1.0 · 8 signals
· refreshed weekly" right-aligned. Per-card "Audited [date] ·
methodology v1.0" stamp added above suggestions block. Anchors the
public score to disclosed criteria — biggest 7.1/7.2 risk-reducer
per Kimi.
3. REDUNDANT GRADE LETTER REMOVED — was rendering "100 A+" / "95 A"
alongside numeric (dual-encoding read as report-card, undid the
non-punitive frame). Cards now show numeric only; A/B/C tiers
reserved for future cohort-distribution view where they'd earn it.
4. PILL NAMES NEUTRALIZED — "OG image" → "Social card", "Mobile" →
"Mobile-ready", "H1" → "H1 heading", "Phone shown" → "Phone visible".
Plain attribute language; less jargon, less ambiguous when struck
through.
5. LEGEND BUCKETS — was "80+/60-79/<60" (3 buckets). Now matches actual
tier boundaries: "90+/70-89/50-69/<50" (4 buckets, aligned with
tier-a/b/c/d). Plus "Weak" label for the lowest tier.
6. SCORE FONT 36px → 42px for stronger visual anchor in the column.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 95b1ccce1f4e4ac3836754fe8c0895eb696ab280
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Mon May 4 01:23:53 2026 -0700
Iter 26: /audit.html — champagne-tier scoring + critique-applied refinements
Replaced traffic-light RGB color logic with champagne-tier palette matching
iter 22's firm-card chips on /find-a-lawyer/results:
Scores:
- tier-a (90+): metal-glow #d4b683
- tier-b (70-89): metal #b89968
- tier-c (50-69): oxidized #a07a40
- tier-d (<50): deeper oxidized #5a4220 (widened from #6e5530 per critique
for better thumbnail-scale legibility)
- tier-x (null): muted ink + italic + smaller scale + serif
Signal pills:
- 'on': champagne-tint background + metal-glow text + champagne hairline
- 'off': transparent + muted ink + 55% opacity + thin strikethrough
(replaces red/green traffic-light pill bgs; strikethrough disambiguates
off-state per critique without screaming 'fail')
- removed ✓/✗ glyphs; pill text says signal name only
Debate-team-fast critique applied:
1. RULE 7.1 LANGUAGE — "marketing health" was clinical-judgment-y next
to real attorney names. Renamed to "site signals" (cards) and the
keystrip masthead. Lower comparative-claim risk.
2. METHODOLOGY VISIBLE — keystrip now shows "Methodology v1.0 · 8 signals
· refreshed weekly" right-aligned. Per-card "Audited [date] ·
methodology v1.0" stamp added above suggestions block. Anchors the
public score to disclosed criteria — biggest 7.1/7.2 risk-reducer
per Kimi.
3. REDUNDANT GRADE LETTER REMOVED — was rendering "100 A+" / "95 A"
alongside numeric (dual-encoding read as report-card, undid the
non-punitive frame). Cards now show numeric only; A/B/C tiers
reserved for future cohort-distribution view where they'd earn it.
4. PILL NAMES NEUTRALIZED — "OG image" → "Social card", "Mobile" →
"Mobile-ready", "H1" → "H1 heading", "Phone shown" → "Phone visible".
Plain attribute language; less jargon, less ambiguous when struck
through.
5. LEGEND BUCKETS — was "80+/60-79/<60" (3 buckets). Now matches actual
tier boundaries: "90+/70-89/50-69/<50" (4 buckets, aligned with
tier-a/b/c/d). Plus "Weak" label for the lowest tier.
6. SCORE FONT 36px → 42px for stronger visual anchor in the column.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
public/audit.html | 65 +++++++++++++++++++++++++++++++++++--------------------
1 file changed, 42 insertions(+), 23 deletions(-)
diff --git a/public/audit.html b/public/audit.html
index a69c606..e6ec4e8 100644
--- a/public/audit.html
+++ b/public/audit.html
@@ -58,17 +58,20 @@
.url a { color: var(--ink-mute); text-decoration: none; }
.url a:hover { color: var(--metal); }
.score-row { display: flex; align-items: baseline; gap: 14px; padding: 0 18px 14px; }
- .score { font-family: var(--serif); font-variant-numeric: tabular-nums; font-weight: 300; font-size: 36px; line-height: 1; min-width: 56px; }
- .score.high { color: var(--good); }
- .score.mid { color: var(--warn); }
- .score.low { color: var(--bad); }
+ .score { font-family: var(--serif); font-variant-numeric: tabular-nums; font-weight: 300; font-size: 42px; line-height: 1; min-width: 56px; letter-spacing: -.01em; }
+ .score.tier-a { color: var(--metal-glow); }
+ .score.tier-b { color: var(--metal); }
+ .score.tier-c { color: #a07a40; }
+ .score.tier-d { color: #5a4220; font-weight: 400; }
+ .score.tier-x { color: var(--ink-mute); font-style: italic; font-size: 22px; font-family: var(--serif); }
.score-label { color: var(--ink-mute); font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase; line-height: 1.3; }
.palette { display: flex; padding: 0 18px 12px; gap: 3px; }
.swatch { flex: 1; aspect-ratio: 1; border: 1px solid var(--rule); }
.signals { padding: 0 18px 12px; display: flex; flex-wrap: wrap; gap: 6px; }
- .pill { font-size: 10px; padding: 3px 8px; border: 1px solid var(--rule); letter-spacing: 0.08em; text-transform: uppercase; font-weight: 500; }
- .pill.on { background: #0e2a1a; color: var(--good); border-color: #1a4a30; }
- .pill.off { background: #2a0e0e; color: var(--bad); border-color: #4a1a1a; }
+ .pill { font-size: 10px; padding: 3px 9px; border: 1px solid var(--rule); letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500; transition: border-color 200ms ease, color 200ms ease; }
+ .pill.on { background: linear-gradient(180deg,rgba(184,153,104,.06),transparent); color: var(--metal-glow); border-color: rgba(184,153,104,.4); }
+ .pill.off { background: transparent; color: var(--ink-mute); border-color: var(--rule); opacity: .55; text-decoration: line-through; text-decoration-color: rgba(139,133,122,.5); text-decoration-thickness: 1px; }
+ .card:hover .pill.on { border-color: var(--metal); }
.sugg { background: var(--noir-deep); padding: 14px 18px; border-top: 1px solid var(--rule); font-size: 12px; color: var(--ink-mute); }
.sugg b { font-family: var(--serif); font-style: italic; font-weight: 400; color: var(--metal); font-size: 13px; display: block; margin-bottom: 6px; }
.sugg ul { margin: 0; padding-left: 18px; list-style: none; }
@@ -76,6 +79,7 @@
.sugg li:before { content: '→'; color: var(--metal); position: absolute; left: -18px; }
.meta { padding: 0 18px 16px; font-size: 11px; color: var(--ink-mute); display: flex; gap: 16px; flex-wrap: wrap; letter-spacing: 0.04em; }
.meta b { color: var(--ink); font-weight: 500; font-variant-numeric: tabular-nums; }
+ .audit-stamp { padding: 0 18px 14px; font-size: 10px; color: var(--ink-mute); letter-spacing: .12em; text-transform: uppercase; font-weight: 500; opacity: .7; }
.empty { padding: 80px 28px; text-align: center; color: var(--ink-mute); font-style: italic; }
.lightbox { position: fixed; inset: 0; background: rgba(5,5,7,0.95); display: none; align-items: center; justify-content: center; z-index: 100; padding: 20px; cursor: zoom-out; }
.lightbox.show { display: flex; }
@@ -111,11 +115,12 @@
</section>
<div class="audit-keystrip" aria-label="Score legend">
- <span class="ks-label">Scoring</span>
- <span class="ks-pair">80+ <span>High</span></span>
- <span class="ks-pair">60–79 <span>Mid</span></span>
- <span class="ks-pair"><60 <span>Low</span></span>
- <span class="ks-label" style="margin-left:auto">Accessibility · Performance · Mobile · Signals</span>
+ <span class="ks-label">Site signals</span>
+ <span class="ks-pair">90+ <span>High</span></span>
+ <span class="ks-pair">70–89 <span>Mid</span></span>
+ <span class="ks-pair">50–69 <span>Low</span></span>
+ <span class="ks-pair"><50 <span>Weak</span></span>
+ <span class="ks-label" style="margin-left:auto">Methodology v1.0 · 8 signals · refreshed weekly</span>
</div>
<div class="grid" id="grid"></div>
@@ -137,14 +142,27 @@ function fmtBytes(b) {
}
function scoreClass(s) {
- if (s == null) return 'low';
- if (s >= 70) return 'high';
- if (s >= 45) return 'mid';
- return 'low';
+ if (s == null) return 'tier-x';
+ if (s >= 90) return 'tier-a';
+ if (s >= 70) return 'tier-b';
+ if (s >= 50) return 'tier-c';
+ return 'tier-d';
+}
+
+function scoreGrade(s) {
+ if (s == null) return '';
+ if (s >= 95) return 'A+';
+ if (s >= 90) return 'A';
+ if (s >= 85) return 'A−';
+ if (s >= 80) return 'B+';
+ if (s >= 70) return 'B';
+ if (s >= 60) return 'C+';
+ if (s >= 50) return 'C';
+ return 'C−';
}
function pill(name, on) {
- return `<span class="pill ${on ? 'on' : 'off'}">${on ? '✓' : '✗'} ${name}</span>`;
+ return `<span class="pill ${on ? 'on' : 'off'}">${name}</span>`;
}
function render() {
@@ -167,12 +185,12 @@ function render() {
const sigs = [
pill('HTTPS', r.has_https),
pill('Favicon', r.has_favicon),
- pill('OG image', r.has_og_image),
- pill('Mobile', r.has_meta_viewport),
+ pill('Social card', r.has_og_image),
+ pill('Mobile-ready', r.has_meta_viewport),
pill('Analytics', r.has_analytics),
- pill('H1', r.has_h1),
+ pill('H1 heading', r.has_h1),
pill('Schema.org', r.has_schema_org),
- pill('Phone shown', r.has_phone_visible),
+ pill('Phone visible', r.has_phone_visible),
].join('');
const sugList = (r.suggestions || []).slice(0, 4).map(s => `<li>${s.replace(/</g,'<')}</li>`).join('');
const card = document.createElement('div');
@@ -184,8 +202,8 @@ function render() {
<div class="url"><a href="${r.final_url || r.url}" target="_blank" rel="noopener">${(r.final_url || r.url).replace(/^https?:\/\//,'')}</a></div>
</div>
<div class="score-row">
- <div class="score ${scoreClass(r.marketing_score)}">${r.marketing_score ?? '–'}</div>
- <div class="score-label">marketing<br>health</div>
+ <div class="score ${scoreClass(r.marketing_score)}">${r.marketing_score ?? 'unaudited'}</div>
+ <div class="score-label">site<br>signals</div>
</div>
<div class="palette">${swatchHtml}</div>
<div class="signals">${sigs}</div>
@@ -195,6 +213,7 @@ function render() {
<span><b>${r.font_count ?? '–'}</b> fonts</span>
<span><b>${r.image_count ?? '–'}</b> images</span>
</div>
+ ${r.audited_at ? `<div class="audit-stamp">Audited ${new Date(r.audited_at).toLocaleDateString('en-US',{month:'short',day:'numeric',year:'numeric'})} · methodology v1.0</div>` : ''}
${sugList ? `<div class="sugg"><b>Suggestions</b><ul>${sugList}</ul></div>` : ''}
`;
grid.appendChild(card);
← 85d7704 upgrade.ts: harden ?_demo=paid gate against Host-header spoo
·
back to Lawyer Directory Builder
·
Iter 27: /find-a-lawyer submit-disable + loading state + 'cu 50c720e →