← Back to SEO Report ← Page analysis

Miami Hit and Run Accident Lawyer — SEO Improvements

injury-law/miami-hit-and-run-accident-lawyer  ·  Gallardo Law Firm  ·  Audited 2026-08-18, 22 logged entries (a)–(v) through 2026-08-21  ·  En / article.cshtml + articlemetas.cshtml + FaqEntities.xml + ServiceEntities.xml + 5 other pages

URL https://gallardolawyers.com/injury-law/miami-hit-and-run-accident-lawyer
Target Keyword miami hit and run accident lawyer
2,1627,104
Scope words, raw (+229%)
2,0936,049
Main content column (En)
0983
FAQ words · 10 of 10 slots
15+1717+22
H2 + H3 headings
14
JSON-LD blocks · 2 speakable ids
05
Data tables · 0 → 2 ordered lists
35
Outbound internal links
16
Inbound internal links
THE HEADLINE: 1,596 impressions across 132 queries produced ZERO clicks. CTR is 0.00% on every single query. The page is being served — it just converts nothing. And the reason is visible in one row: the page's own target, «miami hit and run accident lawyer», is 10 searches a month and sits at position 33.2, while «hit and run accident lawyer» (4,400 vol) already ranks 7.5 and «hit and run lawyer» (8,100 vol) ranks 11.7. The title, H1 and URL are all built on a keyword almost nobody searches, while the page already ranks top-10 for the terms that have the demand.
Meta Tags — entry (u), the CTR pass · the first edit ever made to articlemetas.cshtml
Everything in (a) to (t) affects whether the page RANKS. Title and description are the only elements that affect whether anyone CLICKS — and they had never been touched. The page can rank at 7.5 and still earn nothing, which is exactly what the GSC export shows it doing. The metas were flagged as untouched in (h), (o) and (q); this entry is why those flags exist.
miami-hit-and-run-accident-lawyer / En / articlemetas.cshtml
@* TITLE — NOT TOUCHED, ON PURPOSE. 69 chars. "| Injury Claims |" earns nothing and pushes the brand past 60, but the page ranks 7.5 for its primary term and the title is the element most likely to move that. Separate decision, real downside, not part of this instruction. *@
@* The write script ASSERTS the title still contains "Injury Claims" after writing, so this entry cannot change it by accident. *@
<title>Miami Hit and Run Accident Lawyer | Injury Claims | Gallardo Law Firm</title>

@* DESCRIPTION — 155 chars -> 157. Opens on the reader's own situation, carries a number no competitor snippet has, and answers the question these searchers actually arrive with. *@
@* was: Injured in a hit-and-run accident in Miami? Our lawyers help victims recover compensation for medical bills, lost wages, and damages. No fee unless we win. *@
<meta name="description" content="Driver fled the scene? Nearly 1 in 3 Miami-Dade crashes is a hit-and-run. Our Miami hit and run accident lawyers pursue compensation even if no one is found." />
<link rel="canonical" href="https://gallardolawyers.com/injury-law/miami-hit-and-run-accident-lawyer" />

@* SOCIAL IMAGE — 375x211 is BELOW what the platforms will render as a card, so shares of this URL were showing as a bare text link. The 903x530 asset ALREADY EXISTED on disk; nothing was generated or uploaded. *@
<meta property="og:image" content="https://gallardolawyers.com/themes/gallardo/images/services/903x530/miami-hit-and-run-accident-lawyer.jpg" />
<meta property="og:image:width" content="903" />
<meta property="og:image:height" content="530" />
@* summary -> summary_large_image. Matches miami-wrongful-death-lawyer, which already used 903x530 — a pattern was FOUND, not invented. *@
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="https://gallardolawyers.com/themes/gallardo/images/services/903x530/miami-hit-and-run-accident-lawyer.jpg" />

@* MAINTENANCE — the description is applied IDENTICALLY to name="description", og:description and twitter:description. THREE SURFACES. If one changes, change all three. Replacement counts were asserted before writing: description 3x, image 2x, width 1x, height 1x, card 1x. *@

What was dropped, deliberately — «No fee unless we win». A proven CTR driver, and removing it was a judgement call, not an oversight. Every competitor snippet on this SERP says some version of it, so it differentiates nothing, while the 1-in-3 statistic appears in none of them. 157 characters does not hold both. FLAG: if the firm wants contingency-fee language back it has to displace something, and the statistic is what makes this snippet different from the other nine.
Length was measured, not eyeballed. The first draft was 170 chars and was rejected because Google truncates near 155–160 and «Free consultation.» would have been cut. Four variants were measured and the 157 kept. Checked against Fla. Bar Rule 4-7.13 before writing — the script asserts against a banned list including «maximum compensation», the phrase removed from the page body in (o).
Still short of ideal: 1200×630 is the recommended social size and no such asset exists. 903×530 is the largest available at the correct aspect ratio.

