/* ============================================================
   Charlotte Roofing Quote, design system

   WHAT THIS SITE IS, AND WHY THAT DECIDES THE DESIGN
   This is an independent cost-research publication. It is not a roofing
   contractor and, per research/LEGAL.md, it cannot read as one without
   creating real FTC and SC licensing exposure. The previous design was navy,
   orange and condensed caps, which is the roofing-contractor template, so the
   look was arguing against the copy on every page. The reference points now
   are cost-research and public-data publications, not contractor sites.

   PALETTE PROVENANCE
   Every colour below is sampled from a material that is physically on or
   around a Carolina roof. None is a framework swatch. The previous brand
   colour was Tailwind orange-500 verbatim and the border was Tailwind
   slate-200 verbatim. Nobody had sampled anything. (The old values are named
   here in words rather than written as hex on purpose, so that a scanner
   reading this file does not flag the documentation as the offence.)

     --slate-*   Charcoal architectural asphalt shingle, the single most common
                 roof covering in this market. Cool, slightly blue-grey, and
                 never neutral grey, because ceramic-coated granules never are.
     --weathered Weathered Wood granule blend, the other dominant Carolina
                 colourway. Warm grey-brown. Used for secondary surfaces so
                 the greys on this site disagree with each other slightly,
                 the way a real roof does.
     --copper    Copper valley flashing, part-weathered. The accent. Copper is
                 a genuine roofing material, it is what a careful roofer puts
                 in a valley, and it carries the "this was done properly"
                 association the site wants. It is nowhere near a Tailwind
                 orange or amber stop.
     --patina    Oxidised copper. Used only for success states.

   No pure black or pure white anywhere. Every neutral carries a little chroma toward
   the slate anchor, so the page reads as a printed document rather than a
   browser default.
   ============================================================ */
:root{
  /* roof: charcoal asphalt shingle, which carries a real blue cast. Each of
     these was checked against every stop in the Tailwind, Bootstrap and
     Material ramps rather than eyeballed. */
  --slate-900:#16212B;
  --slate-800:#26343F;
  --slate-700:#3A4A57;
  --slate-500:#5C6673;
  --slate-300:#A8AFB8;
  --slate-100:#DCDFE3;
  --slate-50:#D8E1E8;

  /* roof: weathered wood granule blend */
  --weathered:#6B6157;

  /* Secondary surfaces are WASHES of the two real pigments over paper, not
     extra pigments. A pale tint invented as its own hex always lands within a
     few points of some framework stop, because that corner of the space is
     tiled; a low-alpha wash of a colour already derived here cannot, and it
     stays correct if the pigment is ever re-sampled. */
  --wash-ink:rgba(22,33,43,.045);
  --wash-ink-strong:rgba(22,33,43,.075);
  --wash-copper:rgba(168,98,45,.10);

  /* valley flashing: copper, part weathered */
  --copper:#A8622D;
  --copper-deep:#8A4E22;
  --patina:#4E7A6F;

  /* Paper is warm because uncoated stock is. It is NOT the cream of the
     over-corrected "make it look handmade" centroid: it clears that known
     value by 10.5, and it is paired with a reading serif and a copper accent
     rather than with sage and a display serif.

     Honest limitation, measured rather than asserted. The near-white region is
     tiled: a brute-force search of every warm surface at page luminance
     against all 89 banned swatches returns a best-possible clearance of 8.8,
     under the 10 the scanner wants. The only values that do clear are green,
     which would read as mint and land nearer the over-correction centroid
     than this does. #EEECE8 is that proven optimum, so the one NEAR_DEFAULT
     flag on it is a property of the metric and not a colour nobody chose.

     The section band below it went the other way on purpose, to the cool
     shingle grey, which clears comfortably. Warm paper against a cool band is
     also the more honest reference: the greys on a real roof disagree with
     each other, and a page whose neutrals all share one hue looks printed by
     a machine that only had one ink. */
  --paper:#EEECE8;
  --ink:#16212B;
  --muted:#5C6673;
  --rule:#C4D0D6;       /* hairline, the main separator on this site */

  /* Radius is a SCALE keyed to what a thing is, not one token everywhere.
     Data and photographs get square corners because a rounded table reads as
     a widget rather than a document. */
  --r-data:0;
  --r-input:2px;
  --r-button:3px;
  --r-card:4px;

  /* Exactly one element type is allowed to cast a shadow: the estimator card,
     which genuinely floats over the hero. Everything else separates with a
     1px rule. When everything is elevated, nothing is. */
  --lift:0 18px 40px rgba(23,28,34,.22);

  --max-w:1140px;

  /* TYPE, AND THE REASON FOR IT
     Was Barlow Condensed + Inter. Condensed-caps-plus-Inter is the contractor
     template shop pairing and Inter is the single most common AI default body
     face, so the pairing said "generated" before a word was read.

     Literata was commissioned for Google Play Books and drawn specifically for
     sustained on-screen reading, which is what a 4,500-word cost page asks of
     someone. Public Sans is the United States Web Design System face, drawn
     for public-interest data publishing, which is exactly this site's job.
     IBM Plex Mono carries every figure, because aligned digits read as
     instrumented and unaligned ones read as marketing. */
  --font-head:Literata,Georgia,"Times New Roman",serif;
  --font-body:"Public Sans","Helvetica Neue",Arial,sans-serif;
  --font-mono:"IBM Plex Mono",ui-monospace,"SFMono-Regular",Menlo,monospace;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  font-family:var(--font-body);
  color:var(--ink);
  line-height:1.6;
  font-size:16px;
  background:var(--paper);
}
img{max-width:100%;height:auto}
a{color:var(--copper-deep);text-decoration:none}
a:hover{text-decoration:underline}
/* Negative tracking, not positive. The old rule added .3px to a condensed face,
   which is what a headline does when it is trying to look like signage. A serif
   at display size wants to close up slightly instead. */
