/* Self-hosted, subset to the 109 glyphs this site renders: 32 KB for both.
   Zilla Slab is static at 700 because that is the only serif weight in use.
   Work Sans is variable, declared as a range, which is what lets the 650 in the
   table headers resolve to a real weight instead of a faked bold.
   Deliberately a different pairing from the porta potty site. */
@font-face{font-family:"Zilla Slab";src:url(/assets/fonts/ZillaSlab-700w.woff2) format("woff2");
  font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:"Work Sans";src:url(/assets/fonts/WorkSans-var.woff2) format("woff2-variations"),
  url(/assets/fonts/WorkSans-var.woff2) format("woff2");
  font-weight:100 900;font-style:normal;font-display:swap}

:root{
  /* Deep ink navy and copper on warm paper.
     Same structural move as the porta potty site, deliberately not the same
     palette: that one took forest and brass, so two directories run by the same
     shop would otherwise read as one template wearing different words. Copper is
     the industrial counterpart to brass, and it belongs to a trade of steel
     containers and hauling far better than the old safety-amber did.
     Deep replaces pale, every neutral goes warm, and the near-black CTA is gone. */
  --ink:#101822; --muted:#5a6470; --line:#e4e1da; --bg:#faf8f4; --soft:#f2efe9;
  --navy:#0e2438; --accent:#15618f; --good:#1f7a4d; --warn:#b3541e;
  /* Copper is a highlight, never a button and never body text: stat rules, the
     lead figure, hairline accents. One warm note against the navy is the effect. */
  --amber:#b4643c; --amber-deep:#8f4c2c;
  --oncolor:var(--bg); --oncolor-dim:rgba(255,255,255,.85); --accent-light:#e8b48f;
  --steel:#24313f;
  /* Every figure on this site is meant to be compared with another figure, so
     numbers are monospaced and tabular throughout. It is the single change that
     makes a price table read as data rather than as decoration. */
  /* Three roles, three faces.
     Serif for anything you read: this is a price report, and a text serif carries
     that better than the system UI font, which is also the face every generated
     page defaults to. Iowan and Charter on Apple, Sitka and Cambria on Windows,
     Georgia as the floor, so it lands somewhere considered on every machine and
     costs no webfont request.
     Sans is kept for the interface only, labels, buttons, table headings.
     Mono for every figure, because the whole product is numbers being compared. */
  --serif:"Zilla Slab","Iowan Old Style",Charter,Cambria,Georgia,serif;
  --sans:"Work Sans","Avenir Next","Segoe UI",system-ui,-apple-system,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
  --wrap:1040px;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
/* Body is sans, headings stay serif.
   The body was 17px serif at 1.62 — good for reading an essay, wrong for a page
   somebody is scanning to compare eight companies. With headings at 22px serif
   and body at 17px serif there was barely a weight difference between a section
   title and the paragraph under it, so a long page read as one block with
   nothing to catch the eye. Serif headings keep the character and keep it off
   the sans-everything default that every generated site lands on. */
body{
  margin:0;background:var(--bg);color:var(--ink);
  font:16px/1.58 var(--sans);
  font-feature-settings:"kern" 1;
  text-rendering:optimizeLegibility;
}
b,strong{font-weight:650}
a{color:var(--accent)}
a:hover{color:var(--navy)}
main{max-width:var(--wrap);margin:0 auto;padding:24px 20px 56px}

/* header / footer */
header.site{border-bottom:1px solid var(--line);background:#fff}
.brand{
  display:inline-block;max-width:var(--wrap);margin:0 auto;padding:16px 20px;
  font-weight:700;font-size:19px;letter-spacing:-.01em;color:var(--navy);text-decoration:none
}
.brand span{color:var(--accent)}
footer.site{
  border-top:1px solid var(--line);background:var(--soft);
  padding:24px 20px;font-size:14px;color:var(--muted)
}
footer.site p{max-width:var(--wrap);margin:0 auto 8px}

/* type */
h1{font:700 34px/1.16 var(--serif);letter-spacing:-.02em;margin:.15em 0 .35em}
h2{font:700 25px/1.25 var(--serif);letter-spacing:-.015em;margin:2.2em 0 .55em}
h3{font:700 17px/1.35 var(--sans);letter-spacing:-.005em;margin:1.6em 0 .4em}
/* a rule above each section gives the eye somewhere to stop on a long page */
main h2{padding-top:.55em;border-top:1px solid var(--line)}
main h2:first-of-type{border-top:0;padding-top:0}
.lede{font-size:18.5px;line-height:1.5;color:var(--muted);margin-top:0;max-width:62ch}
main p{max-width:68ch}
.muted{color:var(--muted)}
.fine{font-size:13px;color:var(--muted)}

/* breadcrumbs */
.crumbs{font-size:13px;color:var(--muted);margin-bottom:14px}
.crumbs i{font-style:normal;opacity:.5;margin:0 4px}

/* hero + cta */
.hero{padding:12px 0 4px}
.cta{margin-top:40px;padding:22px;background:var(--soft);border:1px solid var(--line);border-radius:8px}
.cta h2{margin-top:0}
.btn{
  display:inline-block;background:var(--navy);color:#fff;text-decoration:none;
  padding:11px 20px;border-radius:6px;font-weight:600
}
.btn:hover{background:var(--accent);color:#fff}

/* grids + cards */
.grid{list-style:none;padding:0;margin:0;display:grid;gap:2px;
  grid-template-columns:repeat(auto-fill,minmax(210px,1fr))}
.grid li{padding:9px 10px;border-bottom:1px solid var(--line);display:flex;
  justify-content:space-between;gap:10px;align-items:baseline}
.cards{list-style:none;padding:0;margin:0}
.cards li{padding:10px 0;border-bottom:1px solid var(--line);display:flex;
  justify-content:space-between;gap:12px;flex-wrap:wrap}

/* listing table */
table.listing{width:100%;border-collapse:collapse;margin:16px 0;font-size:15px}
table.listing th{
  text-align:left;font-size:12px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);border-bottom:2px solid var(--line);padding:8px 10px 8px 0;font-weight:600
}
table.listing td{padding:11px 10px 11px 0;border-bottom:1px solid var(--line);vertical-align:top}
table.listing tr:hover td{background:var(--soft)}
.tag{
  display:inline-block;margin-left:7px;font-size:11px;color:var(--warn);
  border:1px solid currentColor;border-radius:3px;padding:1px 5px;vertical-align:1px
}

/* Present to a screen reader and to a crawler, absent on screen. Used to give a
   link a real name where the visible text is a drawing plus two fragments. */
.vh{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0
}

/* size-to-job table: reference content, so it reads quieter than the listing */
table.sizefit{width:100%;border-collapse:collapse;margin:14px 0 18px;font-size:15px}
table.sizefit caption{
  text-align:left;font-size:12px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);padding-bottom:6px
}
table.sizefit th{
  text-align:left;font-size:12px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);border-bottom:2px solid var(--line);padding:8px 12px 8px 0;font-weight:600
}
table.sizefit td{padding:10px 12px 10px 0;border-bottom:1px solid var(--line);vertical-align:top}
table.sizefit td:first-child{white-space:nowrap;font-variant-numeric:tabular-nums;font-weight:600}