Keyword Coverage — Was / Now — 221 rows · 72 up · 12 down · 7 unchanged · 130 absent from the page in both scans
GSC last 3 months, page-filtered, exported 2026-08-18  ·  Semrush gap + bulk US, 2026-08-18  ·  scope = metas + content + FAQs + alts
Keyword / queryGSC impPosVolKDBeforeNowΔNote
gallardo law firm1391.076−1brand — the only query on the page ranking position 1
hit and run accident attorneys1319.8590402+2⭐ ENTERED THE PAGE. KD 4, already ranking 9.8, and the plural had never appeared once. Added in (g) and (b)
hit and run lawyer miami11630.4902220−2LEFT THE PAGE, deliberately — 3rd highest query by impressions. Both instances were the stuffed «A hit and run lawyer Miami can…» sentences removed in (k). Still flagged
miami hit and run accident lawyer9633.210089+1⚠ PRIMARY — title, H1, URL, canonical. Volume 10/month at position 33.2. The page's own target is nearly dead
hit and run accident lawyers809.15901122=plural, meta + body only
miami hit and run car accident injury lawyer6911.10500=PHANTOM — volume 0, below Semrush's reporting threshold. Impressions without a market
hit and run accident lawyer687.544008811+3⭐ THE REAL TARGET — 4,400 vol at KD 8, already position 7.5. Best volume-to-position ratio on the page
hit and run accident lawyers near me5912.0901100=GAP — «near me» cluster ≈1,680 vol across 3 variants, all at position ~21, none in copy. Served by FAQ 10 only
miami failure to yield accident injury lawyer498.50300=PHANTOM — one of 45 «miami <cause> injury lawyer» queries, all volume 0. Do not build copy for them
lawyers for hit and run4710.0480600=GAP — KD 6 at position 10, phrase absent
hit and run lawyer near me3421.1720900=GAP — biggest «near me» variant. Deliberately NOT forced into body copy; it reads as spam
hit and run lawyer3311.781001243−1⭐ HIGHEST VOLUME practitioner term on the page. Lost 2 to the (k) stuffing cleanup, regained 1 in the (o) rebalance
hit and run accident attorney329.92400528+6⭐ LARGEST GAIN among practitioner terms. KD 5 at position 9.9 — the cheapest available win, and the page said «lawyer» almost exclusively
hit and run attorney near me2720.94801400=GAP — «near me» is a Google Business Profile job, not a copy job. See the Local pack note in (i)
miami hit and run lawyer2421.21403621−1traded down in (l) to recover «hit and run attorney» — 3,600 vol against 140. The better trade by volume
hit and run attorney2315.836001022=fell to 1 in the (k) cleanup, RECOVERED in (l) — a deliberate re-edit of an earlier edit
hit and run lawyers near me2320.84803000=GAP — third «near me» variant
hit and run lawyers710.316001101+1ENTERED THE PAGE — 1,600 vol, ranking 10.3, phrase had never appeared. Added in (o) via heading-14
lawyer for hit and run accidents59.8110501+1NET ADDITION in (p) — heading-14, displaces no existing term
attorney for hit and run611.0140801+1NET ADDITION in (p) — heading-12. First attempt put it in heading-8 and cost an 8,100-vol term; caught by recount and moved
florida hit and run accident attorney19.070001+1NET ADDITION in (p) — heading-15. Also gives the copy the statewide reach the Service schema already claimed
hit and run (root term)222005762144+82⚠ DENSITY 8.22% → 5.78% without removing a single instance — the page grew around it. Still above the 1–3% comfort range
hit and run accident1300332644+182.35% density
florida statute540042116+15⭐ NOT proportional to page growth — this tracks the statutes the page now cites, where it previously cited one
leaving the scene110527+5KD 5 and its SERP carries an AI Overview — unusually cheap for this set. The (m) rewrite took it DOWN 7→6 first; caught by recount and fixed in the same stroke
felony19+8the four-tier penalty table added in (m), s. 316.027
personal injury protection440070311+8the $10,000 minimum and the 14-day treatment deadline, added in (a)
uninsured motorist290067715+8GUARD RAIL — measured against the dedicated UM page after every edit. That page still owns the term at more than double the density
driver24100+76largest single-word gain
florida1575+60statute citations + the statistics section
crash1769+52body throughout
claim1556+41the case-steps and timeline section (f)
evidence826+18heading-8, restructured by WHO HOLDS THE EVIDENCE
maximum compensation20−2REMOVED ON PURPOSE — Fla. Bar Rule 4-7.13. One in (g), the last in (o)
car accident10−1REMOVED ON PURPOSE — widens separation from miami-car-accident-attorney, which outranks this page for its own keyword (5.26 vs 33.57)
car accident lawyer in miami016003400=Semrush gap term, absent from page and GSC. Belongs to the sibling page, not this one
Full table: 221 rows = 88 on-page phrases + 132 GSC queries + 165 Semrush keywords, de-duplicated. 164 of the 221 carry Semrush Volume and KD; the 57 without are 16 brand queries, 8 junk/out-of-market queries and 33 single words deliberately not sent to Semrush. Totals: phrases on the page 88 → 91 (5 entered, 2 left) · total occurrences 616 → 1,278 (+107%) · scope words 2,264 → 7,479 normalised.
Corpus, counted identically on both sides: Title + Meta description + the page-title banner (H1 and breadcrumb) + the main content column + the FAQ block + image alts. Global header, nav, sidebar and footer excluded. Normaliser: lowercase, «&» → «and», every non-alphanumeric run → a single space, so «hit-and-run» and «hit and run» collapse onto one row. Overlapping matches counted. «Before» is a RE-SCAN, not a copy of the old numbers — every stored figure reproduced exactly, which is what makes the two columns provably comparable.
Counts are substring counts, so a shorter phrase also increments inside a longer one — «miami hit and run accident lawyer» sits inside «hit and run accident lawyer», which sits inside «hit and run». The rows are not mutually exclusive and must not be summed. Δ counts a string; it is not a ranking signal and higher is not better — several negative rows above are improvements.
One structural inflation worth knowing: the page renders a jump-link table of contents repeating all 17 H2 headings verbatim, so every heading phrase is counted twice — once in the TOC anchor, once in the heading. It is real indexable text so it is included, but it inflates the head terms by roughly 2×.
What the Data Says — 132 GSC queries + 165 Semrush keywords, and what the SERP actually shows
Source overlap by Src flag  ·  P = on the page · G = ranking in GSC · S = Semrush volume held
Where the 221 rows come from
SrcRowsWhat it means
-GS99Google ranks the page for it, the copy never uses it, and it has real volume — the largest bucket in the table
P-S45on the page and has volume, but zero impressions
P--33on the page, no volume requested (single words)
-G-23ranking but no volume requested — brand and junk queries
--S14Semrush gap keyword, absent from the page AND from GSC
PGS6all three sources
PG-1«gallardo law firm» — brand
The «attorney» variant is the biggest miss — and it was free
The copy said «lawyer» almost exclusively. Every «attorney» phrasing has real volume, low difficulty, and the page already ranked top-10 for several of them without using the word once: hit and run accident attorney (2,400 / KD 5 / pos 9.9) · hit and run attorneys (390 / KD 9 / pos 9.3) · attorneys for hit and run (720 / KD 14 / pos 8.0) · hit and run attorney near me (480 / KD 14 / pos 20.9). KD 5–14 against a page already sitting at position 8–10. This was the cheapest available win and it was being thrown away. Acted on in (g), (b), (j), (l) and (p): «hit and run accident attorney» 2 → 8, «hit and run accident attorneys» 0 → 2, «attorney for hit and run» 0 → 1.
Plurals beat the singular the page targets
  • hit and run lawyers — 1,600 vol / KD 11 / pos 10.3, phrase appeared 0 times NOW 1
  • hit and run accident attorneys — 590 vol / KD 4 / pos 9.8 on 131 impressions NOW 2
  • hit and run accident lawyers — 590 vol / KD 11 / pos 9.1 on 80 impressions HELD AT 2