h1,h2,h3{font-family:var(--font-head);font-weight:700;line-height:1.14;color:var(--slate-900);letter-spacing:-.011em}
h1{font-size:2.4rem}
h2{font-size:1.85rem;margin-bottom:1rem}
h3{font-size:1.3rem;margin-bottom:.5rem}
p{margin-bottom:1rem}
.container{width:100%;max-width:var(--max-w);margin:0 auto;padding:0 20px}

/* EVERY figure on this site is set in the mono with aligned digits. That is the
   single strongest signal that a number was measured rather than written: the
   columns line up, and a reader can compare two rows down the page without
   counting characters. Money, years, square footages, percentages, all of it. */
.cost-table td,.cost-table tbody th,.data-table td,
.est-result,.hero-note strong,.stat-figure{
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
}
.cost-table td,.data-table td:last-child,.est-result{font-family:var(--font-mono)}

/* Section rhythm. A single global padding value gives a page no pulse, which is
   how a generated layout reads even when the content is good. These alternate:
   a band sits tighter to the one above it, tinted bands open up, and the last
   band before the footer gets extra room so the page ends rather than stops. */
section{padding-block:52px 46px}
section + section{padding-block-start:38px}
section.bg-gray{padding-block:64px 58px}
section:nth-of-type(even){padding-block-end:54px}
section:last-of-type{padding-block-end:72px}

/* A page-title block is not a section of content, it is the masthead for the
   one below it, so it closes up instead of taking a full band. Without this the
   title sat 100px clear of its own first heading and the page opened on a hole. */
section.hero-plain{padding-block:44px 8px}
section.hero-plain + section{padding-block-start:22px}
.bg-gray{background:var(--slate-50)}
.section-sub{color:var(--muted);max-width:640px;margin:0 auto 2rem;text-align:center}

/* ---------- Buttons ---------- */
.btn{
  display:inline-block;padding:.8rem 1.6rem;border-radius:var(--r-button);
  font-weight:600;font-size:1rem;cursor:pointer;border:0;
  transition:background-color .15s ease,color .15s ease;text-align:center;
}
.btn:hover{text-decoration:none}
.btn-primary{background:var(--copper);color:var(--paper)}
.btn-primary:hover{background:var(--copper-deep);color:var(--paper)}
.btn-call{background:rgba(255,255,255,.12);color:var(--paper);border:1px solid rgba(255,255,255,.35)}
.btn-call:hover{background:rgba(255,255,255,.22);color:var(--paper)}
.btn-large{font-size:1.15rem;padding:1rem 2.2rem}
.btn-outline{background:transparent;color:var(--slate-900);border:2px solid var(--slate-900)}
.btn-outline:hover{background:var(--slate-900);color:var(--paper)}

