{"slug":"lawyer-directory-builder","total":37,"limit":100,"offset":0,"since":null,"commits":[{"hash":"40951c7","date":"2026-07-03 08:08:07 -0700","author":"Steve","subject":"chore: macstudio3 migration — reconcile from mac2 + repoint paths (stevestudio2→macstudio3, node/npm/npx→/opt/homebrew)","body":""},{"hash":"650dec4","date":"2026-05-30 23:58:44 -0700","author":"SteveStudio2","subject":"fix: add rel=noopener noreferrer to target=_blank links in dashboard; add backup file patterns to .gitignore","body":"Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"},{"hash":"94f1067","date":"2026-05-13 08:57:56 -0700","author":"Steve","subject":"snapshot: 26 file(s) changed, +6 new, ~20 modified","body":""},{"hash":"1e3890c","date":"2026-05-07 12:29:27 -0700","author":"Steve","subject":"tighten .gitignore: add missing standing-rule patterns (build/ .next/)","body":""},{"hash":"2ad78f2","date":"2026-05-04 10:11:36 -0700","author":"SteveStudio2","subject":"Iter 45: SEO essentials — robots.txt, sitemap.xml, favicon (4× formats)","body":"All three were 404 in production. Google had no efficient way to crawl\nthe site; the methodology v1.0 audit's own signal #8 (\"Favicon\npresent\") was failing on Counsel & Bar's own site, which is the kind\nof irony only a Rule 7.1 plaintiff would notice.\n\nFiles shipped:\n\npublic/robots.txt:\n  - Allow all by default\n  - Disallow /admin/, /api/, /dashboard, /login, post-payment\n    confirmation pages (no SEO value, surface PII to crawlers)\n  - Crawl-delay: 1 (gentle hint)\n  - Sitemap reference\n\npublic/sitemap.xml:\n  - 10 public surfaces with lastmod, changefreq, priority\n  - image:image entry on landing pointing at og.png so Google Image\n    can index the share tile\n  - Priorities: landing 1.0, find/directory 0.9, audit/methodology\n    0.8, upgrade/data 0.7, signup 0.6, privacy/terms 0.3\n\npublic/favicon.svg + public/favicon-32.png:\n  - SVG primary (CB monogram in champagne gradient on noir, scales\n    perfectly across pixel densities)\n  - PNG 32×32 fallback (Playwright-rendered from same SVG) for legacy\n    browsers + Apple Touch Icon\n  - meta name=\"theme-color\" content=\"#0a0a0c\" so mobile browsers tint\n    the URL bar to match noir background\n\nWired <link rel=\"icon\" type=\"image/svg+xml\"> + PNG fallback +\napple-touch-icon + theme-color into landing, /methodology, /audit, and\nleads.ts layout (covers /find-a-lawyer + all dynamic routes).\n\nVerified live: all four assets return 200, 3 rel=icon links per\nsurface.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"31d0eaf","date":"2026-05-04 09:42:48 -0700","author":"SteveStudio2","subject":"Iter 44: OG share image (1200×630) + summary_large_image cards everywhere","body":"Iter 42-43 added share metadata text but no og:image. Social previews on\nLinkedIn / X / Slack / Discord / Facebook rendered as small summary\ncards (text-only). Now full preview cards with brand image.\n\nImage (public/og.svg → public/og.png via Playwright render):\n- 1200×630 noir gradient bg\n- Subtle italic 'I' watermark in deep right (4% opacity, 780px)\n- Volume strip masthead: 'Volume I · Edition 2026 · Counsel & Bar'\n- CB monogram top-right\n- Italic-metal display 'Every California-licensed attorney, indexed.'\n  ('indexed.' in italic-metal, rest in ivory)\n- Lede in ink-soft: 'Drawn from the State Bar of California public roll.\n  Independently audited. Methodology v1.0 published.'\n- Footer strip with hairline rule:\n  · 'lawyers.agentabrams.com' (italic-metal)\n  · 'A DIRECTORY · NOT A REFERRAL SERVICE · NOT THE STATE BAR'\n    (ink-mute caps, §6155 disambiguation in the share preview itself)\n\nWiring (all 4 high-traffic surfaces):\n- og:image, og:image:width=1200, og:image:height=630, og:image:alt\n- twitter:card upgraded summary → summary_large_image\n- twitter:image points to same og.png\n\nDeployed to prod via rsync (og.png 200KB, og.svg 1.5KB, plus updated\nHTML for 3 static pages and leads.ts for dynamic routes). Verified\nlive: og.png 200/204782 bytes; 4-5 og:image meta tags per surface.\n\nBrand language now travels with every shared link — including the\n§6155 'NOT THE STATE BAR' disambiguation, baked into the image itself\nin case a regulator screenshots a social preview.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"ee84e9e","date":"2026-05-04 09:13:57 -0700","author":"SteveStudio2","subject":"Iter 43: OG + JSON-LD propagated to /methodology, /audit, /find-a-lawyer","body":"Iter 42 added share-metadata to landing only. The other 3 high-traffic\npublic surfaces still rendered as bare URLs in social preview cards.\nNow full coverage:\n\n/methodology.html:\n  - canonical, robots index/follow\n  - og:type=article, og:title, og:description (52-char preview), og:url\n  - twitter:card=summary\n  - JSON-LD TechArticle (datePublished/dateModified 2026-05-04, version\n    1.0, author + publisher Organization, mainEntityOfPage)\n\n/audit.html:\n  - canonical, robots index/follow, full description meta\n  - og:website, og:title, og:description (mentions 1,016 audited sites,\n    methodology v1.0)\n  - twitter:card=summary\n  - JSON-LD Dataset (description enumerates all 12 signals,\n    creator+publisher, license link to /terms.html, isAccessibleForFree\n    true). Dataset is the right Schema.org type for an aggregated\n    public-firm scoring; gives Google Dataset Search eligibility.\n\n/find-a-lawyer (and all leads.ts-served routes via the layout helper):\n  - og:website, og:title (page-title from layout('...')), og:description\n    pulls in §6155-safe boilerplate ('Independent. Not a referral\n    service. Not the State Bar.')\n  - og:locale=en_US\n  - twitter:card=summary\n\nJSON-LD intentionally NOT added to find-a-lawyer routes — page is the\nconfigurator, not a content article; SearchAction is already declared\non landing's WebSite entity.\n\nVerified live on https://lawyers.agentabrams.com/ — all 3 surfaces\nreturn 200 with 8-11 meta/structured-data tags each.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"4ff44cf","date":"2026-05-04 08:45:07 -0700","author":"SteveStudio2","subject":"Iter 42: landing — OG + Twitter card + JSON-LD structured data + canonical","body":"Landing had zero share-metadata. Link previews on LinkedIn / X / Discord /\nSlack rendered as bare URLs, no preview card. Added the full set:\n\n- <link rel=\"canonical\" href=\"https://lawyers.agentabrams.com/\">\n- <meta name=\"robots\" content=\"index, follow\">\n- og:type=website, og:site_name, og:title, og:description, og:url,\n  og:locale=en_US (no og:image yet — use summary card; can add a CSS-\n  rendered noir/champagne tile later if a paid social campaign needs it)\n- twitter:card=summary, twitter:title, twitter:description (both tighter\n  copy than OG so they fit X's 70-char render window)\n\nJSON-LD structured data:\n  Organization (@id #org) + WebSite (@id #website) graph entries\n  - name, alternateName, url, description (with §6155 cite verbatim)\n  - areaServed: California\n  - knowsAbout: California attorneys, lawyer directory, California State\n    Bar\n  - sameAs: https://www.calbar.ca.gov/  (Schema.org disambiguation —\n    tells Google + crawlers explicitly that we are NOT calbar.ca.gov,\n    we just reference it as authoritative source — same §6155-correct\n    disambiguation we already do in the visual eyebrow + title)\n  - publisher relation linking WebSite to Organization\n  - potentialAction: SearchAction targeting /find-a-lawyer?zip={zip}\n    so Google can render a sitelinks search box\n\nDeployed to prod via rsync (public/index.html only — static, no pm2\nrestart needed). Verified 14 meta + structured-data tags render live\nat https://lawyers.agentabrams.com/.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"a0b97b0","date":"2026-05-04 08:04:03 -0700","author":"SteveStudio2","subject":"Iter 40: landing footer — add methodology + State Bar lookup links, fix mislabel","body":"Three improvements to the landing footer's link columns:\n\n1. 'Browse the directory' (pointing at /audit.html) was a mislabel — that\n   link IS the site-audit page, not a directory browser. Relabeled to\n   'Site audit' (accurate) and added 'Audit methodology' link below it\n   pointing to /methodology.html (iter 29's substantiation document,\n   not previously linked from the footer).\n\n2. Attorneys column added 'Find your firm' link to /directory (iter 28's\n   attorney self-service surface — was orphaned in the footer despite\n   being a major lawyer-facing entry point). 'Claim your firm' relabeled\n   to 'Claim your listing' to match the verb used everywhere else on\n   /signup ('Claim your listing →' button) and /signup/welcome\n   ('Welcome to the registry').\n\n3. Legal column added 'State Bar lookup ↗' as third link — directs\n   highest-stakes verification (license status) to the authoritative\n   apps.calbar.ca.gov/attorney/Licensee/Search rather than back into our\n   directory. Matches the §6155-correct deep-linking pattern from iter\n   31 (/404 suggest-grid) + iter 36 (/find-a-lawyer/thanks). Privacy\n   and Terms shortened to 'Privacy' / 'Terms' since the column header\n   provides the 'Legal' context.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"a14af3b","date":"2026-05-04 07:55:31 -0700","author":"SteveStudio2","subject":"Iter 39: legal lockdown — three remaining LRS-flavor copy fixes","body":"Steve directive: 'Site must be legally bound. No gray areas.' Final §6155\nsweep across all surfaces. Three fixes applied:\n\n1. /find-a-lawyer URGENCY option label —\n   was: 'I need to talk to someone today'\n   Reads as 'we'll connect you to talk to someone' = LRS routing.\n   now: 'I plan to call a firm today'\n   User describes their own plan; we don't promise a connection.\n\n2. /find-a-lawyer field-note under submit —\n   was: 'By submitting you authorize us to display matching firms.'\n   \"Matching\" is the §6155 LRS-pattern verb.\n   now: 'By submitting you authorize us to display California-licensed\n   firms in your area, ranked by proximity.'\n   Mathematical proximity ranking is not \"matching.\" Honest copy.\n\n3. /terms.html section 4 (How the directory works) —\n   was: 'See a list of California-licensed firms in your area that\n   match your practice area and ZIP.'\n   \"match\" again — same §6155 verb.\n   now: 'See a list of California-licensed firms in your area that you\n   can filter by practice area and ZIP.'\n   The user filters; we don't match.\n\nAfter this iter, the user-visible verb 'match' (and its conjugations)\nno longer appears anywhere on the public site outside of internal DB\nschema (lead.matched_firm_ids column, status='matched' enum, CSS class\n.pill.matched) which is admin-only and never user-rendered.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"3fe9d64","date":"2026-05-04 07:37:11 -0700","author":"SteveStudio2","subject":"Iter 38: landing — critical §6155 fixes from cold-eye debate critique","body":"Cold-eye debate-team-fast review caught two CRITICAL §6155 risks the\nin-loop iterations had drifted into. Both fixed before commit:\n\n1. <title> IMPERSONATION RISK (highest severity) —\n   was: 'The California Bar — Curated.'\n   \"The California Bar\" reads as the State Bar of California itself.\n   This is the line a regulator screenshots first — it appears in SERP\n   results, browser tabs, OG previews. Footer disclaimers can't undo\n   it. Plus 'Curated' was supposed to be removed in iter 27 but\n   somehow survived in the title.\n   now: 'Counsel & Bar — California attorney directory (independent ·\n   not the State Bar)'\n   Eyebrow line 405 also reframed:\n   was: 'California · Est. on the public bar registry'\n   now: 'California · Independent directory · Not the State Bar'\n   Triple-redundant disambiguation across title + eyebrow + footer.\n\n2. FEATURE 02 §6155 FEE-HANDLING IMPLICATION —\n   was: 'Thirty minutes, by Zoom · Pay a flat fee for a real\n        consultation.'\n   Reads like Counsel & Bar arranges paid attorney consultations,\n   which veers toward the §6155 'for compensation, refers' definition.\n   now: 'Consultations on the attorney's terms · Each firm publishes\n   its own consultation fee, schedule, and booking flow. Counsel & Bar\n   never touches the money — payments and engagement letters run\n   directly between you and the attorney.'\n   Closes the fee-handling gap: we don't book consultations, we don't\n   collect attorney fees, attorneys handle their own intake.\n\n3. VISUAL FIX — replaced the giant italic 'I' watermark (clamp 420-\n   1100px, opacity .045) which read as a vertical bar / accidental\n   glyph at desktop widths. Aston Martin doesn't put a giant\n   translucent letter behind the car. Replaced with .hero-folio in the\n   top-right: 'Vol. I' italic Cormorant + champagne hairline rule +\n   'MMXXVI' caps + '№ 001' caps. Real piece of typography that earns\n   the 'Edition 2026' framing the rest of the page is reaching for.\n   Old .hero-watermark class set to display:none (no-op, prevents\n   cache-error if older HTML is served).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"f10bb42","date":"2026-05-04 07:07:24 -0700","author":"SteveStudio2","subject":"Iter 37: /data/thanks editorial confirmation matching iter 25 pattern","body":"Brought /data/thanks paid path to the editorial standard set by\n/upgrade/thanks (iter 25). Was eyebrow + h1 + button + bookmark URL —\nminimal next to the polished /upgrade/thanks for the same money.\n\nWhat shipped on the paid path:\n- Volume strip 'Edition 2026 · Order Confirmed' (or 'Subscription\n  Active' for the recurring tier)\n- Italic-metal display 'Your data is ready.' (kept; still right)\n- Order № receipt strip — DATA-YYYY-MMDD-NNNN format, italic-metal\n  tabular-nums (matches EZ-YYYY-MMDD-NNNN on /upgrade/thanks). Three\n  cols: Order №, Logged, Charged ($amount). For subscription tier\n  shows '$X/mo' and label 'Recurring'.\n- 'What's next' 3-cell grid:\n    i.  Download the CSV — flat-noir + champagne-hairline button\n    ii. Bookmark your download URL — full URL in monospace code box\n    iii. Use the data lawfully — State Bar permitted-use rules,\n         CCPA/CPRA, no bulk SMS / robocalls / resale, inactive\n         attorneys excluded at export\n- 'For the record' trust block — data sourcing (State Bar public DB +\n  publicly-indexed firm sites + LA City Active Business Licenses\n  NAICS 5411), 'directory listing is independent of any commercial\n  offering,' Stripe PCI disclosure.\n\nPending path also got Volume strip 'Edition 2026 · Reservation\nPending' + italic-metal 'Reservation noted.' + back-link to /data.\n\nSame iter-25 architectural pattern, four surfaces deep now: /upgrade,\n/upgrade/thanks, /signup/welcome, /data/thanks.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"e6238ca","date":"2026-05-04 06:38:45 -0700","author":"SteveStudio2","subject":"Iter 36: /find-a-lawyer/thanks — State Bar deep-link + Rule 7.1 honesty","body":"Two fixes to the Verify-with-State-Bar cell on /find-a-lawyer/thanks:\n\n1. Deep-link the State Bar destination — was 'calbar.ca.gov' (homepage,\n   user has to navigate the menus to find licensee search). Now\n   apps.calbar.ca.gov/attorney/Licensee/Search opens the search form\n   directly. One-click verify, matches the deep-link pattern already\n   used in /find-a-lawyer/results firm-card 'verify on State Bar' chips\n   (iter 22) and /404 suggest-grid (iter 31).\n\n2. Soften the unsubstantiated daily-refresh claim — was 'We refresh\n   against it daily but the live source is authoritative.' We do run\n   periodic CalBar scrapes, but no live 'daily' guarantee in\n   production. Now: 'We draw from that roll; the live source at\n   calbar.ca.gov remains authoritative for any disciplinary status\n   check.' Honest, §6155-correct, and explicitly directs the highest-\n   stakes verification (disciplinary status) to the authoritative\n   source.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"7d98dc9","date":"2026-05-04 06:09:24 -0700","author":"SteveStudio2","subject":"Iter 35: Lawyer Pro pitch + dashboard FTC copy — three latent compliance fixes","body":"Three latent §6155 / FTC issues in core code, caught while scanning for\n'24 hour' / 'first call' / 'matched lead' patterns post-iter-34:\n\n1. Lawyer Pro pitch (paid $29/mo product) used 'matched lead' / 'lead\n   alerts' / 'the moment a matched lead is submitted' — implies our\n   directory routes leads to attorneys, which IS the LRS pattern §6155\n   prohibits. Reframed:\n     - 'matched lead' → 'directory inquiry'\n     - 'lead alerts' → 'directory-inquiry alerts'\n     - 'Get notified the moment a matched lead is submitted in your\n        practice area + ZIP' → 'See an alert when a directory inquiry\n        mentions your practice area + ZIP — and you decide whether to\n        reach out'\n     - 'Direct messages with potential clients' → 'Direct messages\n        with visitors who initiate contact'\n     - 'Real-time lead alerts (practice area + ZIP)' → 'Directory-\n        inquiry alerts (practice area + ZIP) — for your awareness'\n   The product is unchanged; the copy now describes it in §6155-safe\n   language: directory shows inquiries → attorney decides to reach\n   out. No matching, no routing.\n\n2. /dashboard EZ Upgrade pitch said 'live in 7 days' (unconditional FTC\n   promise). iter 24 fixed this on /upgrade but missed the dashboard\n   reference. Now matches: 'typical go-live: seven business days from\n   content intake.'\n\n3. /directory inquiry success-flash said \"We'll be in touch within 24\n   hours.\" — same unconditional SLA that violated FTC §5 advertising\n   rules on a service we don't actually staff 24 hours. Softened to\n   \"We'll respond within two business days.\" Operationally honest.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"c18ff69","date":"2026-05-04 05:40:02 -0700","author":"SteveStudio2","subject":"Iter 34: landing stat ledger — fix misleading §6155 stat + Rule 7.1 substantiation","body":"CRITICAL §6155 fix: stat iv was '24 hrs · From submission to first call'\n— this implies we route inquiries to attorneys who then call the consumer\nwithin 24 hours, which IS the LRS pattern §6155 prohibits non-licensee\noperators from running. We don't do that. We show a list of firms; the\nuser calls them.\n\nReplaced with: '$0 to search · No fee from you, no fee from firms · we\ndo not refer cases or split fees · §6155'. Same visual weight, accurate\nservice description, codifies the §6155 posture in the stat ledger\nitself.\n\nRule 7.1 substantiation: stats i-iii were bare integers ('89,390' /\n'42,636' / '1,016') with no source attribution. Hardcoded numbers next\nto real attorney names is the textbook Rule 7.1 trap (caught by Kimi in\niter 21 on the proof strip). Now:\n\n- i. ~89,000 — '~' approximator + 'as of 2026-05-04 · State Bar public\n  roll' attribution. Reflects truth that the count fluctuates daily.\n- ii. ~42,600 — same '~' + 'aggregated from the registry' attribution.\n- iii. 1,016 — exact (we audit a finite cohort, count is precise) +\n  'methodology v1.0 →' link to the substantiation document (iter 29).\n- iv. $0 to search — fee posture, with the §6155 rule cite right there.\n\nVisual: each stat keeps the big italic Cormorant numeral + caps label,\ngains a tiny italic-mute attribution sub-line below the label. No\ndimensional change; just additional regulatory context.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"9d4bfa7","date":"2026-05-04 05:11:58 -0700","author":"SteveStudio2","subject":"Iter 33: walker — added 4 new surfaces from overnight loop","body":"Captures the full overnight loop progress in the click-through video:\n\nNew surfaces walked:\n- 06b-methodology  → /methodology.html (iter 29)\n- 06c-directory    → /directory (iter 28)\n- 06d-upgrade      → /upgrade (iter 24)\n- 10-404           → /lawyer-near-me-typo → 404 page (iter 31)\n\nWalker now captures 14 surfaces (was 11). Each gets its own captioned\nPNG + a per-surface entry in the per-page Steve-avatar PiP overlay.\nBrand-audit (monogram + volStrip + disclaimer presence) reports per\nsurface, including the new ones — note: the audit checks only for the\n.public-vol class, so methodology/directory/upgrade/404 show\nvolStrip=false despite having Volume strips (under .method-vol /\n.dir-vol / .up-vol / .nf-vol class names). Cosmetic walker false-\nnegative; surfaces themselves are correct.\n\nOutput: /tmp/lawyer-clickthrough/walkthrough-2026-05-04T12-11-22.webm\n(6.0 MB, ~14 × 4-second frames + 1-second transitions)\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"4041f14","date":"2026-05-04 04:43:42 -0700","author":"SteveStudio2","subject":"Iter 32: /privacy + /terms — Volume strip masthead + italic-metal display","body":"Last two public-facing surfaces still on bare 'Privacy Policy.' / 'Terms\nof Service.' headers and short-eyebrow chrome. Brought into the\neditorial standard.\n\n/privacy.html:\n- Volume strip 'Edition 2026 · Privacy Policy · Effective 2026-05-03'\n- Italic-metal display 'What we collect. What we don't.' (was 'Privacy\n  Policy.' — bare label, now reads as a statement of position)\n- Lede gains strong-emphasis on 'what we collect, why, how we use it,\n  who it goes to' + 'CCPA / CPRA' (was muted-only, hard to scan)\n\n/terms.html:\n- Volume strip 'Edition 2026 · Terms of Service · Effective 2026-05-03'\n- Italic-metal display 'The terms. Plain language.' (was 'Terms of\n  Service.' — restated as the document's actual posture)\n- Lede explicit: 'most of this is the boring legal stuff every site\n  has to publish — we've kept it in plain English wherever the law\n  lets us'\n\nBoth pages now share the same Volume strip + italic-metal + responsive\nclamp() display sizing as /find-a-lawyer, /signup, /dashboard, /audit,\n/methodology, /directory, /upgrade, /404. Twelve consecutive public\nsurfaces sharing a masthead system.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"41bda2f","date":"2026-05-04 03:49:55 -0700","author":"SteveStudio2","subject":"Iter 31: /404 — path-aware editorial recovery surface","body":"Replaced bare 'Return home / Find counsel' 404 with full editorial\nrecovery layout. Most 404 traffic on a directory site is typo'd or\nstale-link — give the user a real path forward instead of a dead-end.\n\nWhat shipped:\n- Volume strip masthead 'Edition 2026 · Not Found' (was bare eyebrow\n  'Volume I · Edition 2026' floating without rule)\n- Italic-metal display 'Not in the *registry.*' (kept; still the right\n  line)\n- Path strip — surfaces requested URL verbatim in champagne monospace:\n  'REQUESTED /lawyer-near-me'. Path is HTML-escaped and truncated to 80\n  chars; query strings stripped (PII risk). User immediately knows what\n  we couldn't find.\n- 3-cell 'Where you may have meant to land' grid with outlined italic\n  Romans (i/ii/iii):\n    i.  Find counsel → /find-a-lawyer (the 3-section configurator)\n    ii. Audit a site → /audit.html (independent audit + methodology)\n    iii. Verify on the State Bar → apps.calbar.ca.gov licensee search\n         (if the visitor came here trying to look up a lawyer, send them\n         to the authoritative source — that's the §6155-correct move)\n- Big italic '404' watermark stays at 5% opacity behind the content\n  (was 8% — softened so it doesn't fight the suggest-grid for attention)\n- CTA gradient → flat noir + champagne hairline (consistent with\n  iter 24's editorial CTA standard, replacing brushed-metal that read\n  too 'marketing landing')\n- Footer adds 'Methodology v1.0' link (closes another link to the\n  iter-29 substantiation document)\n\nRemoved cta-primary brushed-metal gradient (luxury-watch-ad feel\nflagged in iter 24 critique). All CTAs now flat noir + champagne\nhairline + letter-spacing-on-hover.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"370aff1","date":"2026-05-04 03:20:45 -0700","author":"SteveStudio2","subject":"Iter 30: /signup + /login submit-disable + loading state","body":"Applies the iter-27 loading-state pattern to both auth forms.\n\n/signup (was: 'Claim your listing →' static button → vanilla form post):\n- 'Claiming your listing…' loading text + champagne-disc spinner\n- Button disabled on submit; data-loading-text drives the swap\n- Prevents double-submit during bcrypt password hash + DB INSERT\n\n/login (was: 'Sign in →' static button):\n- 'Signing in…' loading text + spinner\n- Same submit-disable JS pattern\n\nShared CSS in portal layout:\n- button.big-btn:disabled — oxidized gradient + .7 opacity (matches the\n  /upgrade .up-cta:disabled / /find-a-lawyer .cta-metal:disabled style)\n- button.big-btn .cta-spinner — 13px champagne-bordered ring\n- @keyframes portal-spin (720ms linear infinite)\n- prefers-reduced-motion: animation disabled, spinner stays as static\n  champagne dot so the loading state still reads as a state change\n\nBoth auth surfaces now match /find-a-lawyer (consumer) and /upgrade\n(payment) for submit-feedback consistency. Slow-network attorneys no\nlonger see a 'hung browser' on signup or login.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"c9f2fae","date":"2026-05-04 02:53:16 -0700","author":"SteveStudio2","subject":"Iter 29: /methodology page — closes the Rule 7.1 substantiation gap","body":"Two prior iterations (iter 26 audit, iter 28 directory) referenced\n\"methodology v1.0\" without a real document to point at. Both critiques\nflagged this as the largest substantiation gap. This iter ships the\ncanonical document.\n\nNEW: public/methodology.html — full editorial substantiation document:\n\n1. Twelve signals enumerated, each with:\n   - Italic Roman numeral (i. through xii.)\n   - Plain-English description\n   - Inline <code> with the actual technical name (HTTPS, og:image,\n     application/ld+json, etc.) so the criteria can be verified by\n     anyone with browser devtools\n   - Point weight (15+10+10+10+10+10+10+5+5+5+5+5 = 100)\n   The twelve match exactly what src/enrich/site_audit.ts measures.\n\n2. Tier thresholds table — High 90+, Mid 70-89, Low 50-69, Weak <50.\n   Each tier in its own champagne shade matching the audit cards.\n\n3. \"What this score is NOT\" disclosure block — explicit boundaries:\n   - Not a measure of legal skill, courtroom outcomes, expertise\n   - Not a measure of client satisfaction, retention, reputation\n   - Not a measure of bar standing, malpractice, or discipline\n   - Not an endorsement\n   - Audit independent of any commercial offering; purchasing\n     EZ Upgrade does not adjust the score.\n\n4. Refresh cadence (90-day rolling, on-demand re-audit available)\n\n5. Corrections & removal — audit@agentabrams.com, 5-business-day SLA\n   for re-audit. Directory listing draws on State Bar public roll;\n   removal must be requested at the State Bar directly.\n\n6. Versionbar at the bottom — Version v1.0 / Last reviewed 2026-05-04\n   / Next scheduled review 2026-08-01.\n\nWired up:\n- public/audit.html keystrip — \"Methodology v1.0 · 12 signals · how\n  we score →\" now links to /methodology.html (was bare label)\n- public/audit.html per-card stamp — \"Audited [date] · methodology\n  v1.0\" now linked\n- src/server/directory.ts score panel — \"Site signals · methodology\n  v1.0 →\" now linked\n\nBrand: Volume strip, italic-metal display, monogram, hairline-rule\nsections matching the rest of the site. No Rule 7.1 fabricated stats.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"afcb5d7","date":"2026-05-04 02:23:48 -0700","author":"SteveStudio2","subject":"Iter 28: /directory — champagne tiers + monogram + Volume strip + critical compliance decoupling","body":"Visual:\n- Monogram added to brand header (was bare text)\n- Volume strip 'Edition 2026 · Attorney Self-Service'\n- Italic-metal display 'Find your firm. Audit your site. Reserve an EZ Upgrade.'\n- Score colors traffic-light → champagne tiers (tier-a/b/c/d/x), tabular-nums\n- 'Marketing health score' → 'Site signals · methodology v1.0' (matches /audit.html)\n- Lede: 'twelve published signals'; 'typical go-live: seven business days from content intake'\n\nDebate-team-fast caught CRITICAL pay-to-play §6155 risk that I fixed before commit:\n\n1. SCORE-UPGRADE DECOUPLING — old layout: low-score panel → directly into\n   $499 EZ Upgrade pitch with copy 'designed to close the gap your audit\n   just exposed.' That's a textbook §6155 implication: directory shows a\n   score, then sells you a fix for the score. Replaced with:\n     a. <details> disclosure 'See what an EZ Upgrade looks like for this\n        firm' between score and pitch — pitch is now collapsed by default\n        so a low score doesn't auto-render a paid-product offer next to it\n     b. 'Designed to close the gap your audit just exposed' copy DELETED.\n        Replaced with neutral 'An independent site-build service offered\n        by Counsel & Bar. Available to any California-licensed attorney\n        whether or not they're audited; the directory listing remains\n        free either way.'\n     c. Price card adds line 'Site-build service. NOT a directory\n        placement fee.'\n\n2. 'WHAT THIS SCORE IS AND ISN'T' aside between score and upgrade — Rule\n   7.1 substantiation block: 'measures twelve technical/presentation\n   attributes... it is not a measure of legal skill, client outcomes, or\n   professional reputation.' Plus 'audit is independent of and not\n   contingent on the upgrade purchase' explicit decoupling.\n\n3. PRICE FONT WEIGHT REDUCED — was 72px metal-glow $499 directly under\n   96px metal score, reading like 'big number → big number → buy.' Price\n   now 48px ink-soft. Score remains the dominant numeral on the page.\n\n4. NO-AUDIT FALLBACK COPY rewritten — removed 'we'll run a full audit as\n   part of the upgrade' (bundles audit into paid product). Now: 'Site\n   not yet audited. Methodology v1.0 covers twelve published signals.\n   We'll add this firm to the audit queue if you claim the listing.'\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"50c720e","date":"2026-05-04 01:53:13 -0700","author":"SteveStudio2","subject":"Iter 27: /find-a-lawyer submit-disable + loading state + 'curated'→'indexed' compliance fix","body":"VISUAL: form submit now shows 'LOGGING YOUR INQUIRY…' + champagne-disc\nspinner, button .is-loading state with darker gradient + .7 opacity to\nread as disabled. Prevents double-submit and gives feedback during\nPOST→/thanks redirect (felt broken on slow connections).\n\nCSS: .cta-metal:disabled (oxidized gradient + opacity), .cta-spinner\n(14px champagne-bordered ring + cta-spin keyframe), prefers-reduced-\nmotion fallback (no spin, just static dot).\n\nJS: form.config submit handler disables button + flips text via\ndata-loading-text attribute. data-default-text preserved for potential\nrestore-on-error path (not wired yet).\n\n§6155 COMPLIANCE FIX (caught in this iter):\n\"curated\" → \"indexed\" across 4 surfaces:\n- public/index.html meta description + H1 hero (\"Every licensed\n  attorney in California, indexed.\")\n- src/server/leads.ts meta description template + /find-a-lawyer\n  H2 display (\"Find your California attorney, indexed.\")\n\n\"Curated\" implies editorial selection of attorneys, which is exactly the\nlanguage §6155 attaches to lawyer referral services. We're a directory\nof every CA-licensed attorney drawn from the State Bar public roll —\nthe right word is \"indexed.\" Also factually more accurate; we don't\nmake selection judgments, we list everyone.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"95b1ccc","date":"2026-05-04 01:23:53 -0700","author":"SteveStudio2","subject":"Iter 26: /audit.html — champagne-tier scoring + critique-applied refinements","body":"Replaced traffic-light RGB color logic with champagne-tier palette matching\niter 22's firm-card chips on /find-a-lawyer/results:\n\nScores:\n- tier-a (90+): metal-glow #d4b683\n- tier-b (70-89): metal #b89968\n- tier-c (50-69): oxidized #a07a40\n- tier-d (<50): deeper oxidized #5a4220 (widened from #6e5530 per critique\n  for better thumbnail-scale legibility)\n- tier-x (null): muted ink + italic + smaller scale + serif\n\nSignal pills:\n- 'on': champagne-tint background + metal-glow text + champagne hairline\n- 'off': transparent + muted ink + 55% opacity + thin strikethrough\n  (replaces red/green traffic-light pill bgs; strikethrough disambiguates\n  off-state per critique without screaming 'fail')\n- removed ✓/✗ glyphs; pill text says signal name only\n\nDebate-team-fast critique applied:\n\n1. RULE 7.1 LANGUAGE — \"marketing health\" was clinical-judgment-y next\n   to real attorney names. Renamed to \"site signals\" (cards) and the\n   keystrip masthead. Lower comparative-claim risk.\n\n2. METHODOLOGY VISIBLE — keystrip now shows \"Methodology v1.0 · 8 signals\n   · refreshed weekly\" right-aligned. Per-card \"Audited [date] ·\n   methodology v1.0\" stamp added above suggestions block. Anchors the\n   public score to disclosed criteria — biggest 7.1/7.2 risk-reducer\n   per Kimi.\n\n3. REDUNDANT GRADE LETTER REMOVED — was rendering \"100 A+\" / \"95 A\"\n   alongside numeric (dual-encoding read as report-card, undid the\n   non-punitive frame). Cards now show numeric only; A/B/C tiers\n   reserved for future cohort-distribution view where they'd earn it.\n\n4. PILL NAMES NEUTRALIZED — \"OG image\" → \"Social card\", \"Mobile\" →\n   \"Mobile-ready\", \"H1\" → \"H1 heading\", \"Phone shown\" → \"Phone visible\".\n   Plain attribute language; less jargon, less ambiguous when struck\n   through.\n\n5. LEGEND BUCKETS — was \"80+/60-79/<60\" (3 buckets). Now matches actual\n   tier boundaries: \"90+/70-89/50-69/<50\" (4 buckets, aligned with\n   tier-a/b/c/d). Plus \"Weak\" label for the lowest tier.\n\n6. SCORE FONT 36px → 42px for stronger visual anchor in the column.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"85d7704","date":"2026-05-04 01:19:26 -0700","author":"SteveStudio2","subject":"upgrade.ts: harden ?_demo=paid gate against Host-header spoofing","body":"Replaced req.hostname check (spoofable when Express has 'trust proxy' or\nwhen reverse proxies forward arbitrary Host headers) with strict\nNODE_ENV !== 'production' gate. Local-dev preview still works on dev\nmachines; production traffic can no longer trigger the paid branch via\ncrafted Host header.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"bf9516d","date":"2026-05-04 00:52:41 -0700","author":"SteveStudio2","subject":"Iter 25: /upgrade/thanks — post-Stripe-success editorial confirmation","body":"Replaced bare 4-line paid-success page with full editorial confirmation:\n- Volume strip masthead 'Edition 2026 · Order Confirmed'\n- Italic-metal display 'Order received, counselor.'\n- Order № receipt strip (3 cols: Order № EZ-YYYY-MMDD-NNNN / Logged\n  timestamp / Charged $amount italic-metal tabular-nums)\n- 'What happens next' 3-cell hairline-ruled grid:\n  * i. Intake brief — within 24 hours\n  * ii. First proof — five business days (7-day go-live clock starts here)\n  * iii. Revisions & go-live — 14-day window\n- Footer: refund + buyer-delay carve-out + 'Open dashboard →' quiet CTA\n- 'For the record' trust block: §6155 + neutral proximity ranking +\n  Stripe PCI flow + Rule 7.x buyer-responsibility line\n\nLocalhost-only ?_demo=paid flag for visual testing (gated on hostname).\n\nStripe checkout product description updated: 'live in 7 days' (unconditional)\n→ 'typical go-live: 7 business days from content intake' — was emitting on\ncustomer Stripe receipts, fixed at source.\n\nDebate-team-fast critique applied:\n1. PROMISE CALIBRATION — defined 'two rounds of substantive revisions'\n   as 'copy edits, image swaps, layout adjustments within the original\n   four-page scope. New pages or scope changes are quoted separately.'\n   Closes the FTC §5 ambiguity around 'substantive.'\n2. BUYER-DELAY CARVE-OUT — 'Timeline begins on receipt of your content\n   brief; delays in returning the brief shift the proof and go-live\n   dates by the same number of days.' Closes the unconditional-SLA gap.\n3. RULE 7.X CLARIFICATION — added to trust block: 'Site copy you supply\n   or approve remains your professional responsibility under California\n   Rule of Professional Conduct 7.x — we can flag obvious advertising-\n   rule risks but do not provide legal review.'\n4. YEAR-2 HOSTING — 'invoiced separately at our standard rate' →\n   'billed separately at our published rate' (rate must be public, not\n   discretionary).\n\nPending for next iter: pull payment-method last-4 + Stripe lockup from\nPaymentIntent metadata into the receipt strip ('Visa •••• 4242 ·\nprocessed by Stripe') — currently absent, the only element that reads\n'demo' rather than 'production' on this surface.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"b93b18b","date":"2026-05-04 00:20:38 -0700","author":"SteveStudio2","subject":"Iter 24: /upgrade EZ Upgrade page — editorial pass + critique-applied compliance fixes","body":"Visual upgrade:\n- CB monogram added to brand header (was bare text)\n- Volume strip masthead 'Edition 2026 · EZ Upgrade · One-time $499'\n- Italic-metal display 'Reserve your EZ Upgrade.'\n- Hairline-underline configurator inputs (no boxes, focus to champagne)\n- Sticky order-summary aside with hairline rules + italic-metal '$499'\n- Big italic-metal '$499' total + 'INCLUDED' caps for free items\n- Scroll-reveal stagger\n- Submit-disable JS prevents double-charge during Stripe redirect\n\nDebate-team-fast critique applied (live-Stripe page = high-risk):\n\n1. FALSE-TRUST FIX (highest priority) — replaced literally-inaccurate\n   \"Counsel & Bar never sees your card\" with accurate Stripe disclosure:\n   \"Your full card number stays with Stripe; Counsel & Bar receives only\n   the last four digits and billing details needed for your receipt and\n   refund processing.\" Stripe ToS + deceptive-practices issue closed.\n\n2. RULE 5.4 / §6155 BUNDLE FIX — removed \"Counsel & Bar listing — premium\n   tier · INCLUDED\" line from $499 order summary (was implying directory\n   placement is something you pay $499 for). Replaced with explicit\n   disclaimer: \"This is a site-build service, NOT a directory placement\n   fee. The Counsel & Bar listing remains free for any California-licensed\n   attorney whether or not they purchase this upgrade.\"\n\n3. FTC FALSE-ADVERTISING SOFTENED — \"Live in seven days\" (unconditional)\n   → \"Typical go-live: seven business days from content intake.\" Same\n   for revisions/hosting wording.\n\n4. LRS-FLAVOR REMOVED — \"the standard the directory deserves\" implied the\n   directory judges attorneys → \"the standard your firm deserves.\"\n\n5. CTA TONE CORRECTED — brushed-metal gradient (luxury-watch-ad) replaced\n   with flat-noir + champagne hairline + champagne text + letter-spacing\n   ease on hover. More restrained, more DB12, less marketing-landing.\n\n6. BUILD AGREEMENT inline disclosure under CTA (no dead /terms link):\n   \"By continuing you agree to the Build Agreement: seven-business-day\n   typical go-live from content intake, 14-day revision window from\n   first proof, first-year hosting included, full refund any time\n   before first proof. Site-build deliverable only.\"\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"1982ca0","date":"2026-05-03 23:48:36 -0700","author":"SteveStudio2","subject":"Iter 23: /signup/welcome editorial confirmation + critique-applied refinements","body":"New surface — fires after fresh attorney signup, before /dashboard. Pattern\nmirrors /find-a-lawyer/thanks: Volume strip + italic-metal display + Listing №\nreceipt + 3-cell path forward + brushed-metal CTA + trust block.\n\nShared portal layout CSS gained: .signup-vol/v-rule/v-text/v-meta,\n.signup-display/-lede, .receipt/-row + .r-label/-val, .thanks-next/-step/\n-grid/-cell/-num/-link, .public-trust/.t-eyebrow, .cta-metal — all duplicated\nfrom leads.ts so /dashboard, /login, and welcome share the masthead pattern.\n\nRouting: POST /signup with no explicit ?next= now redirects to /signup/welcome\ninstead of straight to /dashboard. Existing ?next= deep-links honored.\n\nDebate-team-fast critique applied immediately:\n1. COMPLIANCE — masthead changed \"Listing Claimed\" → \"Listing on File\"\n   (registrar voice, quieter §6155 posture). Added micro-disclaimer ABOVE\n   headline: \"Counsel & Bar is a directory, NOT a lawyer referral service\"\n   (Rule 7.x conspicuousness rule — disclaimer ≥ firm-name claim).\n2. COPY — \"shows up where consumers look\" → \"listed alongside other\n   California-licensed attorneys in proximity-ranked search results.\"\n3. OVERSTATEMENTS REMOVED:\n   - Cell i: dropped \"we cross-check within 24 hours and tag Bar-verified\"\n     (promised non-existent worker) → \"calbar.ca.gov remains authoritative\"\n   - Cell ii: dropped \"profiles with bios surface above otherwise-equal\n     cards\" (fabricated Rule 7.x ranking-stat) → \"every field rendered as\n     you wrote it. We don't edit, embellish, or rank by paid tier.\"\n   - Cell iii: dropped \"Nothing curated\" (literally false — we do rank +\n     audit-grade) → \"rendered straight from the State Bar record\"\n4. DEAD ANCHORS FIXED — /dashboard now has <section id=\"bar\"|\"profile\"\n   |\"preview\"> wrappers + scrollIntoView(location.hash) script. The three\n   \"Open dashboard / Edit profile / Preview public listing\" links from\n   /signup/welcome now actually scroll to a target.\n5. Profile + Preview placeholder sections added to /dashboard so the\n   anchors land on real content (not bare empty divs).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"8cae410","date":"2026-05-03 23:29:49 -0700","author":"SteveStudio2","subject":"Iter 22: enrich populated /results firm cards with audit-grade + size chips","body":"Each firm card now displays three info chips between meta-line and actions:\n\n1. Site audit chip — buckets marketing_score 0-100 into A/A−/B+/B/B−/C+/C\n   grades via auditChip() helper. Score null → \"unaudited\" (Inter caps,\n   distinguishable from graded italic-metal). Color tiers: A = metal-glow\n   (champagne hot), B = metal (champagne cool), C = #a07a40 (oxidized).\n\n2. Firm size chip — band (\"solo\"/\"small\"/\"medium\"/\"large\") via sizeChip(),\n   falls back to \"N attorneys\" when band is null.\n\n3. Verify-on-State-Bar micro-link — direct query into apps.calbar.ca.gov\n   licensee search w/ firm name pre-filled. Dotted underline → solid\n   champagne on hover. Compliance asset: turns the State Bar from a footnote\n   into a per-firm CTA.\n\nCSS: .firm-chips row, .firm-chip pill (hairline rule, label-uppercase + serif\nitalic value), .firm-verify dotted-underline. .firm-card:hover lifts chip\nborder to .4 metal alpha. Print stylesheet untouched (chips inherit color\noverrides naturally).\n\nThe marketing_score column was already retrieved by match_firms.ts via\nsite_audits subquery; this is the first surface to render it.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"4704a6f","date":"2026-05-03 23:19:55 -0700","author":"SteveStudio2","subject":"Add 7 Express route modules: auth, admin, billing, community, directory, showcase, upgrade","body":"- src/server/auth.ts (144 LOC) — bcrypt session auth, /signup POST + /login POST\n- src/server/admin.ts (537 LOC) — admin dashboard, queue review, manual veto on lead matches\n- src/server/billing.ts (189 LOC) — Stripe checkout sessions, tier upgrades, webhook handler\n- src/server/community.ts (652 LOC) — community board (questions/replies/views), per-tier gating\n- src/server/directory.ts (493 LOC) — public firm/attorney detail pages\n- src/server/showcase.ts (607 LOC) — mockup template gallery + per-firm rendered showcase\n- src/server/upgrade.ts (331 LOC) — EZ Upgrade $499 funnel + post-checkout site provisioning\n\n.gitignore: also exclude tmp/ (45 MB of walker scratch).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"03e8b75","date":"2026-05-03 23:19:24 -0700","author":"SteveStudio2","subject":"Loop housekeeping: migrations, ingest scripts, compliance docs, build-agent automation","body":"Migrations 003-018: site_audits, app_users (+profile), leads, upgrade_orders,\nprof_loc_unique, site_mockups (+extras), data_orders, contact_crawled_at,\nuser_tiers, ratings, community + replies/views, message_user_fk fix, site_intel.\n\nIngest:\n- calbar_full_scrape.ts (full attorney scrape, bar# 29960→360000, conc=5)\n- here_discover.ts (HERE Maps Discover API enricher for phone/website,\n  free-tier 30k/mo, 8,244 LA firms target)\n\nEnrich:\n- discover_websites.ts (web-search firm-website discovery)\n- geocode_nominatim.ts (lat/lng for organizations)\n- render_mockups.ts (Playwright mockup-template renderer)\n- site_audit.ts (HEAD/GET timing + headers + marketing_score)\n\nScripts:\n- build-agent/* (launchd watchdog/progress/nightly/weekly cadence)\n- take-shots.mjs, click_through.ts (Playwright walkers)\n- create_admin.ts (admin user provisioner)\n- probe_calbar.ts (smoke test)\n- setup_stripe_*.ts (lawyer-pro price + webhook + tier-webhook)\n- run_overnight.ts (overnight pipeline orchestrator)\n\nDocs:\n- COMPLIANCE.md (Cal §6155 / Rule 7.x / 5.4 / CCPA standing rules)\n- legal/attorney-engagement-letter.md (canonical engagement-letter draft)\n- legal/MEETING_FOLLOWUP_2026-05-03.md (codex meeting verification)\n- legal/PLATFORM_DECISION_2026-05-03.md (separate-repo vs monorepo decision)\n- docs/COMMUNITY_PLATFORM_SPEC.md (PawCircles-style community sub-brand spec)\n- CHANGES.md / CHANGES2.md (codex review applied-fix log)\n\nFrontend:\n- public/dashboard.html (admin dashboard, will be migrated to portal.ts later)\n\nBuild/walker artifacts:\n- _clickthrough.mjs (Playwright site walker w/ Steve avatar PiP, video out)\n- _shoot_mobile.mjs (375x812 mobile probe for overflow detection)\n\n.gitignore: exclude public/screenshots, public/mockups, public/qa-shots,\npublic/mockup-templates (6+ GB of generated artifacts), *.webm, *.mp4.\n\n.env.example: placeholder env template (no real keys).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"ade90a7","date":"2026-05-03 23:14:07 -0700","author":"SteveStudio2","subject":"Counsel & Bar visual loop: 21 iterations of Aston Martin DB12 / Genesis G80 redesign","body":"Surfaces redesigned with cinematic noir + champagne-metal aesthetic:\n- Landing (/) — italic Roman watermark, proof strip with real CA firms, scroll-reveal stagger\n- /find-a-lawyer — 3-section configurator with outlined italic Romans (i/ii/iii)\n- /find-a-lawyer/thanks — Volume strip + Inquiry № receipt with print stylesheet\n- /find-a-lawyer/results — proximity-ranked firm cards + reason-branched empty state\n- /signup — Volume strip + outlined italic Romans replacing Step 01-04\n- /login + /dashboard — matching Volume strip masthead + italic-metal display\n- /data — champagne-tier compliance callout (replaced amber-warning aesthetic)\n- /audit + /privacy + /terms — monogram + Volume strip + italic-metal display\n\nBrand tokens: --noir #0a0a0c, --ink #f4f1ea, --metal #b89968 (champagne),\nbrushed-metal CTA gradient, Cormorant Garamond italic + Inter sans pairing.\n\nCompliance: §6155 directory-not-referral language, Rule 7.x no-fabricated-stats,\ntrust block conditional on populated vs empty results.\n\nA11y: scroll-reveal honors prefers-reduced-motion, :focus-visible champagne ring,\n@media print stylesheet on /thanks for receipt printing.\n\nIter 21 specifically: editorial empty state on /results with reason enum\n(no_anchor / no_firms_in_radius / ok / no_zip) — replaces misleading LA-fallback\n'near {ZIP}' claim that displayed downtown LA firms for unknown ZIPs.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"331776b","date":"2026-04-30 01:48:00 -0700","author":"Steve Abrams","subject":"Dashboard: add professionals + phones + emails counters; new wiki-lawyers importer","body":"- /api/stats now returns professionals_total, phones_total, emails_total\n- Header shows: firms · lawyers · geo-mapped · phones · emails · multi-firm bldgs · cities\n- Numbers formatted with thousands separators\n- src/ingest/wikipedia_lawyers.ts: ingests Category:Lawyers_from_Los_Angeles\n  + Category:California_lawyers (~880 articles). Extracts birth/death year,\n  education, firm, position from .infobox. Inserts into professionals; if firm\n  matches an existing organization, also creates professional_locations link."},{"hash":"fd5c251","date":"2026-04-30 01:12:22 -0700","author":"Steve Abrams","subject":"Add Wikipedia infobox enricher + firm-website contact crawler","body":"- src/ingest/wikipedia_infobox.ts: pulls Category:Law_firms_based_in_Los_Angeles\n  + Category:Law_firms_based_in_California (28 articles), parses .infobox table\n  for headquarters, founded year, lawyers count, revenue, website. Updates\n  attorney_count + firm_size_band where missing.\n\n- src/enrich/firm_website_contacts.ts: for the 154 firms with websites,\n  fetches homepage + likely contact pages (/contact, /about, /our-team, etc.),\n  regex-extracts emails + phones, inserts into emails/phones tables.\n  Robots-respected via fetchCompliant. 0.5 rps default.\n\n- docs/blocked_sources.md: documented adjacent-city ArcGIS Hub portals\n  (Beverly Hills, Santa Monica, Pasadena, Long Beach) — all client-rendered\n  SPAs with no DCAT feed, blocked without per-portal investigation or Playwright."},{"hash":"c99aeb7","date":"2026-04-30 01:05:51 -0700","author":"Steve Abrams","subject":"Add OSM name-match importer + ghost-address cleanup","body":"- src/ingest/osm_name_search.ts: broader Overpass query for any LA-County\n  named entity matching legal-services vocabulary (law offices, attorneys,\n  counsel, legal, esquire). Excludes amenity tags that are clearly not firms\n  (school, restaurant, hospital, etc.). Yielded 0 incremental on first run —\n  office=lawyer already covers OSM's named LA legal entities. Keeping the\n  importer for future runs as OSM data grows.\n\n- Cleanup: 23 organizations had degenerate address values ('Los Angeles',\n  ', Los Angeles, CA', etc.) from upstream sources with empty street_address.\n  NULLed those so they don't pollute multi-firm building detection."},{"hash":"cec3ccf","date":"2026-04-30 01:00:23 -0700","author":"Steve Abrams","subject":"Add LA City Active Business Licenses importer (NAICS 5411)","body":"7,992 LA City legal-services businesses imported via Socrata API.\nDatabase grew 251 → 8,198 firms. Multi-firm buildings 4 → 585.\nGeo-mapped coverage 223 → 7,342.\n\nReal biglaw clusters now visible: 2049 + 2121 + 1801 Century Park East\n(Century City), 355 S Grand DTLA, 12100 Wilshire Westwood.\n\nFree, no key required. Filter: NAICS 541100 / 541110 / 541199. Excludes\nnotaries (541120) and title offices (541191) which aren't lawyers.\nDedup: address_norm + name match, then name + city fallback."},{"hash":"6003ada","date":"2026-04-30 00:50:47 -0700","author":"Steve Abrams","subject":"Dashboard: Grid + List + Map views with column slider","body":"- Three view modes: Grid (default), List (sortable spreadsheet), Map (preserved Leaflet)\n- Top-right toggle to switch views; localStorage remembers last choice\n- Grid column slider 3-12, default 5; localStorage remembers last value\n- List view: click column headers to sort (firm, city, address, phone, website, size, attys)\n- Firm size pills color-coded (biglaw / large / medium / small / solo)\n- Map lazy-init on first open (faster initial paint)\n- City drill-down filters all three views simultaneously"},{"hash":"9315e69","date":"2026-04-30 00:35:33 -0700","author":"Steve Abrams","subject":"Initial commit: LA Lawyer Directory — office-mapping pipeline","body":"- Compliance-first PostgreSQL schema (organizations, professionals, professional_locations, bar_admissions, education, emails, phones, sources, raw_records, scrape_jobs, schema_migrations)\n- OSM Overpass importer (196 LA County firm offices, geo-tagged)\n- Wikidata SPARQL importer (29 LA biglaw firms: Latham, Gibson Dunn, Paul Hastings, Manatt, Lewis Brisbois, etc.)\n- Express read API + Leaflet dashboard on :9701\n- Robots-aware compliance helper (rate limit, captcha detection, no bypass)\n- Overnight orchestrator with checkpointed scrape_jobs\n- Documented blocked sources (CA State Bar, CA SOS bizfile) requiring Playwright pass\n"}]}