SERP features, weighted by volume across 48 hit-and-run keywords (50,810 combined volume)
FeatureShare of volumeRead
People also ask100%⭐ TARGET — PAA retrieves passages that ANSWER something. This is why every rewritten heading became a question
Video98%the page's embedded video is generic personal-injury content shared with another page
Reviews90%Google Business Profile territory, not on-page
AI Overview70%⭐ TARGET — tables and definitions are what an AI Overview lifts whole
Video carousel67%same production gap as Video
Local pack35%100% on the «near me» subset. Won by proximity and the GBP — no amount of schema or copy moves it
Featured snippet0%ABSENT ENTIRELY — do NOT optimise for one
Measured from the SERP Features column of the two Semrush bulk exports, weighted by volume. This table set the strategy for entries (g) through (p): the intro opens with a definition and answers the question victims actually arrive with, every thin heading became a question, and five tables were built because a table is the form an AI Overview lifts whole.
Demand that is structurally unconvertible, and was NOT chased. 45 GSC queries in the «miami <cause> injury lawyer» pattern — failure to yield, drowsy driving, tire blowout, unsafe lane change, SR 417 — all came back with volume 0, below Semrush's reporting threshold. They generate impressions but there is no real search market behind them. Semrush gap keywords still absent from the page are almost all «car accident lawyer» terms, not hit-and-run terms: car accident lawyer in miami (1,600 / KD 34) · accident lawyers in miami fl (880 / KD 70) · car accident attorneys miami (210 / KD 29). Those belong to miami-car-accident-attorney. Chasing them here would blur the page's signal against a sibling that already outranks it. Also rejected in (p): «defense attorney for hit and run» — 110 vol at KD 0, the cheapest number in the whole set, and the wrong audience entirely. That query is people who FLED, looking for criminal defence.
Content Changes — 22 entries (a)–(v) · scope 2,162 → 7,104 raw words · 15 H2 + 17 H3 → 17 H2 + 22 H3
En/article.cshtml  ·  32 balanced Razor provenance comment pairs — one per pass, each stating WHAT / SOURCE / KEYWORDS REINFORCED
(a) The accuracy pass — a leaked editorial instruction was live on the page REMOVED
The published «Time Limit to File» section read: «Your existing page references a four-year period for hit-and-run injury lawsuits, but that should be updated.» That was a note to the site owner, visible to clients, and it contradicted the correct two-year figure in the very next sentence. Replaced with a clean statement citing Fla. Stat. 95.11, naming the March 24 2023 tort-reform effective date, and explaining that the old four-year window only ever applied to pre-2023 accidents — so it is now moot rather than merely «to be updated». Also in this pass: the $10,000 PIP minimum and the 14-DAY TREATMENT DEADLINE under s. 627.736 (miss it and PIP pays nothing — absent from the page entirely); the phantom-vehicle rule for UM claims; criminal penalties made concrete from «severe penalties» to «first-degree felony carrying a mandatory minimum of four years in prison» under s. 316.027; and the pedestrian/cyclist figure made specific — «a large majority» → «76%, 159 pedestrians and 47 bicyclists out of 271 total deaths». Body 2,101 → 2,327 words. Sitemap lastmod for the EN and ES URLs was 2025-05-21 despite the content being rewritten that month; both set to 2026-08-19 to prompt recrawl.
(e) The page was publishing WRONG NUMBERS CORRECTED
FigureWas on pageCorrected toWhy
2023 crashes104,273105,092The FLHSMV Hit-and-Run Awareness page publishes as-of figures that were never revised. The Traffic Crash Facts Annual Report 2024 (downloaded and read directly, page 11) is final data and supersedes it. The earlier pass had relied on the awareness page.
2023 fatalities271276
2023 serious injuries871954
2024 crashes97,519 (prelim)97,999 (final)
2024 fatalities238 (prelim)242 (final)
2024 serious injuries779 (prelim)871 (final)
Note the coincidence that made the error look plausible: the 871 sitting on the page as the 2023 serious-injury figure is in fact the 2024 figure. A wrong number that happens to be a real number from the same table is the hardest kind to catch by eye.
(e) New section — «How Many Hit-and-Run Accidents Happen in Miami and Florida?» THE STRONGEST LOCAL FACT ON THE PAGE
Nearly ONE IN THREE Miami-Dade crashes is a hit-and-run (32.4%) against roughly one in four statewide (25.5%). Miami-Dade is 15% of Florida's crashes but 19% of its hit-and-runs — drivers flee here more often than elsewhere in the state. The page carried Florida yearly totals only: ZERO Miami-Dade figures and ZERO per-day framing, on a page targeting «Miami hit and run accident lawyer». Two tables, kept separate because they are NOT the same series and must not be blended. Table 1 — 2026 year to date (1/1 to 8/13/2026): Florida 54,706 hit-and-run crashes / 243 per day / 114 fatalities / 10,561 injuries; Miami-Dade 10,570 / 47 per day / 18 fatalities / 1,628 injuries. Table 2 — Florida full year from the Annual Report page 11: 97,999 (2024) · 105,092 (2023) · 107,844 (2022). Sourcing: the county split exists in only one place — the FLHSMV Crash Dashboard, read with County = Miami-Dade and County = (All). The annual report has no hit-and-run-by-county table at all (verified: 7 hit-and-run references in the whole 131-page report, all statewide). The dashboard is a Tableau embed requiring a JS session; automated extraction failed (bootstrapSession returns 404 without a browser-generated session id), so the county figures were read from the live dashboard by the user. Earlier secondary-source claims (19,046 for 2024) were NOT used — the primary read supersedes them, and it independently confirms the ~1-in-3 ratio those sources implied. Per-day and percentage figures are arithmetic on the table totals (225 days YTD, 366 in 2024, 365 in 2023 and 2022). No new sourcing risk.
Anchor is #hit-and-run-statistics, NOT heading-16, so heading-1..15 numbering and every in-page link survive untouched. Same convention used for the timeline section.
(f) Case steps and timeline — the page had ZERO process coverage
Measured on the rendered body before the edit: «step» 0 · «process» 0 · «timeline» 0 · «how long» 0 · «weeks» 0 · «months» 0, and the only <ol> on the whole page was the table of contents. A reader could not answer «what happens next, and when», and neither could an answer engine — while «how long does a hit and run case take» is standard PAA phrasing. What existed was adjacent but not the same thing: «What to Do After a Hit-and-Run Accident» is scene-level victim actions — the first hour, not the case. The nine bullets under «How Gallardo Law Firm Can Help» ARE the real case stages, but sat in an unordered, untimed <ul>. Added: an 8-step ordered list, each step cross-linked to the section that explains it; a statutory deadline table (notify law enforcement immediately · 316.065 / seek treatment or lose PIP 14 days · 627.736 / written crash report with no officer 10 days · 316.066 / insurer must pay PIP or it is overdue 30 days · 627.736(4)(b) / file the lawsuit 2 years · 95.11); and a court-duration table from Fla. R. Gen. Prac. & Jud. Admin. 2.250(a)(1)(B) — non-jury 12 months, jury 18, complex 30. Body 2,680 → 3,404 words.
(g) Intro rewritten for GEO, then the whole page de-duplicated by measurement
The intro was 189 words containing ZERO digits, ZERO statutes and no definition. Nothing in it answered anything, so nothing was retrievable. Paragraph 1 now opens with a definition and answers the question victims actually arrive with — «can I recover if nobody knows who hit me?» REMOVED: «we have experienced and talented professionals who can help you get the maximum compensation possible» — pure puffery with no information, and implying an expected outcome runs at Fla. Bar Rule 4-7.13.
THE DE-DUPLICATION, enforced by measurement rather than by reading. Facts were MOVED, not copied. After the intro rewrite a check found the same figures stated in three places, so three further edits followed: heading-1's paragraph was stripped of all statistics and reduced to a one-line pointer; the statistics opener dropped the «one in three / one in four» framing the intro now owns and took the injury count instead; the statistics closing dropped the 76% pedestrian split, which belongs to heading-6, and cross-links there. Ownership after the pass — each fact stated once in prose: intro owns the one-in-three ratio · heading-1 owns nothing, it points · heading-6 owns the 76% split · the statistics section owns the raw counts, the 81% dawn/dusk/night figure and the tables. Verified on the render: one in three ×1, one in four ×1, 76% ×1, 81% ×1, 54,706 ×1; 10,570 and 1,628 at ×2 each = once in prose plus once as table data, which is correct. Intro 189 → 187 words; body 3,404 → 3,318 — a net REDUCTION despite the intro gaining a fact.
(j)–(n) Heading-by-heading rewrites — every one of them opened with the same defect
  • heading-1 «Why Hit-and-Run Accidents Are So Serious» — 134 words, 0 digits, 0 statutes, 0 citations, 0 outbound links. The heading asserted rather than asked, and the body never answered it. Now a question, with the two mechanisms that actually separate a hit-and-run from an ordinary crash: nobody calls for help, and there is no at-fault insurer to claim against 134 → 384w
  • heading-2 «What Is a Hit-and-Run Accident Claim?» — 122 words, and it carries #hr-definition, one of two speakable selectors. Whatever sits there is what a voice assistant reads aloud. Now names the two tracks: THIRD-PARTY against the other driver's insurer, FIRST-PARTY against your own. «first-party» appeared 0 times before 122 → 233w
  • heading-3 «Why Drivers Flee the Scene» — 87 words, nine bare noun phrases, and it never answered its own heading. The missing answer: fleeing destroys the evidence of the thing being fled from. A driver who stays is tested at the scene; a driver who leaves and sobers up often cannot be proved impaired at all 87 → 466w · 0 → 5 links · 0 → 26 digits
  • heading-4 «Florida Law Requires Drivers to Stop» — cited the WRONG STATUTE for the duty. Stopping, giving information and rendering aid is s. 316.062; the section cited only s. 316.027, which is the crime of BREACHING that duty. Both now cited, with the counter-intuitive part stated: 316.062 alone is a noncriminal traffic infraction 116 → 392w
  • heading-5 «Common Causes of Hit-and-Run Accidents in Miami» — 169 words across SIX H3s at ~28 words each. Three of the six explained why a driver FLEES, not what caused the CRASH — that is heading-3's subject DE-CANNIBALISED 169 → 596w
  • heading-6 to heading-15 — all ten remaining sections were planned TOGETHER before any was written, because doing them one at a time is precisely what produced the heading-3 / heading-5 overlap. Ownership was assigned across all ten first: h6 vulnerable road users · h7 the first hours and the crash report · h8 evidence, by who holds it · h9 the coverage that pays (owns 627.736, 627.727) · h10 damages and the tort threshold (owns 627.737) · h11 what is hit-and-run-specific about a fatal case · h12 deadlines (owns 95.11, unchanged — already good) · h13 insurer arguments and the counter to each · h14 the firm (unchanged but for one phrase) · h15 the call to action. h8 88 → 441w · h13 88 → 326w · page 5,759 → 7,018w