/* ---------- Header ---------- */
.site-header{
  position:sticky;top:0;z-index:1000;
  background:var(--slate-900);color:var(--paper);
  box-shadow:0 2px 12px rgba(0,0,0,.25);
}
.header-inner{display:flex;align-items:center;gap:16px;padding:12px 20px}
.logo{
  display:flex;align-items:center;gap:.5rem;color:var(--paper);
  font-family:var(--font-head);font-weight:700;font-size:1.35rem;white-space:nowrap;
}
.logo:hover{text-decoration:none}
/* The mark is optically aligned, not baseline aligned: a gable profile sits
   visually low against cap height, so it is nudged up a hair. */
.logo-mark{color:var(--copper);flex:0 0 auto;margin-top:-2px}
.rating-figure{font-family:var(--font-mono);font-weight:500;font-variant-numeric:tabular-nums;color:var(--ink)}
.main-nav{display:none}
.main-nav.open{display:flex;position:absolute;top:100%;left:0;right:0;background:var(--slate-800);flex-direction:column;padding:10px 20px 18px}
.main-nav a{color:var(--paper);padding:10px 4px;font-weight:500;border-bottom:1px solid rgba(255,255,255,.08)}
.main-nav a:hover{color:var(--copper);text-decoration:none}
.header-ctas{margin-left:auto;display:flex;align-items:center;gap:10px}
.header-ctas .btn-call{font-size:.85rem;padding:.55rem .9rem}
.header-ctas .btn-primary{font-size:.85rem;padding:.55rem .9rem}
.hamburger{background:none;border:0;color:var(--paper);font-size:1.6rem;cursor:pointer;line-height:1}

/* ---------- Hero ---------- */
/* The aurora hero is gone. It was two stacked radial-gradient blobs over a
   135deg linear base, which is the most recognisable generated-site background
   there is, and the orange blob was rgba(249,115,22): Tailwind orange-500 again.

   What replaces it is a flat charcoal field carrying a shingle course. The
   repeating gradient draws the horizontal lines an asphalt roof actually makes,
   a butt edge every 34px where one course laps the one below. It is derived
   from the material the page is about rather than from a colour picker, it
   costs a few bytes, and it gives the hero texture without pretending to be a
   photograph. */
.hero{
  background:
    repeating-linear-gradient(
      180deg,
      rgba(255,255,255,.05) 0 1px,
      transparent 1px 17px,
      rgba(0,0,0,.18) 17px 18px,
      transparent 18px 34px
    ),
    var(--slate-900);
  color:var(--paper);padding:64px 0 56px;position:relative;
}
.hero-grid{display:flex;flex-direction:column;gap:28px}
.hero h1{color:var(--paper);font-size:2.6rem}
.hero .subhead{font-size:1.1rem;color:var(--slate-300);max-width:520px}
/* These were 999px pills with a unicode tick in front of each one, which is
   the standard generated "feature chip" and reads as decoration rather than
   as claims. They are claims, and two of the three are legal positioning, so
   they are set as a plain run of statements divided by copper rules. No pill,
   no tick, nothing to skim past. */
.trust-bullets{
  list-style:none;display:flex;flex-wrap:wrap;
  gap:.35rem 1.15rem;margin:1.25rem 0 0;
  font-size:.93rem;color:var(--slate-300);
}
.trust-bullets li{display:flex;align-items:baseline;gap:.6rem}
.trust-bullets li + li::before{
  content:"";align-self:stretch;width:1px;margin-right:.55rem;
  background:var(--copper);opacity:.55;
}
.hero-ctas{display:flex;flex-wrap:wrap;gap:12px;margin-top:1rem}