/* profile */
.phead{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap}
.phead h1{margin-top:0}
.where{color:var(--muted);margin:.2em 0 .5em}
.rating b{font-size:18px}
.badge{font-size:12px;font-weight:600;padding:4px 10px;border-radius:20px;white-space:nowrap}
.badge.unclaimed{background:#fdf2e6;color:var(--warn);border:1px solid #f0d5b8}

dl.facts{
  display:grid;grid-template-columns:120px 1fr;gap:0;margin:22px 0;
  border-top:1px solid var(--line);font-size:15px
}
dl.facts dt{padding:11px 0;color:var(--muted);border-bottom:1px solid var(--line)}
dl.facts dd{padding:11px 0;margin:0;border-bottom:1px solid var(--line);word-break:break-word}

/* health card */
.hcard{background:var(--soft);border:1px solid var(--line);border-radius:8px;padding:18px 20px;margin:28px 0}
.hcard h2{margin:0 0 12px;font-size:17px}
.bar{height:8px;background:#e3e9ef;border-radius:5px;overflow:hidden;margin-bottom:14px}
.bar span{display:block;height:100%;background:var(--accent)}
ul.gaps{margin:0 0 12px;padding-left:20px}
ul.gaps li{margin-bottom:4px;color:var(--warn)}

/* forms */
form.claim{margin:16px 0;max-width:640px}
form.claim label{display:block;margin-bottom:14px;font-size:14px;font-weight:600}
form.claim input,form.claim textarea{
  display:block;width:100%;margin-top:5px;padding:10px 12px;font:inherit;font-weight:400;
  border:1px solid var(--line);border-radius:6px;background:#fff
}
form.claim input:focus,form.claim textarea:focus{outline:2px solid var(--accent);outline-offset:-1px}
form.claim .row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
form.claim button{
  background:var(--navy);color:#fff;border:0;padding:12px 24px;border-radius:6px;
  font:inherit;font-weight:600;cursor:pointer
}
form.claim button:hover{background:var(--accent)}
.hp{position:absolute;left:-9999px}

@media (max-width:620px){
  h1{font-size:23px}
  main{padding:18px 16px 40px}
  dl.facts{grid-template-columns:96px 1fr;font-size:14px}
  form.claim .row{grid-template-columns:1fr;gap:0}
  table.listing{font-size:14px}
}

.badge.reference{background:#f2efe9;color:var(--muted);border:1px solid var(--line)}
.tag.ref{color:var(--muted)}

a.site{display:block;font-size:12.5px;color:var(--muted);text-decoration:none;margin-top:2px}
a.site:hover{color:var(--accent);text-decoration:underline}

.actions{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0 0}
.btn.call{background:var(--good)}
.btn.call:hover{background:#175f3c}
.btn.ghost{background:#fff;color:var(--navy);border:1px solid var(--line)}
.btn.ghost:hover{background:var(--soft);color:var(--navy)}
.btn.tiny{padding:7px 13px;font-size:14px;font-weight:600;white-space:nowrap;background:var(--soft);
  color:var(--navy);border:1px solid var(--line)}
.btn.tiny:hover{background:var(--navy);color:#fff;border-color:var(--navy)}
@media (max-width:620px){ .actions .btn{flex:1;text-align:center} }

.chip{display:inline-block;background:#f2efe9;color:var(--navy);border:1px solid #e4e1da;
  border-radius:4px;padding:2px 8px;margin:0 5px 4px 0;font-size:13px;font-weight:600}
.sizes{display:block;font-size:12.5px;color:var(--navy);margin-top:3px;letter-spacing:.01em}
.srcnote{margin:-8px 0 22px}

.pricing{margin:28px 0}
table.ptable{width:100%;border-collapse:collapse;font-size:15px;margin-bottom:10px}
table.ptable th{text-align:left;font-size:12px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);border-bottom:2px solid var(--line);padding:8px 12px 8px 0;font-weight:600}
table.ptable td{padding:10px 12px 10px 0;border-bottom:1px solid var(--line)}
.pcell{font-weight:700;color:var(--navy)}
.from{font-weight:700;color:var(--navy);white-space:nowrap}

.based{display:block;font-size:12px;color:var(--good);font-weight:600;margin-top:2px}
.away{display:block;font-size:12px;color:var(--muted);margin-top:2px}

table.ptable.idx td:first-child{font-weight:600}
table.ptable.idx th:not(:first-child),table.ptable.idx td:not(:first-child){text-align:right}
ul.terms{margin:0 0 14px;padding-left:20px}
ul.terms li{margin-bottom:6px}

dl.faq{margin:14px 0 0}
dl.faq dt{font-weight:600;margin-top:16px}
dl.faq dd{margin:5px 0 0;color:var(--muted)}

.fnav{max-width:var(--wrap);margin:0 auto 10px;line-height:2}
/* A multi-word footer link must not break across two lines. "Ghost Listings"
   was rendering as "Ghost" at the end of one row and "Listings" at the start of
   the next, which reads as two broken links rather than one. */
.fnav a{margin-right:2px;white-space:nowrap}

.grid.nearby li{font-size:14px}

ul.stats{padding-left:20px}
ul.stats li{margin-bottom:12px;line-height:1.65}
.two{display:grid;grid-template-columns:1fr 1fr;gap:28px}
.two h3{font-size:15px;margin:0 0 8px}
ol.rank{margin:0;padding-left:22px;font-size:15px}
ol.rank li{margin-bottom:6px}
p.cite{background:#fff;border:1px solid var(--line);border-radius:6px;padding:12px 14px;
  font-size:14px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;line-height:1.55}
dl.gloss dt{font-size:16px}
@media (max-width:620px){ .two{grid-template-columns:1fr;gap:18px} }

/* ---- header nav ---- */
.hwrap{max-width:var(--wrap);margin:0 auto;padding:0 20px;display:flex;
  align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}
.hwrap .brand{padding:16px 0}
.hnav{display:flex;gap:18px;font-size:14.5px;font-weight:600}
.hnav a{color:var(--muted);text-decoration:none;padding:6px 0;border-bottom:2px solid transparent}
.hnav a[aria-current="page"]{font-weight:700;text-decoration:underline;text-underline-offset:4px}
.hnav a:hover{color:var(--navy);border-bottom-color:var(--accent)}

/* ---- listing table becomes cards on a phone ----
   The phone number is the primary action in this category and a horizontally
   scrolled table hides it off-screen. Restack instead of scrolling. */
@media (max-width:680px){
  table.listing,table.listing tbody,table.listing tr,table.listing td{display:block;width:100%}
  table.listing thead{position:absolute;left:-9999px}
  table.listing tr{border:1px solid var(--line);border-radius:8px;padding:14px;margin-bottom:12px}
  table.listing tr:hover td{background:transparent}
  table.listing td{border:0;padding:0}
  table.listing td:first-child{font-size:16px;margin-bottom:10px}
  table.listing td[data-label]{display:inline-flex;align-items:baseline;gap:6px;
    margin-right:16px;font-size:14px;color:var(--muted)}
  table.listing td[data-label]::before{content:attr(data-label);font-size:11px;
    text-transform:uppercase;letter-spacing:.06em;color:var(--muted);opacity:.75}
  table.listing td.cell-call{margin-top:12px}
  table.listing td.cell-call .btn.tiny{display:block;text-align:center;padding:11px;
    font-size:15px;background:var(--navy);color:#fff;border-color:var(--navy)}
  .hnav{gap:14px;font-size:13.5px;width:100%;padding-bottom:10px}
  .hwrap .brand{padding:14px 0 4px}
}

/* index tables scroll rather than restack — they are genuinely tabular */
table.ptable{display:block;overflow-x:auto;white-space:nowrap}
@media (min-width:681px){ table.ptable{display:table;white-space:normal} }

.cards.guides li{display:block;padding:14px 0}
.cards.guides a{font-weight:600;font-size:16px}
.cards.guides .muted{display:block;margin-top:3px;font-size:14px}
hr.rule{border:0;border-top:1px solid var(--line);margin:32px 0 16px}

.byline{font-size:14px;color:var(--muted);margin:-6px 0 14px}
.cards.posts li{display:block;padding:16px 0}
.cards.posts a{font-weight:600;font-size:16.5px}
.cards.posts time{display:block;font-size:13px;color:var(--muted);margin-top:2px}
.cards.posts .muted{display:block;margin-top:5px;font-size:14px;line-height:1.55}
.pagi{display:flex;justify-content:space-between;gap:16px;font-size:14px;margin:16px 0}

.psize{display:block;font-size:11.5px;color:var(--muted);font-weight:500;margin-top:1px}

/* chart */
figure.chart{margin:18px 0 22px;padding:0}
figure.chart svg{display:block;width:100%;height:auto;overflow:visible}
figure.chart svg g:hover path{fill:var(--navy)}
figure.chart figcaption{font-size:13px;color:var(--muted);margin-top:10px;max-width:62ch}

/* ---- homepage hero: this is a data product, so lead with the numbers ---- */
.hero{padding:22px 0 6px}
.hero h1{font-size:34px;max-width:19ch}
@media (max-width:620px){ .hero h1{font-size:27px} }

.statbar{
  display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:8px;overflow:hidden;margin:26px 0 22px;
  grid-template-columns:repeat(auto-fit,minmax(150px,1fr))
}
.statbar div{background:#fff;padding:15px 16px}
.statbar b{
  display:block;font-size:25px;line-height:1.15;letter-spacing:-.02em;
  color:var(--navy);font-weight:700
}
.statbar span{
  display:block;margin-top:4px;font-size:11.5px;text-transform:uppercase;
  letter-spacing:.06em;color:var(--muted);font-weight:600
}
@media (max-width:620px){
  .statbar{grid-template-columns:1fr 1fr}
  .statbar b{font-size:21px}
}

.hero-cta{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 8px}
@media (max-width:620px){ .hero-cta .btn{flex:1;text-align:center} }

/* The dated, sourced line under a price heading. Small, but it is the line that
   makes the number quotable rather than just another figure on a page. */
.stamp{
  font-size:13px;color:var(--muted);margin:-2px 0 12px;
  padding-left:11px;border-left:3px solid var(--line)
}
.sub{font-size:14px;color:var(--muted);margin:-4px 0 12px}

.explain{
  margin:34px 0;padding:22px 24px;background:var(--soft);
  border:1px solid var(--line);border-radius:8px
}
.explain h2{margin-top:0}
.explain p:last-child{margin-bottom:0}
.explain .stamp{border-left-color:#cfd6cf}

.grid.cities li,.grid.states li{font-size:14.5px}
.grid.states .muted{white-space:nowrap;font-variant-numeric:tabular-nums}

ul.sizelist{list-style:none;padding:0;margin:12px 0 16px;display:grid;gap:2px;
  grid-template-columns:repeat(auto-fill,minmax(210px,1fr))}
ul.sizelist li{padding:9px 10px;border-bottom:1px solid var(--line);display:flex;
  justify-content:space-between;gap:10px;align-items:baseline;font-size:14.5px}

/* ============================================================================
   Product surface

   The look this is aiming at is trade software, not a content site: a masthead
   with a mark, dense hairline tables, uppercase micro-labels, and monospaced
   tabular figures everywhere a number appears. Corners are 3px because precision
   reads as more credible than friendliness when the whole product is a price.
   ========================================================================== */

/* ---- masthead ---- */
header.site{
  border-bottom:1px solid var(--line);background:#fff;
  box-shadow:inset 0 3px 0 var(--steel)
}
.hwrap{padding:0 20px}
.brand{
  display:flex;align-items:center;gap:9px;padding:14px 0;
  font-weight:700;font-size:17.5px;letter-spacing:-.012em;color:var(--steel)
}
.brand span{color:var(--accent)}
.brand svg{display:block;flex:none}
.hnav{gap:20px;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.07em}
.hnav a{color:var(--muted);padding:7px 0;border-bottom:2px solid transparent}
.hnav a:hover{color:var(--steel);border-bottom-color:var(--amber)}

/* ---- numbers ---- */
.pcell,.from,.statbar b,.rating b,.grid .muted,.sizelist .muted,
table.ptable td:not(:first-child),.crumbs .muted{
  font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;letter-spacing:-.02em
}
.pcell,.from{font-weight:700;color:var(--steel)}
.psize{font-family:var(--mono);letter-spacing:0}

/* ---- micro-labels ---- */
.statbar span,table.listing th,table.ptable th,.badge,.tag{
  font-variant-numeric:normal;letter-spacing:.07em
}

/* ---- tables: hairlines, zebra, numbers right ---- */
table.listing,table.ptable{border:1px solid var(--line);border-radius:3px}
table.listing th,table.ptable th{
  background:var(--soft);border-bottom:1px solid var(--line);
  padding:9px 12px;font-size:11px;color:var(--muted)
}
table.listing td,table.ptable td{padding:12px}
table.listing tbody tr:nth-child(even){background:#fbfcfd}
table.listing tbody tr:last-child td,table.ptable tbody tr:last-child td{border-bottom:0}
table.listing tr:hover td{background:#f2efe9}
table.ptable td:first-child{font-weight:600}
table.ptable th:not(:first-child),table.ptable td:not(:first-child){text-align:right}
table.ptable td:not(:first-child){color:var(--steel)}

/* ---- surfaces ---- */
.cta,.hcard,.explain,.statbar,p.cite,.btn,.chip,
form.claim input,form.claim textarea,form.claim button{border-radius:3px}
.cta{background:var(--soft);border-color:var(--line)}
.btn{background:var(--steel);font-weight:650;letter-spacing:.005em}
.btn:hover{background:var(--navy)}
.btn.ghost:hover{border-color:var(--muted)}

/* ---- statbar: the index reading ---- */
.statbar{border-radius:3px;border-top:2px solid var(--amber)}
.statbar b{font-size:23px;color:var(--steel);font-weight:700;letter-spacing:-.03em}
.statbar span{font-size:10.5px;letter-spacing:.08em}
.statbar div:first-child b{color:var(--amber-deep)}

/* ---- the dated, sourced line ---- */
.stamp{
  font-family:var(--mono);font-size:11.5px;line-height:1.55;letter-spacing:-.01em;
  border-left-width:2px;border-left-color:var(--amber);padding-left:10px
}
.explain .stamp{border-left-color:var(--amber)}

/* ---- explain block reads as a report note ---- */
.explain{border-left:2px solid var(--line)}

/* ---- grids: rules on both axes, like a spec sheet ---- */
.grid,ul.sizelist{gap:0;border-top:1px solid var(--line)}
.grid li,ul.sizelist li{border-bottom:1px solid var(--line);padding:8px 12px 8px 2px}
.grid li:hover,ul.sizelist li:hover{background:var(--soft)}

/* ---- footer: closing plate ---- */
footer.site{background:var(--steel);color:#9fb0bf;border-top:0}
footer.site p{color:#8fa2b2;font-size:13px}
footer.site a{color:#cfd6cf;text-decoration:none}
footer.site a:hover{color:#fff;text-decoration:underline}
.fnav{font-size:13px}

@media (max-width:620px){
  .hnav{font-size:11px;letter-spacing:.05em;gap:14px}
  .brand{font-size:16px}
  table.listing td,table.ptable td{padding:10px}
}
@media (max-width:680px){
  table.listing{border:0;border-radius:0}
  table.listing tr{border-radius:3px}
  table.listing tbody tr:nth-child(even){background:transparent}
}
.brand b{font-weight:700;letter-spacing:-.015em}

/* Numeric columns align right and hold a fixed width, so prices and ratings stack
   into scannable columns instead of drifting with the company name beside them.
   Desktop only: below 680px the table restacks into cards. */
@media (min-width:681px){
  table.listing th:nth-child(2),table.listing td:nth-child(2),
  table.listing th:nth-child(3),table.listing td:nth-child(3){text-align:right}
  table.listing th:nth-child(2),table.listing th:nth-child(3){width:112px}
  table.listing th:nth-child(4){width:168px}
  table.listing td:nth-child(4){text-align:right}
}
@media (min-width:681px){
  table.listing th:nth-child(3){width:134px}
  table.listing th:nth-child(4){text-align:right}
}

/* The desktop cell padding must not survive the restack, or the inline PRICE and
   GOOGLE labels get pushed onto separate lines inside each card. */
@media (max-width:680px){
  table.listing td{padding:0}
  table.listing td[data-label]{margin-right:18px}
  table.listing tr{padding:14px 16px}
}

/* ---- charts ---- */
figure.chart{margin:14px 0 30px}
figure.chart svg{display:block;width:100%;height:auto;overflow:visible}
figure.chart figcaption{
  font-size:13px;color:var(--muted);margin-top:12px;max-width:70ch;line-height:1.55
}

/* range plot: sizes against a shared price scale */
.chart.ranges .gl{stroke:#e8edf2;stroke-width:1}
.chart.ranges .ax{font:600 11px/1 var(--mono);fill:var(--muted);letter-spacing:-.02em}
.chart.ranges .sz{font:650 14px/1 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;fill:var(--ink)}
.chart.ranges .band{fill:#f6dcb4}
.chart.ranges .med{fill:#8f4c2c}
.chart.ranges .val{font:700 15px/1 var(--mono);fill:var(--steel);letter-spacing:-.03em}
.chart.ranges .n{font:400 10.5px/1 var(--mono);fill:var(--muted)}
.chart.ranges .rw:hover .band{fill:#f0cd97}

/* tile grid map */
.chart.tilemap .ab{font:700 12px/1 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;letter-spacing:.02em}
.chart.tilemap .pr{font:600 10.5px/1 var(--mono);letter-spacing:-.03em;opacity:.82}
.chart.tilemap .lg{font:500 11px/1 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;fill:var(--muted)}
/* No data reads as an absence: white, dashed, and lighter than any band. */
.chart.tilemap .nd rect{fill:#fff;stroke:#ccd6de;stroke-width:1;stroke-dasharray:3 3}
.chart.tilemap .nd .ab{fill:#b3bfc9;font-weight:600}
.chart.tilemap a.tl{cursor:pointer}
.chart.tilemap a.tl rect{transition:none}
.chart.tilemap a.tl:hover rect{stroke:var(--steel);stroke-width:2}

/* The legend runs out of room on a phone, so the map drops it and the caption
   carries the reading instead. */
@media (max-width:620px){
  .chart.ranges .sz{font-size:13px}
  .chart.tilemap .pr{display:none}
}

/* City price table: long, so it scrolls in its own box rather than running the page
   to 400 rows, and the delta column is coloured because that is the column people
   actually scan. */
table.citytable{display:block;max-height:560px;overflow-y:auto;white-space:normal}
table.citytable thead th{position:sticky;top:0;z-index:1;background:var(--soft);
  box-shadow:inset 0 -1px 0 var(--line)}
table.citytable td.up{color:var(--amber-deep);font-weight:600}
table.citytable td.down{color:#1f5d8a;font-weight:600}

/* Table sort controls. Hidden in the markup and revealed by script, so a reader
   without JavaScript never sees a button that cannot do anything. */
.tctl{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:14px 0 10px}
.tctl[hidden]{display:none}
.tctl-l{font-size:11px;text-transform:uppercase;letter-spacing:.07em;
  color:var(--muted);font-weight:700;margin-right:2px}
.tctl button{
  font:inherit;font-size:13.5px;font-weight:600;cursor:pointer;
  background:#fff;color:var(--steel);border:1px solid var(--line);
  border-radius:3px;padding:6px 13px
}
.tctl button:hover{border-color:var(--muted)}
.tctl button[aria-pressed="true"]{
  background:var(--steel);color:#fff;border-color:var(--steel)
}
.tctl-f{display:flex;align-items:center;gap:6px;font-size:13.5px;
  color:var(--muted);cursor:pointer;margin-left:4px}
.tctl-f input{accent-color:var(--steel);cursor:pointer}
/* Size chips read as a second row of controls rather than more sort buttons, and
   carry the local count so a chip that would empty the table is visibly the one
   to avoid. */
.tctl-n{margin-left:auto;font-size:var(--fs-sm);color:var(--muted);font-variant-numeric:tabular-nums}
.vtick{display:inline-flex;align-items:center;gap:3px;font-size:var(--fs-micro);font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;color:var(--ok,#1c6b3f)}
.jtag{display:inline-flex;align-items:center;font-size:var(--fs-micro);font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.vtick::before{content:"\2713";font-weight:900}
.tctl .uchip{display:inline-flex;align-items:center;gap:6px}
.tctl .uchip .muted{font-weight:700;font-variant-numeric:tabular-nums;opacity:.7}
.tctl .uchip[aria-pressed="true"] .muted{color:#fff;opacity:.85}
@media (max-width:620px){
  .tctl{gap:6px}
  .tctl button{padding:6px 11px;font-size:13px}
  .tctl-f{width:100%;margin-left:0}
}

/* Compact standing strip on a company profile. Same component as the homepage
   statbar, tightened because it sits above the fold next to the call button. */
.statbar.compact{margin:18px 0 10px}
.statbar.compact div{padding:12px 14px}
.statbar.compact b{font-size:20px}
.statbar.compact span{font-size:10px}

/* The company whose page this is, inside its own comparison table. */
table.compare tr.self td{background:#f7f0e6}
table.compare tr.self:hover td{background:#fbf0dc}
table.compare tr.self td:first-child{box-shadow:inset 3px 0 0 var(--amber)}
@media (max-width:680px){
  table.compare tr.self{border-color:var(--amber);background:#f7f0e6}
  table.compare tr.self td:first-child{box-shadow:none}
}

/* Company mark. A third of companies publish no usable logo, so the monogram is
   not a placeholder for a missing feature, it is the design for that case. */
.pident{display:flex;align-items:flex-start;gap:16px}
/* Wider than tall, because company logos are: a wordmark squeezed into a square
   box is mostly empty space with unreadable type in the middle. */
.logo{
  flex:none;width:112px;height:70px;object-fit:contain;background:#fff;
  border:1px solid var(--line);border-radius:4px;padding:6px 8px
}
.logo.mono{
  width:70px;display:flex;align-items:center;justify-content:center;padding:0;
  font:700 26px/1 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  letter-spacing:-.02em;color:#fff;background:var(--m);border-color:var(--m)
}
@media (max-width:620px){
  .logo{width:88px;height:56px}
  .logo.mono{width:56px;font-size:21px}
  .pident{gap:12px}
}

/* Confirmed by phone. The only claim on this site that did not come off a crawler,
   so it gets the one colour reserved for something being genuinely verified. */
.badge.verified{background:#e8f5ee;color:var(--good);border:1px solid #b9dfc9}
.srcnote.confirmed{
  color:var(--good);border-left:2px solid var(--good);padding-left:11px;font-weight:500
}

/* Social profile links. nofollow throughout: these are identity signals for a
   machine, not endorsements, and we are not passing rank to Facebook. */
.socials{display:flex;flex-wrap:wrap;gap:6px}
.socials a{
  display:inline-flex;align-items:center;gap:6px;
  font-size:12.5px;font-weight:600;text-decoration:none;color:var(--steel);
  background:#fff;border:1px solid var(--line);border-radius:3px;padding:5px 10px 5px 8px
}
.socials a:hover{background:var(--soft);border-color:var(--muted)}
.socials svg{flex:none;display:block}

/* Earned badges.
   Three families because they answer different questions: value is what the money
   buys, rep is what other customers found, trust is who they are. Within each, the
   hard-won ones are filled solid and the rest are tinted, so a page with eight
   badges still has an obvious first thing to read. Each carries a title with the
   figure behind it. */
ul.badges{
  display:flex;flex-wrap:wrap;gap:7px;list-style:none;padding:0;margin:16px 0 0
}
ul.badges li{
  display:inline-flex;align-items:center;gap:6px;
  font-size:12.5px;font-weight:700;letter-spacing:.005em;line-height:1;
  padding:7px 12px 7px 10px;border-radius:4px;border:1px solid;
  white-space:nowrap
}
ul.badges svg{flex:none;opacity:.9}

/* tinted */
.b-value{background:#f7f0e6;color:#8a5510;border-color:#eed7ab}
.b-rep{background:#e9f6ef;color:#186b4c;border-color:#bfe0cd}
.b-trust{background:#f2efe9;color:var(--steel);border-color:#e4e1da}

/* earned the hard way: solid, and carrying a little more weight */
.b-value.top{background:#b5710f;color:#fff;border-color:#9c6009;
  box-shadow:0 1px 0 rgba(0,0,0,.06)}
.b-rep.top{background:#1a6b4b;color:#fff;border-color:#155739;
  box-shadow:0 1px 0 rgba(0,0,0,.06)}
.b-trust.top{background:var(--steel);color:#fff;border-color:#0f1a24;
  box-shadow:0 1px 0 rgba(0,0,0,.06)}
ul.badges li.top svg{opacity:1}

@media (max-width:620px){
  ul.badges{gap:6px}
  ul.badges li{font-size:11.5px;padding:6px 10px 6px 8px;gap:5px}
  ul.badges svg{width:12px;height:12px}
}
a.logolink{display:block;flex:none;border-radius:4px}
a.logolink:hover .logo{border-color:var(--amber)}
a.logolink:focus-visible{outline:2px solid var(--amber);outline-offset:2px}

/* ZIP lookup. Hidden in the markup and revealed by script, so nobody without
   JavaScript is shown a box that cannot do anything; the state and city grids
   below are the path in that case. */
.ziplook{margin:20px 0 4px;max-width:420px}
.ziplook[hidden]{display:none}
.ziplook label{
  display:block;font-size:11px;text-transform:uppercase;letter-spacing:.08em;
  color:var(--muted);font-weight:700;margin-bottom:6px
}
.ziprow{display:flex;gap:8px}
.ziprow input{
  flex:1;min-width:0;font:700 17px/1.2 var(--mono);font-variant-numeric:tabular-nums;
  letter-spacing:.04em;color:var(--ink);background:#fff;border:1px solid var(--line);
  border-radius:3px;padding:11px 13px
}
.ziprow input:focus-visible,.ziprow button:focus-visible{outline:2px solid var(--amber);outline-offset:1px}
.ziprow button{
  font:650 14.5px/1 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  cursor:pointer;background:var(--steel);color:#fff;border:1px solid var(--steel);
  border-radius:3px;padding:0 18px;white-space:nowrap
}
.ziprow button:hover{background:var(--navy);border-color:var(--navy)}
.zipout{min-height:1.2em;margin:7px 0 0;font-size:13px;color:var(--muted)}
@media (max-width:480px){ .ziprow{flex-direction:column} .ziprow button{padding:12px} }
/* A logo drawn in white for a dark header gets one. */
.logo.ondark{background:var(--steel);border-color:var(--steel)}
a.logolink:hover .logo.ondark{border-color:var(--amber)}


/* ---- interface furniture stays sans ---- */
.brand,.hnav,.crumbs,.btn,.badge,ul.badges li,.statbar span,.tctl,.tctl button,
table.listing th,table.ptable th,label,select,input,button,.terms span,
.sizes,.based,.away,.tag,.chip,figcaption,.fine,.sub,.zipout,.ziprow button,
.fnav,footer.site,.pagi,.psize,.socials a,dl.facts dt{
  font-family:var(--sans)
}
.logo.mono{font-family:var(--sans)}
/* the site's own headline face should not leak into the data */
.pcell,.from,.statbar b,table.ptable td:not(:first-child){font-family:var(--mono)}
/* serif needs a touch more air between rows than the UI font did */
table.listing td{line-height:1.5}
dl.faq dt{font-family:var(--serif);font-size:17px}

/* Container sizes, drawn against a shared scale.
   The point of the drawing is the comparison: a 20, 30 and 40 share a footprint
   and differ only in wall height, which a list of numbers cannot show. Every
   silhouette uses the same pixels-per-foot, so the row is honest. */
ul.sizerow{
  list-style:none;padding:0;margin:14px 0 10px;
  display:grid;gap:2px;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));
  align-items:stretch
}
ul.sizerow li{margin:0}
ul.sizerow li{display:flex}
ul.sizerow a,ul.sizerow .nolink{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;
  padding:10px 6px 12px;border-radius:4px;text-decoration:none;color:inherit;
  border:1px solid transparent
}
ul.sizerow a:hover{background:var(--soft);border-color:var(--line)}
ul.sizerow a:focus-visible{outline:2px solid var(--amber);outline-offset:-2px}
.cbox{display:block;width:100%;height:auto;max-width:150px}
.cbody{fill:#f3d9b0;stroke:#c9922f;stroke-width:1.2;stroke-linejoin:round}
.crim{stroke:#8f4c2c;stroke-width:2;stroke-linecap:round;fill:none}
.crail{fill:var(--steel)}
ul.sizerow a:hover .cbody{fill:#eecd97}
ul.sizerow b{
  font:700 15px/1 var(--sans);margin-top:8px;color:var(--steel);
  font-variant-numeric:tabular-nums
}
ul.sizerow a b{color:var(--accent)}
ul.sizerow small{
  font:600 10.5px/1.3 var(--sans);text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);margin-top:4px;text-align:center
}
@media (max-width:620px){
  ul.sizerow{grid-template-columns:repeat(auto-fill,minmax(104px,1fr))}
  ul.sizerow b{font-size:13.5px}
  ul.sizerow small{font-size:9.5px}
}

/* Collapsible FAQ, native <details>, no script.
   Used only where the FAQ is supplementary to a full article. The marker is a
   drawn chevron rather than the browser default triangle, which differs on every
   platform and reads as an unstyled page. */
.faq.acc{border-top:1px solid var(--line);margin:14px 0 0}
.faq.acc details{border-bottom:1px solid var(--line)}
.faq.acc summary{
  list-style:none;cursor:pointer;position:relative;
  font:700 17px/1.4 var(--serif);color:var(--ink);
  padding:15px 34px 15px 0
}
.faq.acc summary::-webkit-details-marker{display:none}
/* Rotate about the centre, not a fixed offset: with a fixed `top` the open state
   drifted and read as a corner bracket rather than a chevron. */
.faq.acc summary::after{
  content:"";position:absolute;right:10px;top:50%;width:9px;height:9px;
  border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);
  transform:translateY(-70%) rotate(45deg);transform-origin:center;
  transition:transform .18s ease
}
.faq.acc details[open] summary::after{transform:translateY(-25%) rotate(-135deg)}
.faq.acc summary:hover{color:var(--accent)}
.faq.acc summary:focus-visible{outline:2px solid var(--amber);outline-offset:-2px}
.faq.acc details > div{padding:0 0 16px;color:var(--muted);max-width:70ch}
@media (prefers-reduced-motion:reduce){ .faq.acc summary::after{transition:none} }

/* cost calculator */
form.calc{border:1px solid var(--line);border-radius:6px;padding:16px 18px;margin:18px 0 22px;background:var(--soft)}
.calcgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px 16px}
.calcgrid label{display:flex;flex-direction:column;gap:5px;font-size:12px;text-transform:uppercase;
  letter-spacing:.06em;color:var(--muted);font-weight:600}
.calcgrid select,.calcgrid input{
  font:inherit;font-size:15px;text-transform:none;letter-spacing:0;color:var(--ink);
  padding:8px 9px;border:1px solid var(--line);border-radius:4px;background:#fff;width:100%
}
.calcout{display:block;margin-top:14px;padding-top:13px;border-top:2px solid var(--line)}
.calcout strong{font-size:27px;font-variant-numeric:tabular-nums;display:inline-block}
.calcout span{display:block;font-size:13px;color:var(--muted);margin-top:3px}

/* quote request block */
.quote{margin:34px 0 8px;padding:20px 22px;border:1px solid var(--line);border-radius:8px;background:var(--soft)}
.quote h2{margin-top:0}
.quote form.claim{max-width:none;margin-top:14px}
.quote textarea{resize:vertical}

/* Index Score badge in the listing table */
.iscore{
  display:inline-block;min-width:34px;text-align:center;padding:3px 7px;border-radius:4px;
  font:600 14px/1.25 var(--mono);font-variant-numeric:tabular-nums;
  background:#eef3f7;color:var(--navy);border:1px solid var(--line)
}

/* ---- listing rows: denser, logo-led, two actions ---------------------------
   The table was four lines of stacked text per company and fit four rows on a
   laptop screen. A directory is scanned, not read: the job is to compare eight
   companies without scrolling, which means the logo does the identifying and
   the numbers do the comparing. */
.proof{
  display:flex;flex-wrap:wrap;gap:6px 26px;margin:0 0 14px;padding:11px 14px;
  background:var(--soft);border:1px solid var(--line);border-radius:6px;
  font:14px/1.35 var(--sans);color:var(--muted)
}
.proof b{color:var(--ink);font-variant-numeric:tabular-nums;font-weight:700}

.corow{display:flex;align-items:center;gap:11px}
.corow .logo{width:40px;height:40px;flex:0 0 40px;object-fit:contain;border-radius:4px;background:#fff}
.corow .logo.mono{
  display:flex;align-items:center;justify-content:center;font:700 14px/1 var(--sans);
  color:#fff;background:var(--m,#24313f);border-radius:4px
}
.corow .logolink{display:block;flex:0 0 40px;line-height:0}
.cometa{min-width:0}
a.coname{display:block;font:600 15.5px/1.3 var(--sans);text-decoration:none;color:var(--accent)}
a.coname:hover{text-decoration:underline}
.coline{display:block;font:12.5px/1.4 var(--sans);color:var(--muted);margin-top:2px}
.coline .based{color:var(--good);font-weight:600}
.coline .sizes{color:var(--muted)}

table.listing td{padding:8px 10px 8px 0;vertical-align:middle}
.cell-co{width:44%}
/* side by side, not stacked — stacking them made the row taller than the
   four-line text block it was meant to replace */
.acts{display:flex;flex-direction:column;gap:4px;align-items:flex-end}
/* Website is secondary to the call. As a second bordered button it wrapped to
   its own line and made the row taller than the layout it replaced; as a plain
   link it costs almost no height and still reads as an action. */
.btn.tiny.ghost{
  background:none;border:0;padding:0;font:600 12.5px/1.3 var(--sans);
  color:var(--muted);text-decoration:underline;text-underline-offset:2px
}
.btn.tiny.ghost:hover{background:none;color:var(--accent)}

/* the score is the headline metric — make it read like one */
.iscore{
  min-width:40px;padding:5px 9px;font:700 16px/1.2 var(--mono);
  background:var(--navy);color:#fff;border:0
}
.from{font:700 17px/1.2 var(--mono);font-variant-numeric:tabular-nums}

@media (max-width:720px){
  .cell-co{width:auto}
  .corow .logo,.corow .logolink{width:32px;height:32px;flex-basis:32px}
  .proof{gap:4px 16px;font-size:13px}
}

/* ---- quote capture --------------------------------------------------------
   Five directories checked and every one opens with a single field: Dumpster-
   Comparison takes an email behind "Reveal Price", HometownDumpsterRental and
   Dumpsters.com take a ZIP, Thumbtack takes a ZIP, and Angi asks for nothing at
   all behind "Click to reveal". None of them ask for five things up front,
   which is what this form used to do. Phone rather than email because it is the
   field a hauler can act on. */
.quote .qlede{margin:0 0 14px;color:var(--muted)}
.qform{margin:0}
.qrow{display:flex;gap:10px;flex-wrap:wrap;align-items:stretch}
.qrow input[type=tel]{
  flex:1 1 260px;min-width:0;padding:13px 15px;font:17px/1.2 var(--sans);
  border:1px solid var(--line);border-radius:6px;background:#fff;color:var(--ink)
}
.qrow input[type=tel]:focus{outline:2px solid var(--accent);outline-offset:-1px}
.qrow button{
  flex:0 0 auto;background:var(--navy);color:#fff;border:0;padding:13px 26px;border-radius:6px;
  font:600 16px/1.2 var(--sans);cursor:pointer
}
.qrow button:hover{background:var(--accent)}
.qmore{margin-top:12px}
.qmore summary{
  cursor:pointer;font:600 13px/1.4 var(--sans);color:var(--muted);
  text-decoration:underline;text-underline-offset:2px;list-style:none
}
.qmore summary::-webkit-details-marker{display:none}
.qmore summary:hover{color:var(--accent)}
.qgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:11px 14px;margin-top:12px}
.qgrid label{display:flex;flex-direction:column;gap:5px;font:600 12px/1.3 var(--sans);
  text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.qgrid input,.qgrid select{
  font:15px/1.2 var(--sans);text-transform:none;letter-spacing:0;color:var(--ink);
  padding:9px 10px;border:1px solid var(--line);border-radius:5px;background:#fff;width:100%
}

/* the spread: the argument for the site, in one line, above the form */
.spread{
  margin:30px 0 0;padding:20px 22px 18px;border:1px solid var(--line);
  border-left:4px solid var(--amber);border-radius:6px;background:#fff
}
.spread-n{margin:0 0 6px;font:700 34px/1.05 var(--mono);font-variant-numeric:tabular-nums;color:var(--ink)}
.spread-n i{font:400 20px/1 var(--sans);font-style:normal;color:var(--muted);margin:0 6px}
.spread-t{margin:0;max-width:60ch;color:var(--muted)}
.spread-t b{color:var(--ink)}
.quote{margin-top:14px}
@media (max-width:620px){ .spread-n{font-size:27px} }

/* material disposal guides */
.verdict{display:flex;align-items:center;gap:14px;margin:18px 0 24px;padding:14px 18px;
  border-radius:6px;border:1px solid var(--line);background:var(--soft)}
.verdict .vlabel{font:600 12px/1.2 var(--sans);text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
.verdict .vval{font:700 21px/1.1 var(--sans)}
.verdict.good{border-left:4px solid var(--good)} .verdict.good .vval{color:var(--good)}
.verdict.warn{border-left:4px solid var(--amber-deep)} .verdict.warn .vval{color:var(--amber-deep)}
.verdict.bad{border-left:4px solid var(--warn)} .verdict.bad .vval{color:var(--warn)}
.mcta{margin:26px 0;padding:18px 20px;border:1px solid var(--line);border-left:4px solid var(--navy);
  border-radius:6px;background:#fff}
.mcta p{margin:0 0 12px}

/* ---- listing on a phone -----------------------------------------------------
   The five-column table did not overflow on a 375px screen, it squeezed: every
   cell wrapped until a single company row stood 355px tall. Eighteen of them is
   6,390px of scrolling to compare a town, which is no comparison at all.
   Below 620px each row becomes a card — identity on top, the three numbers in
   one strip, the call across the bottom. */
@media (max-width:620px){
  table.listing, table.listing tbody, table.listing tr, table.listing td{display:block;width:auto}
  table.listing thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  table.listing{border-collapse:separate;border-spacing:0}
  table.listing tr{
    border:1px solid var(--line);border-radius:8px;padding:11px 13px;margin-bottom:9px;background:#fff
  }
  table.listing tr:hover td{background:none}
  table.listing td{border:0;padding:0}

  .cell-co{margin-bottom:9px}
  .corow .logo,.corow .logolink{width:38px;height:38px;flex-basis:38px}
  a.coname{font-size:16px}

  /* score, price and rating share one strip instead of stacking */
  td[data-label="Score"],td[data-label="Price"],td[data-label="Google"]{
    display:inline-flex;align-items:baseline;gap:6px;margin:0 16px 8px 0
  }
  td[data-label="Score"]::before{content:"Score";font:600 10.5px/1 var(--sans);
    text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
  td[data-label="Price"]::before{content:"20 yd";font:600 10.5px/1 var(--sans);
    text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
  td[data-label="Google"]::before{content:"Google";font:600 10.5px/1 var(--sans);
    text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
  .iscore{min-width:0;padding:3px 8px;font-size:15px}
  .from{font-size:16px}
  .psize{margin-left:3px;color:var(--muted);font-size:12px}

  /* the call is the action, so it gets the full width */
  .cell-call .acts{flex-direction:row;align-items:center;justify-content:space-between;gap:10px}
  .cell-call .btn.tiny{flex:1;text-align:center;padding:11px 14px;font-size:15px}
  .cell-call .btn.tiny.ghost{flex:0 0 auto;padding:0}
}

/* town -> county up-link */
.countyup{margin:26px 0 0;padding:12px 15px;background:var(--soft);border-left:3px solid var(--line);
  border-radius:0 5px 5px 0;font-size:15px;color:var(--muted)}
.countyup a{font-weight:600}

/* ---- table that reads as a bar chart ---------------------------------------
   Markup stays a table so every figure is still extractable — the AI-retrieval
   research is consistent that tables and lists get lifted before prose — and
   the bar is drawn behind the value in CSS. No script, no canvas, no image. */
table.bars{width:100%;border-collapse:collapse;margin:14px 0 20px;font-size:15px}
table.bars caption{
  text-align:left;font:600 12px/1.3 var(--sans);text-transform:uppercase;
  letter-spacing:.06em;color:var(--muted);padding-bottom:8px
}
table.bars th[scope=col]{
  text-align:left;font:600 11px/1.2 var(--sans);text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);border-bottom:1px solid var(--line);padding:0 10px 6px 0
}
table.bars th[scope=row]{
  text-align:left;font:400 15px/1.35 var(--sans);padding:7px 12px 7px 0;
  white-space:nowrap;vertical-align:middle
}
table.bars td{padding:7px 10px 7px 0;vertical-align:middle}
table.bars .barcell{position:relative;width:100%;min-width:120px}
table.bars .bar{
  display:block;height:22px;width:var(--w);border-radius:3px;
  background:linear-gradient(90deg,var(--accent),#4b93c4);opacity:.22
}
table.bars .barcell b{
  position:absolute;left:9px;top:50%;transform:translateY(-50%);
  font:650 14px/1 var(--mono);font-variant-numeric:tabular-nums;color:var(--ink)
}
table.bars td.muted{white-space:nowrap;font-size:13px}
table.bars tr:hover .bar{opacity:.34}
@media (max-width:620px){
  table.bars th[scope=row]{max-width:38vw;white-space:normal}
  table.bars .barcell b{font-size:13px}
}

/* Container row, enlarged where the drawings are the point of the page.
   scale() does not affect layout, so the boxes grew into each other and three
   containers read as one continuous shape. The gap has to cover the overflow
   the transform creates, not the untransformed width. */
.sizerow.big{gap:52px;margin:22px 0 30px;flex-wrap:wrap}
.sizerow.big .cbox{transform:scale(1.3);transform-origin:bottom center;margin-bottom:12px}
@media (max-width:620px){ .sizerow.big{gap:34px} .sizerow.big .cbox{transform:scale(1.1)} }

/* ---- price-by-size range bars ----------------------------------------------
   The bar spans p25 to p75 rather than reaching from zero, with the median
   ticked inside it. For a dumpster price the spread IS the finding — $350 to
   $485 around a $410 median tells you something a bar ending at $410 cannot. */
table.ranges{width:100%;border-collapse:collapse;margin:14px 0 20px;font-size:15px}
table.ranges th[scope=col]{
  text-align:left;font:600 11px/1.2 var(--sans);text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);border-bottom:1px solid var(--line);padding:0 12px 6px 0
}
table.ranges th[scope=row]{
  text-align:left;font:650 15px/1.3 var(--sans);white-space:nowrap;padding:9px 14px 9px 0
}
table.ranges td{padding:9px 12px 9px 0;vertical-align:middle}
table.ranges .rangecell{width:60%;min-width:150px}
.rtrack{position:relative;display:block;height:20px;background:var(--soft);
  border-radius:3px;overflow:hidden}
.rspan{position:absolute;top:0;bottom:0;left:var(--a);width:calc(var(--b) - var(--a));
  background:linear-gradient(90deg,#8fbcd8,var(--accent));opacity:.45;border-radius:3px}
.rmid{position:absolute;top:-2px;bottom:-2px;left:var(--m);width:2px;background:var(--navy)}
.rlab{display:block;margin-top:3px;font:400 12px/1.2 var(--mono);color:var(--muted)}
table.ranges .pcell{font:650 16px/1 var(--mono);font-variant-numeric:tabular-nums;white-space:nowrap}
table.ranges td.muted{white-space:nowrap;font-size:13px}
@media (max-width:620px){
  table.ranges th[scope=row]{padding-right:8px}
  table.ranges .rangecell{width:auto}
  table.ranges td.muted{display:none}
}

/* ============================================================================
   MONEY PAGES — index, sizes, calculator, fees.
   Same spec as the rest of the site: no new hues, the tint is the only depth
   technique, borders last. The one real investment is the scaled roll-off
   drawing and the price range chart.
   ============================================================================ */
.mhero .hero-in,.mhero{max-width:var(--wrap)}
.mhero .msplit{display:grid;grid-template-columns:minmax(0,1.45fr) minmax(0,1fr);
  gap:34px;align-items:center}
.mhero h1{font-size:clamp(36px,5.2vw,54px);line-height:1.04;margin:.1em 0 .3em}
.mhero .lede{max-width:34em;font-size:var(--fs-lead,20px);color:var(--steel,#24313f)}
/* Stacked and left-aligned on purpose: the drawings are scaled to volume, so five
   of them in a column read as a chart of the size range rather than as clip art.
   Height-capped so the stack does not tower over the headline beside it. */
@media(max-width:860px){
  .mhero .msplit{grid-template-columns:1fr;gap:18px}
  }

/* Figures without a box. */
.mstat{display:flex;flex-wrap:wrap;gap:0 44px;margin:26px 0 0;padding:0;border:0}
.mstat div{padding:0 0 2px}
.mstat b{display:block;font:700 clamp(24px,3vw,31px)/1 var(--serif);color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.mstat span{display:block;margin-top:7px;font:600 12px/1.3 var(--sans);
  color:var(--muted);text-transform:uppercase;letter-spacing:.07em}
.mstat div::after{content:"";display:block;width:26px;height:3px;margin-top:10px;
  background:var(--accent);opacity:.55}

/* Price range chart: every size on one dollar axis, drawn from the measured
   quartiles rather than a made-up range. The bar is the middle half of what
   companies actually publish; the tick is the median. */
.rchart{margin:22px 0 8px}
.rchart .rrow{display:grid;grid-template-columns:150px minmax(0,1fr);gap:16px;
  align-items:center;padding:10px 0;border-top:1px solid var(--line)}
.rchart .rrow:first-of-type{border-top:0}
.rchart .rname{display:flex;align-items:center;gap:9px;min-width:0;
  text-decoration:none;color:var(--ink)}
.rchart .rname svg.sart{flex:0 0 46px;width:46px;height:38px;color:var(--navy);opacity:.8}
.rchart .rname b{font:600 14px/1.25 var(--sans);letter-spacing:-.005em}
.rchart .rname:hover b{color:var(--accent)}
.rchart .rgtrack{position:relative;height:34px;background:var(--soft);border-radius:var(--r)}
.rchart .rbar{position:absolute;top:9px;height:16px;border-radius:var(--r);
  background:var(--navy)}
.rchart .rmed{position:absolute;top:5px;height:24px;width:2px;background:var(--accent)}
.rchart .rglab{position:absolute;top:8px;font:600 14px/17px var(--sans);
  color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums}
.rchart .raxis{position:relative;height:22px;margin-left:166px;border-top:1px solid var(--line)}
.rchart .raxis i{position:absolute;top:5px;transform:translateX(-50%);
  font:12px/1 var(--sans);color:var(--muted);font-style:normal;
  font-variant-numeric:tabular-nums}
@media(max-width:700px){
  .rchart .rrow{grid-template-columns:1fr;gap:4px;padding:13px 0}
  .rchart .raxis{margin-left:0}
}

/* Size cards: the drawing identifies the size before the price does. */
.ucards{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:0;
  margin:22px 0 6px;border-top:1px solid var(--line);border-left:1px solid var(--line)}
.ucard{display:flex;flex-direction:column;padding:20px 16px 18px;background:var(--bg);
  text-decoration:none;color:inherit;transition:background .13s ease;
  border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
.ucard:hover{background:var(--soft)}
.ucard:active{transform:scale(.995)}
/* Height-bound, same as the job grid. Sizing by width made every drawing render
   139px tall inside a 64px box, so all five overflowed their container; the
   scale difference lives in the viewBox and survives either way. */
.ucard .uc-art{color:var(--accent);height:72px;margin:0 0 10px;display:flex;
  align-items:flex-end;justify-content:flex-start;overflow:hidden}
.ucard .uc-art svg.sart{height:100%;width:auto;opacity:1;stroke-width:2.4}
.ucard h3{font:700 20px/1.2 var(--serif);color:var(--ink);margin:0;letter-spacing:-.015em}
.ucard .uc-wk{margin:11px 0 0;font:700 26px/1 var(--serif);color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.ucard .uc-per{margin:6px 0 0;font:600 12px/1.3 var(--sans);color:var(--muted);
  text-transform:uppercase;letter-spacing:.07em}
.ucard .uc-mo{margin:10px 0 0;font:14px/1.4 var(--sans);color:var(--steel,#24313f);
  font-variant-numeric:tabular-nums}
.ucard .uc-who{margin:8px 0 0;font:14px/1.45 var(--sans);color:var(--muted)}
@media(max-width:900px){.ucards{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:560px){.ucards{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* Claim prompts. Same offer as the porta potty site: the outbound link is real. */
.claimcta{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:28px;align-items:center;
  margin:34px 0;padding:26px 28px;background:var(--soft);border-radius:var(--r)}
.claimcta .cc-eyebrow{margin:0;font:600 12px/1.3 var(--sans);color:var(--accent);
  text-transform:uppercase;letter-spacing:.09em}
.claimcta h2{margin:.25em 0 .3em;font:700 25px/1.18 var(--serif);color:var(--ink);
  letter-spacing:-.015em}
.claimcta .cc-lede{margin:0;font:16px/1.55 var(--sans);color:var(--steel,#24313f);max-width:52ch}
.claimcta .cc-missing{margin:15px 0 7px;font:600 12px/1.3 var(--sans);color:var(--muted);
  text-transform:uppercase;letter-spacing:.07em}
.claimcta .cc-gaps{list-style:none;display:flex;flex-wrap:wrap;gap:7px;margin:0;padding:0}
.claimcta .cc-gaps li{padding:5px 11px;border-radius:999px;background:var(--bg);
  font:600 14px/1.3 var(--sans);color:var(--steel,#24313f)}
.claimcta .cc-act{margin:19px 0 0}
.claimcta .cc-act .btn{min-height:50px;display:inline-flex;align-items:center;padding:0 26px}
.claimcta .cc-fine{margin:11px 0 0;font:14px/1.45 var(--sans);color:var(--muted)}
.claimcta .cc-score{display:flex;flex-direction:column;align-items:center;gap:8px;
  width:118px;flex:0 0 118px}
.claimcta .cc-score svg{width:100%;height:auto;transform:rotate(-90deg)}
.claimcta .cc-ring-bg{fill:none;stroke:var(--line);stroke-width:8}
.claimcta .cc-ring{fill:none;stroke:var(--accent);stroke-width:8;stroke-linecap:round}
.claimcta .cc-score text{fill:var(--ink);font:700 20px/1 var(--serif);
  font-variant-numeric:tabular-nums;transform:rotate(90deg);transform-origin:44px 44px}
.claimcta .cc-score span{font:600 12px/1.3 var(--sans);color:var(--muted);
  text-transform:uppercase;letter-spacing:.07em}
@media(max-width:720px){
  .claimcta{grid-template-columns:1fr;gap:18px;padding:22px 20px}
  .claimcta .cc-score{flex-direction:row;width:auto;flex:none;order:-1}
  .claimcta .cc-score svg{width:74px}
}
.claimband{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:center;
  margin:30px 0;padding:22px 24px;background:var(--soft);border-radius:var(--r)}
.claimband .cb-eyebrow{margin:0;font:600 12px/1.3 var(--sans);color:var(--accent);
  text-transform:uppercase;letter-spacing:.09em}
.claimband h2{margin:.25em 0 .3em;font:700 25px/1.18 var(--serif);color:var(--ink);
  letter-spacing:-.015em}
.claimband p{margin:0;font:16px/1.55 var(--sans);color:var(--steel,#24313f);max-width:56ch}
.claimband .cb-act{margin:0}
.claimband .cb-act .btn{min-height:50px;display:inline-flex;align-items:center;
  padding:0 24px;white-space:nowrap}
@media(max-width:720px){
  .claimband{grid-template-columns:1fr;gap:16px;padding:20px}
  .claimband .cb-act .btn{width:100%;justify-content:center}
}

/* Tile grids and search, ported from the porta potty build. Rules sit on the
   tiles, never on the container: a tinted container with gaps paints every empty
   cell in the last row as a grey block. */
.citytiles,.statetiles,.tsresults{list-style:none;margin:18px 0 0;padding:0;
  display:grid;gap:0;grid-template-columns:repeat(4,minmax(0,1fr));
  border-top:1px solid var(--line);border-left:1px solid var(--line)}
.citytiles a,.statetiles a,.tsresults a{display:block;padding:15px 16px 13px;
  background:var(--bg);text-decoration:none;color:var(--ink);transition:background .13s ease;
  border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
.citytiles a:hover,.statetiles a:hover,.tsresults a:hover,
.citytiles a:focus-visible,.statetiles a:focus-visible,.tsresults a:focus-visible{background:var(--soft)}
.citytiles b,.statetiles b,.tsresults b{display:block;font:700 20px/1.2 var(--serif);
  letter-spacing:-.015em}
.citytiles span,.tsresults span{display:block;margin-top:3px;font:12px/1.3 var(--sans);
  color:var(--muted)}
.citytiles i,.tsresults i{display:block;margin-top:9px;font:600 14px/1.3 var(--sans);
  font-style:normal;color:var(--accent);font-variant-numeric:tabular-nums}
.statetiles span{display:flex;gap:14px;margin-top:8px;font:14px/1.3 var(--sans);
  color:var(--muted);font-variant-numeric:tabular-nums}
.statetiles span b{display:inline;font:700 14px/1.3 var(--sans);color:var(--ink)}
@media(max-width:980px){.citytiles,.statetiles,.tsresults{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:700px){.citytiles,.statetiles,.tsresults{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:420px){.citytiles,.statetiles,.tsresults{grid-template-columns:1fr}}
.tilesearch{margin:16px 0 0;max-width:420px}
.tilesearch input{width:100%;padding:11px 13px;border:1px solid var(--line);
  border-radius:var(--r);font:16px/1.2 var(--sans);background:var(--bg);color:var(--ink)}
.tilesearch input:focus-visible{outline:2px solid var(--accent);outline-offset:1px;
  border-color:var(--accent)}
.ts-none{margin:14px 0 0;font:14px/1.4 var(--sans);color:var(--muted)}

/* Job-type entry grid. The recommended size is drawn to scale on each card, so
   the grid answers "which size" while it routes the click. */
.jobs{list-style:none;margin:18px 0 0;padding:0;display:grid;gap:0;
  grid-template-columns:repeat(4,minmax(0,1fr));
  border-top:1px solid var(--line);border-left:1px solid var(--line)}
.jobs a{display:flex;flex-direction:column;height:100%;padding:18px 16px 16px;
  background:var(--bg);text-decoration:none;color:var(--ink);transition:background .13s ease;
  border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
.jobs a:hover,.jobs a:focus-visible{background:var(--soft)}
.jobs a:active{transform:scale(.995)}
/* Height-bound, not width-bound. Every drawing shares one 120x100 viewBox, so
   sizing by width makes them all the same rendered height and overflow the card;
   sizing by height keeps them inside it and the scale difference stays visible
   because it lives inside the viewBox. */
.jobs .jb-art{color:var(--accent);height:66px;margin:0 0 10px;display:flex;align-items:flex-end;
  overflow:hidden}
.jobs .jb-art svg.sart{height:100%;width:auto;opacity:1;stroke-width:2.6}
.jobs .jb-name{font:700 18px/1.25 var(--serif);letter-spacing:-.015em}
.jobs .jb-size{margin-top:7px;font:600 14px/1.3 var(--sans);color:var(--accent);
  font-variant-numeric:tabular-nums}
.jobs .jb-tons{margin-top:7px;font:14px/1.45 var(--sans);color:var(--muted)}
@media(max-width:900px){.jobs{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:480px){.jobs{grid-template-columns:1fr}}

/* Numbered explainer lists: the number carries the sequence, so no card needed. */
ol.movers{margin:16px 0 0;padding:0 0 0 1.35em;display:grid;gap:14px}
ol.movers li{font:16px/1.6 var(--sans);color:var(--steel,#24313f);padding-left:.25em}
ol.movers li b{color:var(--ink);font-weight:700}
ol.movers li::marker{color:var(--accent);font-weight:700;font-variant-numeric:tabular-nums}

/* Town suggestions under the hero search. */
.zipsug{list-style:none;margin:8px 0 0;padding:0;max-width:430px;
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--bg)}
.zipsug li + li{border-top:1px solid var(--line)}
.zipsug a{display:flex;align-items:baseline;gap:6px;padding:9px 12px;text-decoration:none;
  color:var(--ink);font:14px/1.35 var(--sans)}
.zipsug a:hover,.zipsug a:focus-visible{background:var(--soft)}
.zipsug b{font-weight:700}
.zipsug i{margin-left:auto;font-style:normal;color:var(--muted);
  font-variant-numeric:tabular-nums;font-size:12px}

/* Hero wallpaper. Written to work with both hero shapes on this site: the
   homepage puts its content as direct children, the money pages wrap theirs in
   .hero-in. Anything that is not the pattern gets lifted above it. */
/* A ground for the wallpaper to sit on. Without it the motifs float on white and
   read as smudges rather than as a designed hero; same treatment as the porta
   potty site, in this site's blue rather than its green. */
/* Dark hero. A warm-paper page with no dark anchor sits in one narrow value band
   and reads beige; the value jump is what makes it feel deliberate. Figures land
   in paper-white where they read as the product rather than as caption. */
.hero{position:relative;overflow:hidden;
  background:linear-gradient(180deg,#0e2438 0%,#0c1f30 62%,#0a1b2a 100%);
  border-bottom:1px solid #081726}
.hero > *:not(.heropat){position:relative;z-index:1}
.hero .heropat{
  position:absolute;inset:0;width:100%;height:100%;
  opacity:.12;z-index:0;pointer-events:none;
}
/* Secondary text sits directly over the wallpaper, and this site's --muted is
   lighter than the porta potty site's, so at the default it measured 3.85:1
   against the darkest point a motif can make. Darkened just for the hero. */
.hero .lede,.hero .statbar span,.hero .mstat span,.hero .ziplook label{color:#31404e}

/* Grid tiles: the <li> stretches to the row height but a display:block anchor
   only takes its content height, so the borders never lined up across a row. */
.citytiles li,.statetiles li,.tsresults li,.jobs li,.guidecards li{display:flex}
/* min-width:0 or the anchor cannot shrink below its own min-content width and
   overflows the grid cell. On the state tiles that meant every card sat about
   6px into the one beside it: Alabama's card ended at x=397 while Alaska's began
   at 391, so two cells of a deliberately gapless lattice were overlapping.
   The inner stat row wraps for the same reason. */
.citytiles a,.statetiles a,.tsresults a,.jobs a,.guidecards a{flex:1;min-width:0}
.statetiles span,.citytiles span{flex-wrap:wrap}

/* Prose columns must not inherit the numeric mono. table.ptable applies it to
   every cell after the first, which turned "2.5 to 5 tons for a typical 20 to 30
   square roof" into terminal output. */
/* .idx right-aligns every cell after the first, which is correct for figures and
   wrong for a sentence. Specificity has to beat table.ptable.idx td:not(:first-child). */
table.ptable td.prose,table.ptable.idx td.prose{
  font-family:var(--sans);font-variant-numeric:normal;letter-spacing:normal;
  text-align:left;color:var(--steel);
}
table.ptable.idx th:nth-child(3),table.ptable th:nth-child(3){text-align:left}

/* Guides: cards, not a column of underlined links with clipped descriptions. */
.guidecards{list-style:none;margin:22px 0 0;padding:0;display:grid;gap:0;
  grid-template-columns:repeat(2,minmax(0,1fr));
  border-top:1px solid var(--line);border-left:1px solid var(--line)}
.guidecards a{display:block;padding:18px 20px 16px;background:var(--bg);
  text-decoration:none;color:var(--ink);transition:background .13s ease;
  border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
.guidecards a:hover,.guidecards a:focus-visible{background:var(--soft)}
.guidecards b{display:block;font:700 var(--fs-lead,19px)/1.3 var(--serif);
  letter-spacing:-.015em;color:var(--ink)}
.guidecards span{display:block;margin-top:7px;font:15px/1.5 var(--sans);color:var(--muted)}
@media(max-width:700px){.guidecards{grid-template-columns:1fr}}

/* Glossary: a definition grid. Forty terms as a flat dt/dd wall is unscannable
   and gives the eye nowhere to stop. */
.glosscards{display:grid;gap:0;grid-template-columns:repeat(2,minmax(0,1fr));
  margin:22px 0 0;border-top:1px solid var(--line);border-left:1px solid var(--line)}
.glosscards article{padding:18px 20px 16px;background:var(--bg);
  border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
.glosscards h2{margin:0;font:700 17px/1.3 var(--serif);letter-spacing:-.01em;color:var(--ink)}
.glosscards p{margin:7px 0 0;font:15px/1.55 var(--sans);color:var(--steel)}
@media(max-width:700px){.glosscards{grid-template-columns:1fr}}

.hero .heropat{opacity:.07}
.hero h1{color:#faf8f4}
.hero .lede,.hero .mstat span,.hero .statbar span,.hero .crumbs,.hero .crumbs a,
.hero .ziplook label{color:#c2ccd6}
.hero .crumbs a:hover{color:#faf8f4}
.hero .lede strong{color:#faf8f4}
.hero .mstat b,.hero .statbar b{color:#faf8f4}
.hero .mstat div::after{background:#d08a5c;opacity:1}
/* Copper is mixed for light grounds; the lead figure needs a lighter cut here. */
.hero .statbar div:first-child b,.hero .mstat div:first-child b{color:#d08a5c}
.hero .statbar{background:rgba(250,248,244,.06);border-color:rgba(250,248,244,.14)}
.hero .statbar div{background:transparent;border-color:rgba(250,248,244,.14)}
.hero .mstat{border:0;background:none}

/* One filled action per viewport. Copper would read as a second decorative note
   against the stat rules, so the primary CTA is paper. */
.hero .btn{background:#faf8f4;color:#0e2438;border-color:#faf8f4}
.hero .btn:hover{background:#fff;border-color:#fff}
.hero .btn.ghost{background:transparent;color:#faf8f4;border-color:rgba(250,248,244,.42)}
.hero .btn.ghost:hover{background:rgba(250,248,244,.10);border-color:#faf8f4}

.hero input[type=text],.hero input[type=search],.hero .tilesearch input,.hero .ziprow input{
  background:rgba(250,248,244,.08);border-color:rgba(250,248,244,.24);color:#faf8f4}
.hero input::placeholder{color:rgba(250,248,244,.55)}
.hero input:focus-visible{outline-color:#d08a5c;border-color:#d08a5c}
.hero .ziprow button{background:#faf8f4;color:#0e2438;border-color:#faf8f4}
.hero .zipsug{background:var(--bg);border-color:var(--line)}
.hero .stamp{color:#c2ccd6;border-left-color:#d08a5c}

/* Wallpaper theming. The motifs draw in currentColor, so the pattern inverts for
   whatever ground it sits on instead of being hardcoded to one palette. This is
   what broke before: the repalette mapped the dumpster's fill to the same navy
   as the hero, and it went invisible with nothing to show it had. */
.heropat{color:var(--navy)}
.heropat{--pat-fill:var(--bg);--pat-soft:var(--line);--pat-cut:var(--bg)}
.hero .heropat{
  color:#faf8f4;
  --pat-fill:#0e2438;--pat-soft:rgba(250,248,244,.55);--pat-cut:#0e2438;
  opacity:.085;
}

/* Full-bleed hero. Inset, it reads as a card dropped on the page; edge to edge it
   reads as a band of the page itself, which is the difference between a component
   and a designed layout. The inner content keeps the wrap so nothing else moves. */
.hero{
  margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);
  padding-left:calc(50vw - 50%);padding-right:calc(50vw - 50%);
  max-width:100vw;
}

/* The claim panels are the one thing on these pages we want an operator to click,
   and on --soft they read as another content block. A committed dark ground makes
   them the only inverted element on the page, and the button the highest-contrast
   thing on it. All of this is measured: cream on navy is 12.7:1 here, the amber
   eyebrow 8.2:1, body cream at 85% 9.6:1, and the button 12.7:1 the other way.
   An amber button was the obvious idea and it fails AA at 4.1:1, so the button is
   cream. */
.claimcta,.claimband{background:var(--navy);border:0;position:relative;overflow:hidden}
.claimcta .cc-eyebrow,.claimband .cb-eyebrow{color:var(--accent-light)}
.claimcta h2,.claimband h2{color:var(--oncolor)}
.claimcta .cc-lede,.claimband p{color:var(--oncolor-dim)}
.claimcta .cc-fine{color:rgba(255,255,255,.72)}
.claimcta .cc-missing{color:rgba(255,255,255,.72)}
.claimcta .cc-gaps li{background:rgba(255,255,255,.12);color:var(--oncolor)}
.claimcta .cc-act .btn,.claimband .cb-act .btn{background:var(--oncolor);color:var(--navy);
  border-color:var(--oncolor);font-weight:700}
.claimcta .cc-act .btn:hover,.claimband .cb-act .btn:hover{background:#fff;border-color:#fff}
.claimcta .cc-act .btn:active,.claimband .cb-act .btn:active{transform:scale(.97)}
.claimcta .cc-ring-bg{stroke:rgba(255,255,255,.22)}
.claimcta .cc-ring{stroke:var(--accent-light)}
.claimcta .cc-score text{fill:var(--oncolor)}
.claimcta .cc-score span{color:rgba(255,255,255,.72)}

/* Floating quote pill, phones only. The form is the conversion point and on
   mobile it sits far below the table; this is the way down to it. A pill in
   the corner, never a full-width bar. */
.qpill{display:none}
@media (max-width:820px){
  .qpill{display:inline-flex;position:fixed;right:14px;bottom:calc(14px + env(safe-area-inset-bottom));
    z-index:60;background:var(--navy);color:#fff;text-decoration:none;font-weight:700;
    font-size:var(--fs-sm);padding:14px 22px;border-radius:999px;
    box-shadow:0 4px 14px rgba(0,0,0,.25)}
  .qpill:active{transform:scale(.97)}
}

/* Before/after row on the claim page. Real listing classes, so the preview is
   the thing itself rather than a drawing of it. */
.claim-preview{border:1px solid var(--line);border-radius:8px;padding:16px 18px;margin:14px 0 26px;
  background:var(--soft)}
.claim-preview .cp-label{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.07em;
  color:var(--muted);font-weight:700;margin:10px 0 4px}
.claim-preview .cp-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0;
  padding:10px 12px;background:#fff;border-radius:6px}
.claim-preview .coname{font-weight:700}

/* Keyboard skip link: invisible until focused, then a plain visible button. */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--navy);color:#fff;
  padding:10px 18px;border-radius:0 0 6px 0;text-decoration:none;font-weight:700}
.skip:focus{left:0}

/* Per-company service-area map: a range instrument in the site's own palette.
   Banded rings, crosshair, north tick; every dot is a link. */
.amap{margin:20px auto;max-width:380px}
.amap svg{width:100%;height:auto;display:block}
.am-water{fill:#dde8ec}
.am-land{fill:#fdfcf9;stroke:#d8d2c6;stroke-width:1}
.am-guide{fill:none;stroke:var(--muted);stroke-opacity:.18;stroke-width:1}
.am-rim{fill:none;stroke:var(--muted);stroke-opacity:.55;stroke-width:1.5;stroke-dasharray:6 5}
.am-road{fill:none;stroke:var(--muted);stroke-linecap:round;stroke-linejoin:round}
.am-road.i{stroke-width:2.2;stroke-opacity:.4}
.am-road.u{stroke-width:1.3;stroke-opacity:.28}
.am-north{font-size:11px;font-weight:700;fill:var(--muted);text-anchor:middle;letter-spacing:.05em}
.am-rlab{font-size:10.5px;fill:var(--muted);paint-order:stroke;stroke:#fff;stroke-width:3px;stroke-linejoin:round}
.am-spoke{stroke:var(--muted);stroke-opacity:.28;stroke-width:1}
.am-dot{fill:var(--steel);stroke:#fff;stroke-width:1.8}
.am-dot.home{fill:var(--accent);stroke:#fff;stroke-width:2}
.amap a:hover .am-dot{fill:var(--accent)}
.am-lab{font-size:12.5px;font-weight:600;fill:var(--ink);paint-order:stroke;stroke:#fff;stroke-width:3.5px;stroke-linejoin:round}
.am-yard{fill:var(--warn,#b3541e);stroke:#fff;stroke-width:1.8}
.am-ylab{font-size:11px;fill:var(--muted)}

/* The operator entry reads as an offer, not another section. */
.hnav .hnav-op{display:inline-flex;align-items:center;line-height:1;border:1px solid var(--line);border-radius:999px;padding:7px 13px}
.hnav .hnav-op:hover{border-color:var(--accent);color:var(--accent)}

/* Badge embed offer. The textarea selects itself on click. */
.badgeoffer .badge-preview{margin:10px 0}
.embedcode{width:100%;font:12px/1.5 ui-monospace,Menlo,monospace;color:var(--ink);
  background:var(--soft);border:1px solid var(--line);border-radius:6px;padding:10px 12px;
  resize:vertical}

.cb-badge{display:block;margin-top:12px;border-radius:8px}

.cell-call .btn.tiny{font-variant-numeric:tabular-nums}

/* Index Score breakdown: was rendering as cramped text columns. */
table.scorebreak{width:100%;border-collapse:collapse;margin:14px 0}
table.scorebreak caption{font-size:var(--fs-sm);color:var(--muted);text-align:left;margin-bottom:6px}
table.scorebreak th{text-align:left;font-size:var(--fs-micro);text-transform:uppercase;
  letter-spacing:.06em;color:var(--muted);padding:6px 14px 6px 0;border-bottom:1px solid var(--line)}
table.scorebreak td{padding:10px 14px 10px 0;border-bottom:1px solid var(--line);vertical-align:top}
table.scorebreak td:nth-child(2){white-space:nowrap}
table.scorebreak tr:last-child td{border-bottom:0}
@media (max-width:620px){
  /* four columns cannot breathe on a phone: component and points share the top
     line, the finding and the next step run full width beneath */
  table.scorebreak thead{display:none}
  table.scorebreak caption{display:block;width:100%}
  table.scorebreak,table.scorebreak tbody{display:block}
  table.scorebreak tr{display:grid;grid-template-columns:1fr auto;gap:2px 12px;
    padding:10px 0;border-bottom:1px solid var(--line)}
  table.scorebreak td{display:block;padding:0;border:0}
  table.scorebreak td:first-child{font-weight:700}
  table.scorebreak td:nth-child(3){grid-column:1 / -1}
  table.scorebreak td:nth-child(4){grid-column:1 / -1;color:var(--muted);font-size:var(--fs-sm)}
  table.scorebreak tr:last-child{border-bottom:0}
}

/* the vs-peers highlighted row breathed against the accent bar */
tr.self td{padding-top:12px;padding-bottom:12px}
tr.self td:first-child{padding-left:12px}
.gmap iframe{width:100%;height:320px;border:0;border-radius:10px;display:block}
/* Cross-link to the sister directory. Deliberately quiet: it is a useful next
   step for the minority of visitors who need both, not a promotion. */
.sister{margin:18px 0 0;padding:12px 14px;border-left:3px solid var(--line);
  background:var(--soft);font-size:15px;line-height:1.55}

/* ------------------------------------------------------------------ mobile
   Measured on a phone-width viewport rather than assumed.

   The sort and filter chips came out 35px tall. That is fine for a mouse and
   short of the 44px a thumb wants, and these are the controls the whole page
   turns on: somebody standing in a driveway deciding which of sixty companies
   to ring. The "only with a published price" checkbox was 13px, which is a
   miss waiting to happen.

   Header nav links get nowrap for the same reason the footer ones did: at
   phone width "What size?" was breaking after "What" and reading as two
   separate links. */
@media (max-width: 700px) {
  .hnav a { white-space: nowrap; }
  .tctl button { min-height: 44px; padding: 10px 14px; }
  .tctl-f { min-height: 44px; padding: 0 4px; gap: 10px; }
  .tctl-f input { width: 20px; height: 20px; }
  .tctl { gap: 10px; }
  /* The count stops being pushed to the far right on its own orphan row and
     sits under the chips where it reads as a result of them. */
  .tctl-n { margin-left: 0; width: 100%; }
}

/* Control groups. On desktop they are transparent: the chips lay out exactly as
   they did when they were flat children of .tctl. */
.tctl-g{display:contents}

@media (max-width: 700px) {
  /* Measured on a phone: the fourteen controls here wrapped into eight rows and
     stood 295px tall, taller than the headline and the intro put together, and
     the table they filter did not begin until 1,047px down the page. Somebody
     looking for a dumpster should not have to scroll past the controls twice
     before they see a single company.

     Each group becomes one row you swipe instead of a block that wraps. Nothing
     is hidden and nothing shrinks below the 44px a thumb needs; the row simply
     runs off the edge the way a phone user expects a chip rail to. */
  .tctl-g{display:flex;flex-wrap:nowrap;align-items:center;gap:10px;
    overflow-x:auto;-webkit-overflow-scrolling:touch;
    scrollbar-width:none;padding-bottom:2px;max-width:100%}
  .tctl-g::-webkit-scrollbar{display:none}
  .tctl-g > *{flex:0 0 auto}
  .tctl{flex-direction:column;align-items:stretch;gap:8px}
  .tctl-l{padding-right:2px}
}

@media (max-width: 700px) {
  /* The hero intro ran to six lines at 18.5px and the H2 under it to three at
     25px, which is a screen and a half of preamble on a page whose whole job is
     the list underneath. Both come down a step. This is not shrinking the type
     to win a measurement: at 16.5px the intro is still the largest body text on
     the page and still reads first. */
  .hero .lede{font-size:16.5px;line-height:1.5}
  main > h2{font-size:21px;line-height:1.25}
}