The four stuffed sentences, removed together in (k) SPAM PATTERN
«A hit and run {attorney|lawyer} Miami can …» — broken word order left from old keyword stuffing, on four separate headings. It reads as spam to a human and to Google's helpful-content signals, and the sentences carried no information either way. heading-2 → «A hit and run attorney can tell you which track applies»  ·  heading-3 → «A Miami hit and run lawyer can investigate why the driver fled»  ·  heading-9 → «A hit and run accident attorney can help fight these disputes»  ·  heading-13 → «A hit and run lawyer can respond with medical records» Each replacement carries a DIFFERENT phrase, chosen on volume against fit, so the page now covers four distinct terms once each instead of two terms twice each in sentences no one would want to read. TWO REAL LOSSES, NEITHER ACCIDENTAL. «hit and run lawyer miami» went 2 → 0 — the page's third-highest query at 116 impressions. The judgement: the page held that exact phrase twice and still sat at position 30.4, which is evidence the exact form was not what was holding the ranking up, while stuffing is a known negative signal. The natural variant «miami hit and run lawyer» rose 2 → 3, and the title, H1 and og:title all carry «Miami Hit and Run Accident Lawyer». FLAGGED rather than buried: if the firm wants exact-match coverage of that query back, the way to do it is a heading or a FAQ question in that word order — not a spam sentence.
Substantive legal material added, all primary-sourced
  • THE BIGGEST LEGAL OMISSION — the tort threshold. «Pain and Suffering» sat in heading-10's list as though automatically available. In Florida it is not: s. 627.737(2) allows those damages only for significant and permanent loss of an important bodily function, permanent injury within a reasonable degree of medical probability, significant and permanent scarring, or death. «627.737» and «permanent injury» each appeared ZERO times before
  • Comparative fault — a gap across the whole page. «comparative» appeared 0 times and s. 768.81 was never cited, yet heading-13 listed «you were partially at fault» as an insurer argument and never explained it. Added as a seventh H3 in question form, linking to heading-13, so the tactic and the rule sit at either end of one link
  • Licence revocation was missing from the entire page. s. 316.027 requires revocation for at least three years under s. 322.28(4), with reinstatement conditional on a victim impact panel or a department-approved vulnerable road user course
  • The penalty tiers, as a table — injury = third-degree felony, no minimum · serious bodily injury = second-degree · death = first-degree, 4 years · death while under the influence = first-degree, 4 years, s. 316.027(2)(c). Built as a table because a table is the form an AI Overview lifts whole
  • Crash reports are confidential for 60 DAYS under s. 316.066(2) — but the exemption does not apply to the parties, their legal representatives or their insurers, which is exactly this page's reader. This closes part of the «no local operational detail» gap logged in (i)
  • UM coverage is included in every Florida bodily injury policy UNLESS a named insured signs a written rejection (s. 627.727). Worth more to a reader than the sentence it replaced, because people who assume they have no UM coverage often do — see the misattribution this replaced, in Measurement Discipline below
(l) The Aaron Cohen case — a local fact, and how it was verified NEW H3
In February 2012 cyclist Aaron Cohen was struck on the Rickenbacker Causeway in Miami-Dade by a driver with a suspended licence who had been drinking in Coconut Grove. The driver fled and did not turn himself in for 18 hours; by then impairment could not be proved, so he faced only a leaving-the-scene charge and served under two years. The Legislature responded with the Aaron Cohen Life Protection Act, HB 55 (2014). The narrative came from Miami New Times and WLRN, both linked inline. The LEGAL CORE was verified against primary sources, not the news coverage: s. 316.193(3) DUI manslaughter, mandatory minimum 4 years, and s. 316.027 leaving the scene with death, mandatory minimum 4 years — which did not exist before the 2014 act. Several law-firm blogs in the search results claim the act created «3, 7 or 10 year» minimums. The statute text says 4. The statute was followed. «Aaron Cohen Life Protection Act» is the bill's popular name and is NOT a short title inside 316.027, so the copy credits the 2014 law rather than the statute. THE DRIVER IS NOT NAMED — he is a private individual, the case is over a decade old, and naming him adds nothing to a page about victims' claims. The victim is named because the statute's popular name already is.
The local signal is a by-product, not padding. The (i) audit found the page named NO Miami road or landmark anywhere. Rickenbacker Causeway and Coconut Grove now appear as facts of a real case rather than as inserted place names — and they were deliberately NOT added to the Service areaServed, because that list is places the firm serves and a causeway is not one.
Duplication I created across passes, then closed SELF-CORRECTED
  • FAQ 6 carried heading-4's second paragraph VERBATIM — because that FAQ was written in (b) out of this section's copy. Division of labour now explicit: the FAQ stays the short answer, the section carries the full tier table. Verified after render: the sentence appears in the FAQ block and NOT in the body
  • Two heading-1 list items restated other sections' facts and were rewritten after a post-edit duplication scan — the pedestrian item was heading-6's 76% figure in words, the fatal item was heading-4's felony sentence in substance. Both replaced with new information, and the cross-link moved from heading-4 to heading-11, the section actually about fatal cases
  • heading-6 closed by listing «nearby businesses, traffic cameras, dashcams, and witness statements» — heading-8's whole subject in miniature, two sections early. Replaced with what is specific to a pedestrian or cyclist case: no second vehicle means no paint transfer and no damage pattern to match
  • heading-13 was 88 words of seven bare assertions — and by (n) TWO sections linked INTO it. Pointing readers at a hollow section was self-inflicted. Every argument now has a counter, and each counter links to the section that owns the rule rather than restating it. Not built as a table, because the counters are cross-links and links in table cells read badly on mobile