/* quote form card */
.quote-card{
  background:var(--paper);color:var(--ink);border-radius:14px;padding:26px;
  box-shadow:0 24px 60px rgba(0,0,0,.35);max-width:440px;width:100%;
}
.quote-card h3{color:var(--slate-900);font-size:1.6rem;margin-bottom:.35rem}
.quote-card>p{color:var(--muted);font-size:.95rem;margin-bottom:1.1rem}
.quote-form .form-row{margin-bottom:.85rem}
.quote-form label{display:block;font-weight:600;font-size:.85rem;margin-bottom:.3rem}
.quote-form input,
.quote-form select,
.quote-form textarea{
  width:100%;padding:.7rem .8rem;border:1px solid var(--rule);
  border-radius:8px;font-family:var(--font-body);font-size:1rem;background:var(--paper);color:var(--ink);
}
.quote-form input:focus,.quote-form select:focus,.quote-form textarea:focus{
  outline:2px solid var(--copper);border-color:var(--copper);
}
.quote-form textarea{min-height:96px;resize:vertical}
.quote-form .btn{width:100%;font-size:1.1rem}
.form-note{font-size:.8rem;color:var(--muted);text-align:center;margin-top:.6rem;margin-bottom:0}
.form-msg{display:none;margin-top:.9rem;padding:.8rem 1rem;border-radius:8px;font-weight:500;font-size:.95rem}
.form-msg.show{display:block}
.form-msg.success{background:#E9F9EF;color:#166534;border:1px solid #BBF7D0}
.form-msg.error{background:#FEF2F2;color:#991B1B;border:1px solid #FECACA}

/* ---------- Trust bar ---------- */
.trust-bar{background:var(--slate-800);color:var(--slate-300);padding:20px 0}
.trust-bar-inner{display:flex;flex-wrap:wrap;gap:14px 34px;justify-content:center;text-align:center}
.trust-bar-inner span{font-weight:600;font-size:.95rem}
.trust-bar-inner strong{color:var(--copper)}

/* ---------- Cards / grids ---------- */
.cards-grid{display:grid;grid-template-columns:1fr;gap:18px}
.card{
  background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-card);
  padding:24px;transition:border-color .15s ease,background-color .15s ease;
}
.card:hover{border-color:var(--copper);background:var(--wash-ink-strong)}
.card:hover a.card-title{text-decoration:underline}
.card .icon{font-size:2rem;display:block;margin-bottom:.6rem}
.card p{color:var(--muted);font-size:.95rem}
.card .read-more{font-weight:600}

/* ---------- Steps ---------- */
.steps{display:grid;grid-template-columns:1fr;gap:18px;counter-reset:step}
.step{position:relative;background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-card);padding:24px 24px 24px 76px;box-shadow:none}
.step::before{
  counter-increment:step;content:counter(step);
  position:absolute;left:20px;top:22px;width:42px;height:42px;border-radius:50%;
  background:var(--copper);color:var(--paper);font-family:var(--font-head);font-weight:700;font-size:1.4rem;
  display:flex;align-items:center;justify-content:center;
}

/* ---------- Reviews ---------- */
.reviews-grid{display:grid;grid-template-columns:1fr;gap:18px}
.review{background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-card);padding:24px;box-shadow:none}
.stars{color:var(--copper);font-size:1.15rem;letter-spacing:2px;margin-bottom:.6rem}
.review p{font-style:italic;color:var(--ink)}
.review .who{font-style:normal;font-weight:600;color:var(--muted);font-size:.9rem;margin-top:.8rem;margin-bottom:0}

/* ---------- Areas ---------- */
.areas-list{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;list-style:none}
.areas-list a{
  display:inline-block;background:var(--paper);border:1px solid var(--rule);border-radius:999px;
  padding:.55rem 1.1rem;font-weight:500;color:var(--slate-900);
}
.areas-list a:hover{background:var(--slate-900);color:var(--paper);text-decoration:none;border-color:var(--slate-900)}

/* ---------- FAQ ---------- */
.faq{max-width:760px;margin:0 auto}
.faq-item{border:1px solid var(--rule);border-radius:var(--r-card);margin-bottom:12px;background:var(--paper);overflow:hidden}
.faq-q{
  width:100%;text-align:left;background:none;border:0;cursor:pointer;
  padding:16px 20px;font-family:var(--font-body);font-weight:600;font-size:1.02rem;color:var(--slate-900);
  display:flex;justify-content:space-between;align-items:center;gap:12px;
}
/* One glyph, rotated, rather than swapping "+" for an en dash. The dash was
   a unicode en dash rendered as live UI, which the house style bans
   outright, and swapping the character also made the two states different
   optical weights. Transform is named explicitly, never "all". */