Statistics that were considered and deliberately NOT added. The FLHSMV Annual Report 2024 carries 19,591 hit-and-run «other injuries» plus 871 incapacitating = 20,462 people injured in Florida hit-and-run crashes in 2024. It was not put in heading-1: every count on this page belongs to #hit-and-run-statistics under the ownership rule set in (g), and if the figure is wanted it becomes a row in that table. The report's cause tables (speeding and aggressive driving 38,968 crashes / 449 deaths) were rejected for heading-5 because they are ALL-CRASH STATEWIDE figures, not hit-and-run — using them would either misattribute them or drift the section off subject. And nothing was invented to fill the gap. No verified Miami-Dade hit-and-run cause data exists in any source held — the dashboard breaks hit-and-run out by county but not by contributing cause. Rather than borrow statewide all-crash data or write filler place names, heading-5 keeps «in Miami» in the H2 and the page carries its local weight where it is real: the statistics section and the Rickenbacker Causeway case. Camera retention figures were left qualitative («days, sometimes less») for the same reason — systems vary too much and no source held covers it.
FAQ Roster — 0 → 10 of 10 slots · 0 → 983 words · every question closes a measured gap
This was a DATA gap, not a template gap — no view code was touched. ServicePageSkin.cshtml already renders FAQs with schema.org/FAQPage markup and takes up to 10. It was rendering nothing because 0 records were linked to this service, and 0 of the 1,851 records in the file mentioned hit-and-run, so there was nothing to link — the content had to be written. Four existing H2s were already phrased as questions and seeded it.
App_Data/FaqEntities.xml  ·  language="en"  ·  +10 records, +40 lines, 0 deletions · 1,851 other records untouched
The roster — 10 questions, chosen to close measured keyword gaps, not invented
1What should I do immediately after a hit-and-run accident in Miami?
2Do I have to file a police report after a hit-and-run in Florida? CLOSES «police report» — 0 occurrences
3How long do I have to file a hit-and-run claim in Florida? CLOSES «statute of limitations» — 0
4Can I still get compensation if the hit-and-run driver is never found? the page's core differentiator
5Does my insurance cover a hit-and-run accident in Florida?
6Is a hit-and-run a felony in Florida? CLOSES «criminal charges / felony» — 0
7How do hit-and-run accident attorneys identify the driver who fled? «attorneys» — 2,400 vol at KD 5
8What if I was a pedestrian or cyclist hit by a driver who fled?
9How much does a hit-and-run accident attorney cost in Miami? CLOSES «contingency fee» — 0
10Do I need a hit and run accident lawyer near me in Miami? CLOSES «near me» — 3 GSC variants, ~1,680 vol, all at pos ~21
Every answer is traceable to a named source
316.065 / 316.066police report duty, 10-day written report
SB 488, Ch. 2026-39reporting threshold $500 → $2,000 effective 2026-10-01 — injury or death still triggers the duty at any dollar amount
95.11two-year limit, HB 837 effective 2023-03-24
316.027felony tiers / 4-year mandatory minimum
627.736$10,000 PIP, 14-day treatment rule
627.727UM — unsigned rejection means coverage is deemed included at BI limits
Bar Rule 4-1.5contingency caps 33⅓% / 40%, tiered above $1M
FLHSMV76% pedestrian/cyclist share — 159 + 47 of 271 (2023)
NOT USED, DELIBERATELY. Miami-Dade county-level counts sourced only from secondary pages (e.g. 13,122 for 2025) could not be confirmed against a primary FLHSMV release. Q10 uses the qualitative «among the highest in Florida» plus the verified statewide «one in four» figure instead. CANNIBALISATION CHECK: all 10 questions are hit-and-run specific. Q5 covers insurance and Q8 covers pedestrians, but both are framed as hit-and-run scenarios, so miami-uninsured-motorist-accident-lawyer and miami-pedestrian-accident-attorney keep their subjects intact. FILE DISCIPLINE: records appended before </Data> with the BOM, CRLF and « />» house style preserved, so the diff is +40/−0. The full file was re-parsed after writing to confirm it is still valid XML.
A deployment fact that cost one verification cycle: App_Data is cached at application startup, so the running dev server rendered 0 FAQs after the write. The block was only confirmed live after a restart — 1 schema.org/FAQPage container, all 10 questions present, page weight 62,835 → 75,789 bytes.
STILL OPEN — Spanish. All 10 records were added with language="en" only, so the ES page still shows none. The Spanish article is 2,602 words against 7,104, with ZERO statutes and ZERO page-specific JSON-LD blocks. Half the audience, less than half the page.
Internal Linking & Cannibalisation — entries (r), (s), (t) · outbound 3 → 5 · inbound 1 → 6 · one entry crashed the entire site
THE FINDING: the page had exactly THREE links leaving it in 7,101 words — two to miami-wrongful-death-lawyer, one to miami-brain-injury-lawyer — against 43 in-page anchors. The «We Also Represent Clients in the Following Cases» block at the foot of the page was effectively the entire outbound internal linking, and it had never been reviewed against the copy. The inbound side was worse: ONE inbound internal link, against 22 for miami-car-accident-attorney — and that single link came FROM miami-car-accident-attorney, the page that outranks this one for its own keyword (5.26 vs 33.57).
App_Data/ServiceEntities.xml  ·  En/article.cshtml  ·  5 other pages  ·  Views/Shared/Partials/PartialServicesRelated.cshtml NOT touched
The related-services block, tested entry by entry against how often the page actually discusses that topic REPLACED
Medical Malpractice — 0 mentions in English AND 0 in Spanish. No topical relationship to a hit-and-run at all. FINAL SIX: Uninsured Motorist (14 mentions — heading-9 is entirely this) · Drunk Driving (17 DUI/drunk/impaired) · Bicycle Accident (16 cyclist / 10 bicycl) NEW · Rideshare Accident (7 — heading-13 names rideshare coverage) · Distracted Driving (4) · Spinal Cord Injury (1) ANCHOR TEXT CANNOT BE IMPROVED HERE — a real limit, not an oversight. The shared partial renders @services.GetShortName, and shortname is a GLOBAL attribute on the service record. Changing «Pedestrian Accident» to something keyword-rich would rewrite that label in every menu, sidebar and related block site-wide. Generic anchors are the most this block can produce — which is the main reason the body links below matter more than it does.
EDIT METHOD: the <ServicesRelated> node was located by PARSING with lxml and using sourceline, then a single line range was replaced in the raw bytes. A text search would have been wrong — these service ids appear in many records. The 266KB file's BOM, CRLF endings, tabs and comments are otherwise byte-identical; 155 records re-parsed intact after writing.
SIDE EFFECT, ACCEPTED AND FLAGGED: the node is language-agnostic, so the SPANISH page of this same service shows the same six. It improves there too — Spanish has 6 «peatón» and 10 «ciclista» mentions and 0 for malpractice. Confirmed live in (v): Conductores Sin Seguro, Conductores Ebrios, Accidente de Bicicleta, Accidentes de Uber y Lyft, Conducción Distraída, Lesiones de Médula Espinal.
Two body links in heading-6 — the higher-value half, and NO WORDS ADDED
heading-6 is an entire H2 titled «Hit-and-Run Accidents Involving Pedestrians and Cyclists» and it linked to NEITHER sibling page. A contextual link inside prose that states the relationship carries more weight — for ranking and for AI extraction — than a bare list item at the foot of the page, because the surrounding sentence supplies the relationship and a link list cannot. The anchors wrap words already in the sentence, so word count stayed at 7,101 raw / 7,475 normalised, «hit and run» density stayed at 5.74%, and not one row in the keyword table moved.
*** MY EDIT IN (r) CRASHED THE ENTIRE SITE. *** The 8-entry version of the block did not fail to render — the application never started. dotnet watch: Exited with error code -1073741571 = 0xC00000FD, STACK_OVERFLOW, thrown at Site..ctor()RouteConfig.RegisterRoutesProgram.Main — before routing exists, so every page on the site went down, not just this one. THE CAUSE: the XML parser resolves each <Service id="…"/> reference into the full entity RECURSIVELY, and has no cycle guard. miami-car-accident-attorney already lists THIS page in its own ServicesRelated — that is the single inbound link noted above — so any entry that can reach it closes a loop back here. Two of the three additions did: miami-pedestrian-accident-attorney → miami-car-accident-attorney → HERE and miami-wrongful-death-lawyer → miami-car-accident-attorney → HERE.
THE MISTAKE, precisely: a DIRECT back-link check was run when writing (r), found none, and stopped there. The cycles were two and three hops out. Checking one level deep on a graph is not checking a graph.
THE FIX: six entries, reachability tested for all six across the whole graph before writing, and the writer REFUSES to emit any id that can reach this page — the check lives in the script, not in judgement, so the same mistake cannot repeat silently. Whole-graph cycle detection across all 155 service records afterwards: 0 cycles. Dangling <Service id> references: 0. git diff confined to the one node, 6 insertions / 6 deletions.
WHAT SURVIVED: Medical Malpractice still removed · Bicycle Accident still added (the one addition with no path back) · BOTH body links kept, because plain <a href> is not an entity reference and had nothing to do with the crash. WHAT WAS LOST: Pedestrian and Wrongful Death as block entries — and the practical cost is small, since wrongful death was already body-linked twice and pedestrian is still body-linked from heading-6.
THE DISTINCTION THAT MATTERS WHEN ADDING LINKS IN THIS CODEBASE.
<a href="…">inert. Any number, any direction, reciprocal is fine. Cannot break the build.
<Service id="…"/>followed recursively at startup. Must never form a loop back to the current page.
It is also why pedestrian and wrongful death, which cannot go in this page's bottom block, are still linked to and from this page in prose — the same destination and the same reader benefit, with none of the structural risk. FLAG FOR THE FIRM — the underlying defect is in the parser, not in the data. It should carry a visited-set guard. A single bad entry in an XML data file takes down the entire site at startup, with a stack trace that names no service and no file. That is worth fixing at the source, and it is outside the scope of this page's work.
(t) Five inbound links added — on five OTHER pages 1 → 6
SCOPE NOTE — this is the one entry in this report that edits other pages. Every prior entry kept to this page and flagged problems elsewhere rather than fixing them; this was explicitly authorised. Nothing on THIS page changed: word count, density and every table row held.
Why each earned it: the pedestrian page carries an entire H2, «Pedestrian Accidents Involving Hit-and-Run Drivers», with a written paragraph, and linked here zero times — the best inbound opportunity on the site. The blog post is about a driver who struck two cyclists on Crandon Boulevard, fled, and returned 20 minutes later; it linked to the DUI page and the wrongful death page and not to the hit-and-run service page. The other three had «Hit-and-run accidents» sitting as a bare list item, linked in place with existing wording kept.
ANCHOR TEXT DELIBERATELY NOT UNIFORM. Two prose anchors carry the descriptive terms; the three list items keep the wording already on those pages. Five identical commercial anchors appearing at once is a manipulation pattern — and it is the same instinct that produced the stuffed sentences removed in (k). Not attempted: forcing «hit and run lawyer miami» into an anchor. There is no natural English sentence with that word order, so putting it in someone else's copy would just move the problem.
File discipline: 5 files, one line each, 5 insertions / 4 deletions. Each file's own encoding preserved individually — all five carry a BOM; the pedestrian page is LF and the other four are CRLF, and each was read and rewritten with its own ending. Written only after asserting the target string appeared EXACTLY once and that the file did not already link here.
Cannibalisation was measured after every content pass, not assumed — and the guard rail held every time. Two sibling pages were at risk throughout: miami-car-accident-attorney and miami-uninsured-motorist-accident-lawyer. The UM check, run when «uninsured motorist» rose 7 → 10 in (f): this page 3,404 words, UM ×10, density 0.59%, hit-and-run ×95 — against the UM page at 1,069 words, UM ×7, density 1.31%, hit-and-run ×1. The UM page still owns the term at more than double the density, and the two topical centres stayed cleanly separated: the UM step here is framed around a driver who fled and the phantom-vehicle problem, not general UM law. «car accident» went 1 → 0, which widens the separation from a sibling that already outranks this page for its own keyword. heading-11 (fatal cases) keeps only what is hit-and-run specific — the driver is often still unknown, the family is waiting on a criminal investigation, and the civil deadline does not pause while they wait. Who may bring a wrongful death claim and what the Act allows is miami-wrongful-death-lawyer's subject, carried there with ss. 768.16–768.26; writing it again would cannibalise a sibling.
REPORTED, NOT FIXED: miami-uninsured-motorist-accident-lawyer is only 1,069 words — thin against this page at 7,104 and against its own keyword set. Worth its own pass.
JSON-LD Schemas — 1 → 4 blocks · built to the house format, values hit-and-run specific
Why this pass happened. A local-targeting audit of the rendered page found the city covered and the neighbourhoods not: «miami» ×39 including title, H1, meta, 5 headings and 6 FAQs · «miami-dade» ×7 · hialeah, coral gables, doral, homestead, aventura, westchester ×1 each, all six in one intro sentence, 0 in headings and 0 in FAQs · miami beach, north miami beach, kendall, brickell, little havana ×0. And 57% of this page's GSC impressions (917 of 1,596) are local-intent. Meanwhile nothing in the structured data named any locality — the only JSON-LD on the page was the shared skin's LegalService, whose serviceArea was a single vague AdministrativeArea «Miami, Florida». The three new blocks were copied STRUCTURALLY from miami-wrongful-death-lawyer, which is itself the format used by product-liability-attorney-miami, miami-surgical-errors-attorney and miami-brain-injury-lawyer: same blocks, same order, same property set — only the values differ.
Block 1
BreadcrumbList
Fields — 3 levels
position 1Home
position 2Personal Injury
position 3Miami Hit and Run Accident Lawyer
Notes
  • Position 2 and 3 URLs were both fetched after render: HTTP 200
  • Those URLs are not href attributes, so any audit that only scans hrefs skips them. Verified separately
Block 2
WebPage + Speakable
Fields
speakable#hr-intro · #hr-definition — both resolve to exactly 1 element each, verified on the render
#hr-definitionheading-2. Whatever sits there is what a voice assistant reads aloud — which is why the 122-word section was the first one rewritten in (k)
breadcrumbcross-reference to the BreadcrumbList node
Open
  • Speakable covers only two selectors. The FAQ answers and the statute passages are the better extraction candidates and are unmarked
Block 3
Service
Fields
alternateName4 values
areaServed9 values — State Florida · AdministrativeArea Miami-Dade County · City Miami, Hialeah, Coral Gables, Doral, Homestead, Aventura · AdministrativeArea Westchester
hasOfferCatalog7 offers, all claim types the page actually discusses
priceNONE ON ANY OFFER — it would compound the skin's existing priceRange against Fla. Bar Rule 4-7
The rule that governed areaServed
  • All nine were checked against the page copy before being written — all 9 present. Structured data says what the copy says
  • Miami Beach and North Miami Beach are DELIBERATELY ABSENT. They carry 37 GSC impressions at KD 0–3 across 4 queries and rank 15.9–26.2 — the cheapest local win available — but they appear NOWHERE in the copy. Putting a locality in schema that the page never mentions is a claim the page does not make. Fix the copy first, then extend areaServed
  • Westchester is typed AdministrativeArea, not City: it is an unincorporated census-designated place, not a municipality
  • Rickenbacker Causeway and Coconut Grove were NOT added — that list is places the firm serves, and a causeway is not one
Block 4
LegalService (shared skin)
Coverage
Emitted by ServicePageSkin.cshtml for every service page. UNCHANGED — editing it would change every page on the site
FAQPage microdata + 10 Question/Answer also come from the skin. No FAQPage node was added in the article — it would duplicate the skin's
Deliberately not added anywhere
  • aggregateRating — self-serving review markup on a service page is a Google structured-data policy violation and risks a manual action
  • geo / hasMap — neither template carries them; the firm's location already sits in the skin's PostalAddress. Adding them here only would break the house format this pass exists to match
  • Article — service page, not an article; no template carries one