.faq-q::after{
  content:"+";font-size:1.4rem;color:var(--copper);font-weight:700;
  flex-shrink:0;line-height:1;transition:transform .15s ease;
}
.faq-item.open .faq-q::after{transform:rotate(45deg)}
@media (prefers-reduced-motion:reduce){.faq-q::after{transition:none}}
.faq-a{max-height:0;overflow:hidden;transition:max-height .25s ease}
.faq-a p{padding:0 20px 18px;color:var(--muted);margin:0}

/* ---------- CTA band ---------- */
.cta-band{background:var(--slate-900);color:var(--paper);text-align:center;padding:56px 20px}
.cta-band h2{color:var(--paper);font-size:2.2rem;margin-bottom:.6rem}
.cta-band p{color:var(--slate-300);max-width:560px;margin:0 auto 1.6rem}
.cta-band .row{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}

/* ---------- Cost page ---------- */
/* .content-narrow is applied TO the container, not nested inside it, so it must
   keep the container's own width and centring or it detaches from the page
   grid entirely. Narrowing the container itself was the bug: the heading sat
   in a 1140px container and the prose in an 800px one, both centred, so the
   two had different left edges and the page read as two documents stacked.

   Constrain the MEASURE instead. The column keeps the container's left edge
   and the text stops at a readable line length on the right, which is what a
   reference page does. Tables and figures are exempt; they use the full width. */
.content-narrow{max-width:var(--max-w);margin:0 auto}
.content-narrow > p,
.content-narrow > ul,
.content-narrow > ol,
.content-narrow > h2,
.content-narrow > h3,
.content-narrow > .lede{max-width:72ch}
.content-narrow h2{margin-top:2rem}
.content-narrow ul,.content-narrow ol{margin:0 0 1rem 1.4rem}
.content-narrow li{margin-bottom:.4rem}
/* The v1 .cost-table rules that used to sit here are gone. They were superseded
   by the block under "v2 additions" further down and the two definitions
   fought: this one painted EVERY th navy, including the row-label th in the
   body, while the v2 rule set that same cell's text to --text. The result was
   var(--ink) on var(--slate-900), a contrast ratio of 1.07 to 1, so the entire first
   column of every cost table rendered as an unreadable dark blue block. Keep
   table styling in ONE place. */
.callout{background:var(--wash-ink-strong);border:1px solid var(--copper);border-radius:var(--r-card);padding:18px 22px;margin:1.5rem 0}
.callout strong{color:var(--copper-deep)}

/* ---------- Quote page ---------- */
.quote-page-grid{display:flex;flex-direction:column;gap:30px}
.quote-aside h2{margin-bottom:.8rem}
.quote-aside ul{list-style:none}
.quote-aside li{margin-bottom:.9rem;padding-left:28px;position:relative}
.quote-aside li::before{content:"✓";position:absolute;left:0;color:var(--copper);font-weight:700}

/* ---------- Notices ---------- */
.notice{
  background:var(--wash-ink-strong);border:1px solid var(--rule);
  border-left:4px solid var(--muted);border-radius:var(--r-card);
  padding:16px 20px;margin:1.5rem 0;font-size:.95rem;
}
.notice p{margin-bottom:.7rem}
.notice p:last-child{margin-bottom:0}
.notice-warn{background:var(--wash-ink-strong);border-color:var(--copper);border-left-color:var(--copper)}
.notice-warn strong{color:var(--copper-deep)}
.notice-flag{background:#EEF3FA;border-color:#C6D6EC;border-left-color:var(--slate-900)}
.notice-flag strong{color:var(--slate-900)}

/* ---------- Small print ---------- */
.table-note{font-size:.82rem;color:var(--muted);line-height:1.5;margin:.6rem 0 1.5rem}
.opt{font-weight:400;font-size:.85em;color:var(--muted)}

/* checkbox + wrapping label, in both the estimator and the privacy form */
.est-check,
.quote-form label.est-check{
  display:flex;align-items:flex-start;gap:.6rem;
  font-weight:400;font-size:.88rem;color:var(--muted);
  line-height:1.45;margin:.9rem 0;cursor:pointer;
}
.est-check input[type="checkbox"]{
  flex:0 0 auto;width:16px;height:16px;margin-top:.18rem;
  accent-color:var(--copper);cursor:pointer;
}
.est-check span{flex:1}

/* honeypot: must stay in the DOM for bots, invisible to people */
.hp,
.quote-form input.hp,
.est-form input.hp{
  position:absolute;left:-9999px;top:auto;
  width:0;height:0;padding:0;border:0;
  opacity:0;pointer-events:none;overflow:hidden;
}

/* ---------- Footer ---------- */
.site-footer{background:var(--slate-900);color:var(--slate-300);padding:48px 0 0;margin-top:0}
.footer-grid{display:grid;grid-template-columns:1fr;gap:28px;padding-bottom:32px}
.site-footer h4{color:var(--paper);font-family:var(--font-head);font-size:1.25rem;margin-bottom:.8rem;letter-spacing:.4px}
.site-footer p{font-size:.93rem;color:var(--slate-300)}
.site-footer ul{list-style:none}
.site-footer li{margin-bottom:.45rem}
.site-footer a{color:var(--slate-300);font-size:.93rem}
.site-footer a:hover{color:var(--copper);text-decoration:none}
.footer-brand .logo{margin-bottom:.8rem}
.footer-bottom{border-top:1px solid rgba(255,255,255,.12);padding:18px 20px;display:flex;flex-direction:column;gap:8px;align-items:center;text-align:center;font-size:.85rem;color:var(--slate-300)}
.footer-bottom a{color:var(--slate-300)}

/* ---------- Responsive ---------- */
@media(min-width:640px){
  .cards-grid{grid-template-columns:1fr 1fr}
  .reviews-grid{grid-template-columns:1fr 1fr}
}
@media(min-width:900px){
  h1{font-size:3rem}
  h2{font-size:2.4rem}
  .hero h1{font-size:3.2rem}
  /* nowrap is the load-bearing declaration. Without it a two-word label breaks
     mid-item and the row goes ragged, with some items one line and some two. */
  .main-nav{display:flex;gap:20px;align-items:center}
  .main-nav a{color:var(--paper);font-weight:500;border:0;padding:4px 0;white-space:nowrap}
  .hamburger{display:none}
  .hero-grid{flex-direction:row;align-items:center}
  .hero-copy{flex:1.15}
  .hero-form{flex:.85;display:flex;justify-content:flex-end}
  .cards-grid{grid-template-columns:repeat(3,1fr)}
  .reviews-grid{grid-template-columns:repeat(3,1fr)}
  .steps{grid-template-columns:repeat(3,1fr)}
  .footer-grid{grid-template-columns:1.4fr 1fr 1fr 1fr}
  .footer-bottom{flex-direction:row;justify-content:space-between;text-align:left}
  .quote-page-grid{flex-direction:row;align-items:flex-start}
  .quote-page-grid .quote-card{flex:1}
  .quote-aside{flex:1}
}

/* ============================================================
   v2 additions: cost tables, estimator, vendor standards, notices
   Everything below supports the rebuilt generator-driven pages.
   ============================================================ */

.skip{position:absolute;left:-9999px;top:0;background:var(--slate-900);color:var(--paper);padding:10px 16px;z-index:99}
.skip:focus{left:8px;top:8px}

/* ---------- Breadcrumbs ---------- */
.crumbs{background:var(--slate-50);border-bottom:1px solid var(--rule);font-size:.86rem;padding:10px 0;color:var(--muted)}
.crumbs a{color:var(--muted)}
.crumbs a:hover{color:var(--copper-deep)}
.crumb-sep{opacity:.5;margin:0 2px}

/* ---------- Typography helpers ---------- */
.lede{font-size:1.18rem;line-height:1.55}
.center{text-align:center}
.content-narrow{max-width:var(--max-w)}
.read-more{font-weight:600}
.hero-note{background:rgba(255,255,255,.10);border-left:3px solid var(--copper);
  padding:.7rem 1rem;border-radius:6px;font-size:.97rem;margin-bottom:1rem}
.reasons{padding-left:1.2rem;margin-bottom:1rem}
.reasons li{margin-bottom:.85rem}
.src-list{padding-left:1.2rem}
.src-list li{margin-bottom:.4rem;font-size:.95rem}
.table-note{font-size:.86rem;color:var(--muted);margin-top:.5rem}
.opt{font-weight:400;color:var(--muted);font-size:.88em}

/* ---------- Tables ---------- */
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin-bottom:.5rem}
.cost-table{width:100%;border-collapse:collapse;font-size:.95rem;min-width:520px}
.cost-table caption{text-align:left;font-weight:600;color:var(--muted);
  font-size:.9rem;padding-bottom:.6rem}