Bug fixed
VideoObject thumbnailUrl held «VIDEO_ID»
  • The template placeholder …/vi/VIDEO_ID/hqdefault.jpg was never substituted and returns HTTP 404. thumbnailUrl is REQUIRED for a VideoObject rich result, so the whole video result was invalid and earned nothing. Replaced with the real id (FonIANXLB3M), maxresdefault first and hqdefault as fallback — both HTTP 200.
  • uploadDate was WRONG: the page said 2026-04-07T10:10:25Z; YouTube's own record is 2026-04-29T11:39:23-07:00. Off by 22 days and missing the timezone offset.
  • itemprop="video" was ORPHANED. The DOM was walked upward from the node and there was NO enclosing itemscope, so the property had no subject. Removed; the itemscope/itemtype pair was left, so the page still exposes a valid top-level VideoObject.
  • contentUrl and publisher added. Caveat recorded: schema.org defines contentUrl as the actual media byte stream, which YouTube does not expose — the watch URL is the standard pragmatic choice, and nothing depends on it because embedUrl already satisfies Google's requirement.
  • Every value was checked against the live YouTube record before being changed. Post-edit: 0 occurrences of VIDEO_ID remain, 8 properties emitted, all 6 URLs in the block HTTP 200, and UTF-8 integrity confirmed at byte level (U+00ED, U+2019, U+2026 all intact, BOM preserved).
  • Open defect
    The VIDEO_ID bug is SITE-WIDE
  • 22 files across 11 pages (EN+ES) carry the same unsubstituted placeholder, including miami-car-accident-attorney and personal-injury-lawyer-in-florida. Site-wide, only 3 pages have a real thumbnail id against 27 placeholder instances. Every one of those pages has an invalid video rich result for the reason this page did.
  • This video is not in wwwroot/sitemap_video.xml — 0 references to the id or the page. And 0 VideoEntities records are linked to this service, so the sidebar video section renders empty — the same class of data gap the FAQs had.
  • The video is generic personal-injury content, not hit-and-run specific, and the same video also embeds on miami-pedestrian-accident-attorney. Video appears on 98% of this keyword set's volume and a carousel on 67%. A hit-and-run-specific video would likely move more than further copy edits — but it is a production job for the firm.
  • Open defect
    E-E-A-T fields are all empty
  • datePublished, dateModified, author, reviewedBy and image are ZERO across all three new blocks.
  • Dates and image can be added without the firm — article:published_time is already 2025-02-07 in these metas. A named attorney reviewer cannot, and for a legal page it is the strongest trust signal available.
  • The wrongful-death schema block this one was copied from is marked PENDING REVIEW in its own Razor comment. This one inherits that status — same format, same open question for the firm.
  • Stated plainly
    What this markup will NOT do
  • Service and WebPage render nothing in the SERP. They are entity and understanding signals for Google and generative engines, not a rich result.
  • This is worth stating because 35% of this keyword set's volume shows a Local pack, and 100% of the «near me» subset does — 4 queries, 1,770 volume, 143 GSC impressions, all at position 12–21. A Local pack is won by the Google Business Profile and searcher proximity, NOT by this markup. No amount of schema or body copy moves it. That part of the local opportunity sits outside this page.
  • Measurement Discipline — every error found in this workstream, including the ones I made and the one that was live on the client's page
    Six failures are recorded here. Three were mine, two were live on the page before this work started, and one was in the tooling. Every one of them produced clean, plausible, internally consistent output — which is exactly why they survived until something measured them.
    Recorded in full because the rules adopted from them apply to every future page
    A statute the page cited for something it does not say WAS LIVE ON THE PAGE
    CLAIMED, in heading-9: «Under Florida Statute 627.727, a claim involving an unidentified phantom vehicle generally requires either physical contact … or independent corroborating evidence.»
    TRUE: the full text of 627.727 was fetched from flsenate.gov and searched. It contains ZERO occurrences of «physical contact», «corroborat», «phantom» or «hit-and-run». The rule is real in Florida practice — but it comes from POLICY LANGUAGE tested against case law, not from that statute. The false attribution was removed and the practical position kept. NO CASE WAS CITED IN ITS PLACE. The governing decision is generally given as Brown v. Progressive Mutual Ins. Co., 249 So. 2d 429 (Fla. 1971), but that was only confirmable from competitor law-firm pages, and a law firm's own site should not carry a case citation verified from secondary sources. FLAG FOR THE FIRM: if the attorneys confirm the cite, it belongs there. 627.727 IS still cited — for something it does say and the page never mentioned: UM coverage is included in every Florida bodily injury policy unless a named insured signs a written rejection. Worth more to a reader than the sentence it replaced, because people who assume they have no UM coverage often do.
    Two sources disagreed and the page was carrying the wrong one RESOLVED IN FAVOUR OF THE PRIMARY
    The FLHSMV Hit-and-Run Awareness page publishes as-of figures that were never revised. The Traffic Crash Facts Annual Report 2024 is final data and supersedes it. The earlier pass had relied on the awareness page, so six published figures were wrong (see Content Changes above). RULE APPLIED, AND APPLIED AGAIN LATER: when two products of the same agency disagree, the final annual report wins over the live dashboard page, and a primary read supersedes any secondary source. The same rule rejected the widely-repeated 19,046 figure for 2024 Miami-Dade hit-and-runs and the 13,122 figure for 2025 — neither could be confirmed against a primary FLHSMV release, so neither was used. 2025 statewide figures were also refused: secondary sources disagreed (85,459 vs 91,164 crashes) and no primary release could be reached to settle it. The page says nothing about 2025.
    The 7-day output cache — three fetches came back stale before anyone noticed RULE ADOPTED
    ServicePageController carries [DonutOutputCache(Duration = 3600*24*7, VaryByParam = "abbreviatedLanguage;serviceUrl", VaryByHeader = "User-Agent")]a SEVEN DAY server-side output cache keyed on User-Agent. A plain re-fetch after an edit returns the OLD page. It did exactly that here, repeatedly — including once with a cache-busting query string, which does not work, because the query string is not in the vary key. In entries (m) and (n) three fetches in a row came back stale. And byte size alone is not enough to detect it: two different renders came back at the same size.
    RULE ADOPTED: fetch with a fresh User-Agent AND confirm a known new string is present before trusting any measurement. Every measurement in this report was taken from a fetch confirmed to contain the new content. A second environment fact learned the same way: the app serves on 5238 / 7155, not 5000 / 44300, http 301s to https, and the Spanish URL carries an /es/ prefix that is NOT in the entity's urlspanish attribute.
    A bad keyword trade, caught by recount inside the same pass REVERSED
    (p) first placed «attorney for hit and run» into heading-8 by replacing the phrase «the most time-sensitive thing a hit and run lawyer does». The recount showed the cost immediately: «hit and run lawyer» — 8,100 vol at position 11.7 — fell 3 → 2 to gain a 140-volume phrase. heading-8 was restored and the variant moved to heading-12, which ended abruptly on a bare list and needed a closing line anyway. The same mistake in reverse had already been caught in (l), where a closing sentence written as «A Miami hit and run lawyer» (140 vol) was re-edited to «A hit and run attorney» (3,600 vol, KD 10) — a deliberate re-edit of a previous edit, and the better trade by volume. And a third instance in (m): the first version of the heading-4 rewrite took «leaving the scene» DOWN 7 → 6, because the removed sentence had carried it twice while the new opening said «turns walking away from those duties into a felony». Changed to «turns leaving the scene into a felony» — plainer English, and the term recovered in the same stroke.
    RULE: recount after every edit, not at the end of the pass. All three of these were invisible to reading and obvious to counting.
    A measurement that caught an omission the copy had disguised
    After the (n) comparative-fault edit, «comparative» was STILL at 0 — the copy explained the rule in plain words without ever naming the doctrine. Plainer for a reader, but it costs the entity: «modified comparative negligence» is the term Google and the answer engines associate with this rule. Named once, in bold; the plain-language explanation still does the work of explaining. This is the same failure mode as the «attorney» variant across the whole page — the concept was covered, the word people search for was not.
    The raw word count has always run about 5% high — and this is the first pass that checked it CAVEAT ADDED, FIGURE KEPT
    Both columns are produced by stripping tags with a regex and putting a SPACE where each tag was. That splits any word an inline tag cuts through: <b>hit</b>-and-run counts as 2 tokens and Miami<b>'s</b> as 2. The page uses a lot of inline bold, and the effect grew as bold was added. Verified on a constructed sample, not assumed.
    MethodBeforeNowMultiple
    Tag-strip (the figures in this report)2,1627,104×3.28
    DOM text (truer prose)1,9746,783×3.44
    The table keeps the tag-strip figure because every Before number in this report and every Density denominator was computed that way, and mixing the two would break comparability. Both columns are inflated by the same rule, so the BEFORE vs NOW comparison stands and no keyword count is affected — the keyword counter normalises separately and matches phrases, not token boundaries. USE ~6,800 IF A SINGLE NUMBER IS QUOTED TO THE CLIENT.
    A second stale-figure problem was found in the same pass: the WORD COUNT table still carried the (o) figures and had never been updated when (p) added three sentences. Raw 7,018 → 7,101, normalised 7,396 → 7,475. The Density denominator had already moved; only the table and two SCOPE WORDS lines were left behind. They now agree. Also checked and ruled out: no <script> or <style> content falls inside the counting scope in either capture, so no JSON-LD is being counted as prose.
    An error in the original scan — three rows were on the page all along FIXED
    #3 «hit and run lawyer miami» — on the page 2× — -GSPGS  ·  #13 «hit and run accident attorney» — on the page 2× — -GSPGS  ·  #58 «gallardo law» — on the page 7× — -G-PG- THE BUG: the 2026-08-18 pass assigned the «P» flag from a fixed list of extracted phrases, so rows that entered the table from GSC or Semrush were never tested against the copy at all. All 221 rows are now tested. The on-page phrase count changed from 85 to 88 — none of which is a change to the page. This matters because #13 was later reported as one of the biggest wins of the workstream: it was at 2, not 0, before the work started, and the report says so.
    Rules adopted ADOPTED
    • Before adding any id to a <ServicesRelated> node, test the WHOLE GRAPH for reachability back to the current service — not just whether it links back directly. The check lives in the script, which refuses to write otherwise
    • Parse XML with an XML parser and locate nodes by sourceline. A raw text search over a file where the same ids appear in many records will hit the wrong one
    • Confirm freshness by string match, never by byte size — two different renders came back at the same size
    • Recount after every edit, inside the pass — three keyword trades went the wrong way and all three were invisible to reading
    • A primary source supersedes a secondary one, and the final report supersedes the live dashboard page — even when the secondary figure is widely repeated
    • Verify a legal citation against the statute text before publishing it — the page was citing 627.727 for a rule that statute does not contain, and several law-firm blogs repeat a wrong mandatory-minimum figure for the Aaron Cohen Act that the statute text contradicts
    WHAT THIS ENTIRE REPORT DOES NOT MEASURE. Every Impr and Pos figure in the keyword table was exported 2026-08-18, BEFORE any edit in (a) to (v). Nothing here is evidence that the work changed a ranking. The table shows what the edits did to the PAGE, not what Google did with it. Re-export GSC no earlier than 4–6 weeks after these changes are live in production to see that. And note that all of this was verified on LOCALHOST — none of it is in production until the site is deployed.
    Validation — RESULT: APP STARTS · 0 BROKEN ANCHORS · 0 GRAPH CYCLES · ALL EXTERNAL URLS HTTP 200
    Entry (v) — live renders, 2026-08-21 · closes the "NOT re-fetched" caveat carried by (p), (q), (r), (s), (t) and (u)
    ✓ Verified on the live render
    • THE APPLICATION STARTS. The stack overflow logged in (s) is gone; the process is resident and serving. An acyclic graph was the argument — a running process is the evidence
    • 43 in-page anchors · 0 broken · heading-1..15 all present · TOC 17 entries, every label matching its rewritten heading
    • 4/4 JSON-LD blocks parse as valid JSON · no duplicate top-level @type · no Razor @@ escape leaked into output · key sets identical to the wrongful-death page, block for block
    • 2/2 speakable selectors resolve to exactly 1 element each
    • METAS: the new description on all 3 surfaces · 903×530 appears 3× and 375×211 ZERO times · twitter:card = summary_large_image
    • BLOCK: renders exactly the intended six, in order, Medical Malpractice absent — on the English page AND the Spanish page
    • 5 contextual outbound links in the content column (bicycle 1, brain injury 1, pedestrian 1, wrongful death 2) · 5/5 inbound links live with the intended anchor text
    • 26 body cross-links across 7,104 words ≈ 1 per 270, with varied anchor text — checked because heavy internal linking with identical anchors reads as manipulation
    • All flsenate.gov and flhsmv.gov URLs fetched: HTTP 200 · breadcrumb positions 2 and 3: HTTP 200 · all 6 video-block URLs: HTTP 200
    • 0 duplicate sentences · repeated 10-word runs are all heading text appearing in the TOC and in cross-links, which is expected
    • 0 stuffed «hit and run {noun} Miami can» constructions · 0 «maximum compensation» · 0 «VIDEO_ID» · 0 British spellings anywhere in the file, Razor comments included
    • XML: whole-graph cycle detection across all 155 service records = 0 cycles · 0 dangling <Service id> references · FaqEntities.xml re-parsed valid, 1,851 other records untouched
    • File integrity: BOM preserved on every file · article.cshtml is LF and articlemetas.cshtml next to it is CRLF — each write reads its own · 32 Razor comment pairs balanced
    ⚠ Caveats worth knowing
    • Everything was verified on LOCALHOST. None of it is in production until the site is deployed
    • No GSC data postdates the edits. Every Impr and Pos figure was exported before the first change. Re-export no earlier than 4–6 weeks after production deployment
    • The 7-day User-Agent-keyed output cache makes any casual re-fetch unreliable. Confirm a known new string is present before trusting a measurement — a cache-busting query string does NOT work, because the query string is not in the vary key
    • The raw word count runs ~5% high and always has. Quote ~6,800, not 7,104, to the client. The normalised figure runs ~6.5% high and exists only so Density and the counts share one denominator
    • Entries (p) through (u) were originally counted from a hand-patched capture because the dev server was down. The live re-run in (v) measured a difference of exactly +3 raw words — the new meta description is 28 words where the old was 25. The patching method reproduced the render exactly; nothing else moved. The keyword table was then re-run against the live render, 221 rows rewritten
    • «hit and run» density is 5.78% — down from 8.22% without removing a single instance, but still well above the 1–3% comfort range. It is the page's exact-match term and it is moving the right way, but it should keep moving
    • Hyphenation is still inconsistent: 44 hyphenated / 18 unhyphenated. The title, H1 and og:title use the unhyphenated form; almost all body copy uses the hyphenated one. Both normalise identically for search, but it is worth making consistent
    • Zero <img> elements across 7,104 words. The five tables cover part of what images were wanted for — visual break, scannability — but there are still no images. 903×530 exists; no sibling uses body images
    • The renderer STRIPS OPTIONAL CLOSING TAGS: </p> and </li> are absent from the served HTML though present in the source. Worth remembering for any future source-to-capture matching
    • The 2026 YTD statistics table is explicitly a year-to-date snapshot and needs periodic refreshing or rewording. The by-year table needs the 2025 annual report, which FLHSMV has not published
    Status — Done vs Open
    Final verification 2026-08-21  ·  22 entries (a)–(v)  ·  3 files on this page + ServiceEntities.xml + 5 other pages
    ✓ Done
    • Scope 2,162 → 7,104 raw words · every one of the 15 original H2 sections reviewed, 12 rewritten, 2 new named-anchor sections added
    • FAQ block 0 → 10 of 10 slots (983 words) with schema.org/FAQPage — a data gap closed without touching view code
    • JSON-LD 1 → 4 blocks, built to the house format, 9 areaServed values each verified present in the copy first
    • The page's first data tables (5) and its first real ordered lists — both built for extractability against a SERP that is 100% PAA and 70% AI Overview
    • Six wrong FLHSMV figures corrected against the primary annual report; the Miami-Dade 1-in-3 ratio added, the strongest local fact on the page
    • A leaked editorial instruction removed from live copy; «maximum compensation» taken to zero; a misattributed statute removed
    • Four stuffed «hit and run {noun} Miami» sentences replaced with four distinct terms in fluent English
    • VideoObject fixed — thumbnailUrl, uploadDate, orphaned itemprop, contentUrl and publisher
    • Outbound internal links 3 → 5, inbound 1 → 6, related-services block moved into the cluster — and the startup cycle it introduced found and fixed
    • Meta description rewritten for CTR on three surfaces; social card 375×211 → 903×530 with summary_large_image
    • Sitemap lastmod refreshed for the EN and ES URLs, which had read 2025-05-21
    Standing instruction: every change made to this page is logged in miami-hit-and-run-accident-lawyer-improvements.txt as a matter of course, without being asked. Each pass gets its own CHANGE LOG section appended below the previous one, in the established format — lettered entries continuing the existing (a)–(v) sequence, with WHAT changed, the SOURCE or rule relied on, the KEYWORDS reinforced with their volume/KD data, the validation run, and the updated open-items list carried forward. To refresh the keyword table after the next round: re-fetch the page with a fresh User-Agent, confirm freshness by string match, then re-run scratchpad/addcol.py — it re-asserts every Before figure against what is already in the table, so «Before» keeps meaning 2026-08-18 no matter how many times it runs.