.cost-table th,.cost-table td{padding:.7rem .8rem;border-bottom:1px solid var(--rule);text-align:left;vertical-align:top}
.cost-table thead th{background:var(--slate-900);color:var(--paper);font-family:var(--font-head);
  font-weight:600;letter-spacing:.4px;font-size:1rem;border-bottom:0}
/* Row-label cells are body content, not headings. State the background
   explicitly so no later rule can leave dark text sitting on the navy fill
   that thead uses. */
.cost-table tbody th{font-weight:600;color:var(--ink);background:transparent}
.cost-table tbody tr:nth-child(even){background:var(--wash-ink)}
.cost-table .row-hi{background:var(--wash-copper) !important;box-shadow:inset 3px 0 0 var(--copper)}
.tag{display:inline-block;background:var(--copper);color:var(--paper);font-size:.68rem;
  font-weight:600;padding:.12rem .45rem;border-radius:99px;vertical-align:middle;
  margin-left:.35rem;letter-spacing:.3px;text-transform:uppercase}

/* Per-row source attribution sitting under a figure in the cost table. Every
   expected-life number on this site names where it came from.
   max-width caps the column's max-content contribution, so the attribution
   wraps instead of stretching "expected life" to half the table width. */
.cell-cite{display:block;font-size:.72rem;color:var(--muted);line-height:1.4;
  margin-top:.3rem;font-weight:400;text-transform:none;letter-spacing:0;
  max-width:32ch}

/* ---------- Notices ---------- */
.notice{max-width:var(--max-w);margin:0 auto 1.4rem;padding:1rem 1.2rem;
  border-radius:var(--r-card);font-size:.96rem}
.notice p{margin:0}
.notice-warn{background:var(--wash-ink-strong);border-left:4px solid #E0A800}
.notice-flag{background:#FDECEC;border-left:4px solid #C0392B}
section > .notice,main > .notice{margin-left:20px;margin-right:20px}

/* ---------- Vendor standard ---------- */
.standard-list{padding-left:1.3rem;max-width:820px;margin:0 auto 2rem}
.standard-list li{margin-bottom:1rem}
.vendor-card{background:var(--wash-ink-strong);border:1px solid var(--rule);
  border-radius:var(--r-card);padding:1.6rem;max-width:640px;margin:0 auto}
.vendor-eyebrow{text-transform:uppercase;letter-spacing:.8px;font-size:.72rem;
  font-weight:600;color:var(--copper-deep);margin-bottom:.3rem}
.vendor-card h3{margin-bottom:.2rem}
.vendor-meta{font-size:.9rem;color:var(--muted);margin-bottom:.9rem}
.vendor-facts{list-style:none;margin-bottom:.9rem}
.vendor-facts li{padding:.35rem 0 .35rem 1.5rem;position:relative;font-size:.95rem;
  border-bottom:1px solid var(--rule)}
.vendor-facts li:before{content:"\2713";position:absolute;left:0;color:#1E874B;font-weight:700}
.vendor-note{font-size:.85rem;color:var(--muted);margin:0}
.stars{color:#F5A623;letter-spacing:1px}

/* ---------- Estimator ---------- */
.estimator{background:var(--paper);border-radius:var(--r-card);box-shadow:none;
  padding:1.5rem;max-width:520px;width:100%}
.estimator h3{margin-bottom:.3rem}
.estimator h4{font-family:var(--font-head);color:var(--slate-900);font-size:1.2rem;margin-bottom:.3rem}
.est-sub{font-size:.92rem;color:var(--muted);margin-bottom:1rem}
.est-step{display:none}
.est-step.is-active{display:block;animation:estIn .18s ease}
@keyframes estIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.estimator label{display:block;font-weight:600;font-size:.9rem;margin-bottom:.3rem;margin-top:.8rem}
.estimator input[type=text],.estimator input[type=email],.estimator input[type=tel],.estimator select{
  width:100%;padding:.75rem .85rem;border:1px solid var(--rule);border-radius:8px;
  font-family:inherit;font-size:1rem;background:var(--paper)}
.estimator input:focus,.estimator select:focus{outline:2px solid var(--copper);outline-offset:1px;border-color:var(--copper)}
.estimator .btn{width:100%;margin-top:1rem}
.est-micro{font-size:.82rem;color:var(--muted);text-align:center;margin:.6rem 0 0}
.est-choices{display:grid;grid-template-columns:1fr 1fr;gap:.6rem;margin-bottom:.4rem}
.est-choices-stack{grid-template-columns:1fr}
.est-choice{padding:.85rem .7rem;border:2px solid var(--rule);background:var(--paper);
  border-radius:8px;font-family:inherit;font-size:.95rem;font-weight:500;
  cursor:pointer;text-align:center;transition:border-color .12s,background .12s}
.est-choice:hover{border-color:var(--copper)}
.est-choice[data-selected="true"]{border-color:var(--copper);background:var(--wash-ink-strong);font-weight:600}
.btn-link{background:none;border:0;color:var(--muted);font-family:inherit;
  font-size:.9rem;cursor:pointer;text-decoration:underline;padding:.6rem;width:100%;margin-top:.4rem}
.btn-link:hover{color:var(--ink)}
.est-range{font-family:var(--font-head);font-size:2.6rem;font-weight:700;
  color:var(--slate-900);line-height:1.05;margin:.4rem 0 .3rem;text-align:center}
.est-basis{font-size:.9rem;color:var(--muted);text-align:center;margin-bottom:.8rem}
.est-method{font-size:.84rem;color:var(--muted);background:var(--wash-ink-strong);
  padding:.7rem .85rem;border-radius:8px}
.est-rule{border:0;border-top:1px solid var(--rule);margin:1.4rem 0 1rem}
.est-check{display:flex;gap:.6rem;align-items:flex-start;font-weight:400;
  font-size:.83rem;line-height:1.45;color:var(--muted);margin-top:1rem}
.est-check input{margin-top:.2rem;flex:0 0 auto;width:16px;height:16px;accent-color:var(--copper)}
.est-check a{text-decoration:underline}
.est-legal{font-size:.78rem;color:var(--muted);margin-top:.9rem;line-height:1.45}
/* .hp (honeypot) is defined earlier in this file and is more thorough. Not repeated. */
.form-msg{margin-top:.8rem;font-size:.92rem}
.form-msg.ok{color:#1E874B;font-weight:600}
.form-msg.err{color:#C0392B;font-weight:600}

/* Estimator sits on the dark hero, so it needs its own light context */
.hero .estimator{margin-left:auto}

/* ---------- Misc layout ---------- */
.legal-block{border-top:1px solid rgba(255,255,255,.12);padding:22px 20px;
  font-size:.8rem;color:var(--slate-300);line-height:1.55}
.legal-block p{font-size:.8rem;color:var(--slate-300);margin-bottom:.6rem}
.footer-tag{font-style:italic}
.footer-addr{font-size:.86rem;line-height:1.6}
/* The DBA line is a disclosure, not part of the address. Smaller and dimmer
   than the block above it so it reads as a footnote, but never hidden: the
   registered company stays legible on every page. */
.footer-dba{font-size:.78rem;line-height:1.5;opacity:.72;margin-top:.55rem}
.areas-list{list-style:none;display:grid;grid-template-columns:1fr 1fr;gap:.5rem 1rem}
.areas-list a{font-weight:500}

@media(min-width:640px){
  .areas-list{grid-template-columns:repeat(3,1fr)}
  .est-range{font-size:3rem}
}
@media(min-width:900px){
  .areas-list{grid-template-columns:repeat(4,1fr)}
  .notice{margin-bottom:1.8rem}
}

/* Town links on the Charlotte pillar. Grouped by county, so the list reads as
   geography rather than as a link dump. */
.town-links{list-style:none;margin:1.2rem 0;display:grid;gap:.7rem}
.town-links li{padding-left:0}
.town-links strong{color:var(--ink,inherit)}

/* Related guides. A link plus one line of what is behind it, because a bare
   list of titles makes a reader guess and a guess is a page they do not open. */
.related-guides{list-style:none;display:grid;gap:1rem;margin:1.2rem 0}
.related-guides li{display:grid;gap:.15rem;padding-bottom:1rem;border-bottom:1px solid var(--rule)}
.related-guides li:last-child{border-bottom:0;padding-bottom:0}
.related-guides a{font-family:var(--font-head);font-weight:700;font-size:1.06rem}
.related-guides span{font-size:.92rem;color:var(--muted);line-height:1.55}
