/* Business Internet Locator */

/* Palette and type ported from Colocation Scout so the two sites read as one
   family. Navy carries structure, one green carries signal, warm off-white
   ground with white surfaces on top. */
:root {
  --ink: #16181d;
  --ink-2: #4b5160;
  --muted: #80869a;
  --line: #e6e4df;
  --bg: #faf9f7;
  --surface: #ffffff;
  --bg-soft: #ffffff;
  --brand: #003b5c;
  --brand-dark: #002944;
  --brand-deep: #001c2e;
  --accent: #003b5c;
  --accent-ink: #002944;
  --accent-soft: #e5edf2;
  --signal: #43b763;
  --signal-soft: #e9f7ed;
  --signal-bright: #7fe0a0;
  --sky: #7fd4f0;
  --ink-inv: rgba(230, 239, 245, .68);
  --ink-inv-2: rgba(230, 239, 245, .5);
  --rule-inv: rgba(230, 239, 245, .12);
  --warn: #b26a00;
  --font-head: "Schibsted Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --radius: 12px;
  --wrap: 1140px;
  /* The clear space between the content and the window edge, at any width. See
     .wrap for why this is a variable and not just padding.
     It grows with the window rather than sitting at a fixed number, because the
     complaint this solves is proportional: 1140px of content looks stretched in
     a 1180px window and looks right in a 1900px one. 6vw and the 1140px cap
     hand off at about 1460px, so below that the margin grows and above it the
     content stops growing. 80px is where a margin stops reading as breathing
     room and starts reading as a narrow column. */
  --gutter: clamp(20px, 6vw, 80px);
  --shadow: 0 1px 2px rgba(22, 24, 29, .04), 0 12px 32px -16px rgba(22, 24, 29, .12);
  --shadow-lg: 0 24px 60px -30px rgba(0, 32, 51, .45);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.62;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; }
a { color: var(--brand); }
h1, h2, h3, h4 { font-family: var(--font-head); letter-spacing: -.015em; text-wrap: balance; }
p { text-wrap: pretty; }

/* Width, not max-width plus padding, and the reason is Windows per-monitor
   scaling. Cody runs two screens at different scale factors, so the same window
   is about 1180 CSS pixels on one and about 1900 on the other.
   `max-width: 1140px; padding: 0 20px` is fine at 1900 and wrong at 1180: the
   container hits its cap, the outer margin goes to nothing, and the page runs
   edge to edge with the logo 13px from the window frame.
   Padding cannot fix that, because padding sits INSIDE max-width. It narrows
   the text and leaves the box touching the edges.
   min() fixes both screens with one rule. The content is 1140px when there is
   room for it, and viewport-minus-two-gutters when there is not, so the gutter
   is a floor rather than a leftover. 1180px gives a 47px margin; 1900px gives
   the same 1140px column it always had. */
.wrap {
  width: min(var(--wrap), 100% - 2 * var(--gutter));
  margin-inline: auto;
}
/* A wrap inside a wrap is a double inset and a narrower column than its
   neighbours. Components carry their own wrap so they are safe to drop anywhere,
   which means nesting has to be harmless. */
.wrap .wrap { width: auto; }
/* TYPE SCALE, AUGUST 2026. Everything below was tuned on a wide monitor and read
   a notch too large on an ordinary laptop, where a 150% Windows scale leaves an
   effective viewport nearer 1000px than 1400px. Two things were wrong and both
   are fixed here rather than in a media query.

   The vw terms in the clamps grew too fast: 4.6vw put a 46px headline into a
   474px column at a 1000px viewport, which is three lines of six words. The vw
   term now rises more slowly, so a narrow viewport lands near the floor instead
   of near the cap, and a genuinely wide one still gets a big headline.

   Vertical padding was the other half. The home hero measured 785px tall, which
   is the whole first screen on a 760px viewport: the visitor saw the headline
   and nothing else, so nothing below the fold could earn a scroll.

   Body copy stays at 16px. The complaint was about display type and whitespace,
   and shrinking running prose to fix a headline makes the reading pages worse. */
.section { margin: 38px auto; }
.section > h2 { font-size: 1.42rem; line-height: 1.28; margin: 0 0 13px; letter-spacing: -.01em; }
.section > h3 { font-size: 1.04rem; margin: 22px 0 8px; }
.section p { margin: 0 0 14px; }
.lead { font-size: 1.08rem; color: var(--ink-2); }

/* A compact answer-first line on high-intent pages. Deliberately quieter than
   a callout: it should help scanning without competing with the page itself. */
.answer-summary {
  margin-top: 30px;
  margin-bottom: -10px;
}
.answer-summary p {
  margin: 0;
  padding: 3px 0 3px 14px;
  border-left: 2px solid var(--accent);
  color: var(--ink-2);
  line-height: 1.65;
}
.answer-summary strong {
  margin-right: 7px;
  color: var(--ink);
  font-size: .76rem;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.skip {
  position: absolute; left: -9999px; top: 0; background: var(--brand); color: #fff;
  padding: 10px 16px; z-index: 100;
}
.skip:focus { left: 0; }

/* ---------------------------------------------------------------- header */
.site-head {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255,255,255,.94);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--line);
}
.head-inner { display: flex; align-items: center; gap: 20px; height: 60px; }
.brand { display: flex; align-items: center; text-decoration: none; flex: none; }
/* Height drives it, width follows. Two lines of type sit beside the mark, so
   the height has to carry both, and "Locator" is the line that gives out first.
   44px was measured, not guessed: it is the smallest height at which the second
   line still reads as a word rather than a blue smudge, which is why the type
   scale pass above stopped here instead of taking it down with everything else. */
.brand-logo { display: block; height: 44px; width: auto; }

.site-nav { display: flex; gap: 18px; margin-left: auto; }
.site-nav a {
  text-decoration: none; color: var(--ink-2); font-size: .89rem; font-weight: 500;
  padding: 6px 0; border-bottom: 2px solid transparent;
}
.site-nav a:hover { color: var(--brand); }
.site-nav a.active { color: var(--brand); border-bottom-color: var(--sky); }
.head-cta { flex: none; }
.nav-toggle { display: none; background: none; border: 0; padding: 8px; cursor: pointer; }
.nav-toggle span { display: block; width: 22px; height: 2px; background: var(--ink); margin: 4px 0; border-radius: 2px; }

/* ----------------------------------------------------------------- hero */
.hero {
  background: linear-gradient(160deg, var(--brand-deep) 0%, var(--brand) 55%, #0a6b8f 100%);
  color: #fff; padding: 50px 0 44px;
  position: relative; isolation: isolate;
}
/* The animated lattice sits on the gradient rather than replacing it, which is
   why the component is passed background="none". Copy stays above it. */
.hero-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.hero-bg iso-fiber-bg { display: block; width: 100%; height: 100%; }
.hero > .wrap { position: relative; z-index: 1; }
.hero h1 { font-size: clamp(1.7rem, 3vw, 2.45rem); line-height: 1.15; margin: 0 0 13px; letter-spacing: -.025em; max-width: 20ch; }
.hero-sub { font-size: 1.04rem; color: rgba(255,255,255,.88); max-width: 62ch; margin: 0 0 22px; }
.eyebrow {
  font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .12em;
  font-size: .76rem; font-weight: 700; color: var(--accent-ink); margin: 0 0 14px;
}
.hero .eyebrow { color: var(--sky); }
.hero-ctas { display: flex; gap: 12px; flex-wrap: wrap; }
.hero-stats { display: flex; gap: 34px; margin-top: 28px; flex-wrap: wrap; }
.hero-stats strong { display: block; font-size: 1.5rem; line-height: 1.1; }
.hero-stats span { font-size: .84rem; color: rgba(255,255,255,.72); }

/* Split hero. Used only where the thing the visitor came to do should be on
   screen without scrolling, which today means the availability checker. */
.hero-split { padding: 40px 0 38px; }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(370px, 450px); gap: 36px; align-items: start; }
.hero-split h1 { font-size: clamp(1.6rem, 2.5vw, 2.1rem); max-width: 16ch; }
.hero-split .hero-sub { max-width: 46ch; margin-bottom: 0; }
/* The card is already the widest thing in its column, so the shared 720px cap
   and the generous standalone padding both work against it here. */
.hero-aside .checker { max-width: none; margin: 0; padding: 22px; }

/* Set by checker.js once the visitor is past the questions. The hero copy has
   said its piece by then, and the results card is several times taller than the
   form was, so it takes the whole column instead of being clipped inside half
   of one. */
body.checker-wide .hero-copy { display: none; }
body.checker-wide .hero-grid { grid-template-columns: minmax(0, 1fr); }
body.checker-wide .hero-aside .checker { max-width: 720px; margin: 0 auto; padding: 22px; }
body.checker-wide .hero-split { padding: 24px 0 38px; }

@media (max-width: 980px) {
  .hero-grid { grid-template-columns: 1fr; gap: 28px; }
  .hero-split .hero-sub { max-width: 62ch; }
}

/* --------------------------------------------------------------- buttons */
.btn {
  display: inline-block; padding: 11px 18px; border-radius: 8px; text-decoration: none;
  font-weight: 600; font-size: .9rem; border: 1px solid transparent; cursor: pointer;
  transition: transform .08s ease, box-shadow .12s ease, background .12s ease;
}
.btn:active { transform: translateY(1px); }
/* Navy carries structure, green carries "go". Every button that starts an
   address check or submits a form is green, on white and on the navy hero. */
.btn-primary { background: var(--signal); color: #052b14; }
.btn-primary:hover { background: #38a655; }
.btn-ghost { background: rgba(255,255,255,.1); color: #fff; border-color: rgba(255,255,255,.34); }
.btn-ghost:hover { background: rgba(255,255,255,.18); }
/* A third weight, between the green primary and the near-invisible ghost. Used
   for a control that has to be findable without competing with the one action
   that matters on the screen. Inherits --accent, so it is navy on a white page
   and sky blue on the dark checker card without a second rule. */
.btn-outline {
  background: transparent; color: var(--accent); border-color: var(--accent);
  font-weight: 650;
}
.btn-outline:hover { background: var(--accent); color: #fff; }
.checker .btn-outline:hover { color: #00263c; }
.btn-sm { padding: 8px 14px; font-size: .88rem; }
.btn-block { width: 100%; }
.inline-link { font-weight: 600; }

/* ----------------------------------------------------------- breadcrumbs */
.crumbs { font-size: .84rem; color: var(--muted); padding: 14px 0 0; }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--brand); text-decoration: underline; }
.crumb-sep { margin: 0 8px; opacity: .5; }

/* ---------------------------------------------------------------- cards */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(255px, 1fr)); gap: 14px; }
.card {
  display: flex; flex-direction: column; gap: 6px; padding: 18px 18px 20px;
  border: 1px solid var(--line); border-radius: var(--radius); text-decoration: none;
  background: #fff; color: var(--ink); transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.card:hover { border-color: var(--accent); box-shadow: var(--shadow); transform: translateY(-2px); }
.card-icon { height: 26px; width: auto; max-width: 150px; object-fit: contain; object-position: left center; align-self: flex-start; margin-bottom: 8px; }
.card-title { font-weight: 650; font-size: 1rem; line-height: 1.3; }
.carrier-logo { display: block; height: 42px; width: auto; max-width: 260px; object-fit: contain; object-position: left center; margin: 0 0 18px; }
.card-desc { font-size: .88rem; color: var(--muted); line-height: 1.5; }
.card-tag {
  align-self: flex-start; margin-top: 4px; font-size: .7rem; text-transform: uppercase;
  letter-spacing: .07em; font-weight: 700; color: var(--brand);
  background: var(--accent-soft); padding: 3px 8px; border-radius: 999px;
}

/* ---------------------------------------------------------------- lists */
.ticks, .warns { list-style: none; padding: 0; margin: 0 0 16px; }
.ticks li, .warns li { position: relative; padding-left: 28px; margin-bottom: 9px; }
.ticks li::before {
  content: ""; position: absolute; left: 6px; top: .62em; width: 6px; height: 11px;
  border-right: 2px solid var(--signal); border-bottom: 2px solid var(--signal);
  transform: rotate(42deg);
}
.warns li::before {
  content: "!"; position: absolute; left: 4px; top: 0; font-weight: 800;
  color: var(--warn); font-size: .95rem;
}
.two-col { columns: 2; column-gap: 34px; }
.two-col li { break-inside: avoid; }

.steps { padding-left: 20px; margin: 0; }
.steps li { margin-bottom: 12px; }

/* --------------------------------------------------------------- tables */
.table-wrap { overflow-x: auto; margin: 0 0 18px; border: 1px solid var(--line); border-radius: var(--radius); }
table { border-collapse: collapse; width: 100%; font-size: .93rem; min-width: 460px; }
th, td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--line); vertical-align: top; }
thead th { background: var(--bg-soft); font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
tbody th { font-weight: 600; }
tbody tr:last-child th, tbody tr:last-child td { border-bottom: 0; }

/* -------------------------------------------------------------- callout */
.callout {
  background: var(--accent-soft); border-left: 3px solid var(--accent);
  padding: 16px 18px; border-radius: 0 var(--radius) var(--radius) 0; margin: 20px 0;
}
.callout strong { display: block; margin-bottom: 4px; }
.callout p { margin: 0; font-size: .94rem; color: var(--ink-2); }

/* Acquired carrier names, under the carrier grid. Deliberately quiet: it is a
   footnote for somebody holding old paperwork, not one of the options. */
.carriers-retired { margin: 14px 0 0; color: var(--ink-2); font-size: .92rem; }

.note { border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; margin-bottom: 14px; background: var(--bg-soft); }
.note h3 { margin: 0 0 6px; font-size: 1.02rem; }
.note p { margin: 0; color: var(--ink-2); font-size: .95rem; }

.split { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; margin: 8px 0 12px; }
.split h3 { font-size: .96rem; margin: 0 0 8px; }
.provider-block { border-top: 1px solid var(--line); padding-top: 30px; }
.provider-type { font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); margin: -8px 0 12px; font-weight: 600; }

/* ----------------------------------------------------------------- FAQ */
.faqs { border-top: 1px solid var(--line); }
.faq { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer; padding: 15px 34px 15px 0; font-weight: 600; list-style: none;
  position: relative; font-size: 1rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; position: absolute; right: 6px; top: 13px; font-size: 1.3rem;
  font-weight: 400; color: var(--accent);
}
.faq[open] summary::after { content: "\2013"; }
.faq-a { padding: 0 0 16px; color: var(--ink-2); }
.faq-a p { margin: 0; }

/* ---------------------------------------------------------------- forms */
.form-section { background: var(--bg-soft); padding: 38px 20px; margin: 48px 0 0; border-top: 1px solid var(--line); }
.form-card { max-width: 720px; margin: 0 auto; background: #fff; border: 1px solid var(--line); border-radius: 16px; padding: 26px; box-shadow: var(--shadow); }
.form-card h2 { margin: 0 0 6px; font-size: 1.32rem; letter-spacing: -.015em; }
.form-sub { color: var(--muted); margin: 0 0 20px; font-size: .93rem; }
.field { display: block; margin-bottom: 15px; }
.field > span { display: block; font-size: .8rem; font-weight: 600; margin-bottom: 5px; color: var(--ink-2); }
.field input, .field select, .field textarea {
  width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px;
  font: inherit; font-size: .9rem; background: #fff; color: var(--ink);
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.field-row.two { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
.form-fine { font-size: .82rem; color: var(--muted); margin: 12px 0 0; text-align: center; }
.hp { position: absolute; left: -9999px; }

/* ------------------------------------------------- the checker card, dark */
/* Deep blue on the hero's blue, ported from the home page console panel so both
   placements read as one component. It was a white card until August 2026, which
   put a bright rectangle in the middle of a dark hero and made the page look
   like two designs stapled together.
                                                                    ┌ how ┐
   The palette is swapped by REBINDING the variables rather than by rewriting
   the forty-odd rules underneath. Every child already reaches for var(--ink),
   var(--muted), var(--line) and var(--accent-soft), so redefining those four
   here re-themes the steps, the price panel, the carrier list, the result rows
   and stage three in one place. Add a child rule with a hardcoded #16181d and
   you have opted out of this and will get black text on navy, so do not. */
.checker {
  --ink: #ffffff;
  --ink-2: rgba(230, 239, 245, .74);
  /* .55 is the console panel's muted tone and it reads fine on the panel's own
     labels, but the checker uses --muted for running help text at 14px, which
     measured 4.16:1 on this ground. Lifted until it clears 4.5:1 while staying
     visibly quieter than --ink-2. */
  --muted: rgba(230, 239, 245, .66);
  --line: rgba(230, 239, 245, .2);
  --accent: var(--sky);
  --accent-soft: rgba(0, 20, 33, .42);
  --surface: rgba(0, 20, 33, .5);
  --bg-soft: rgba(0, 20, 33, .5);

  max-width: 720px; margin: 0 auto; padding: 26px;
  background: #003b5c;
  border: 1px solid rgba(230, 239, 245, .16); border-radius: 16px;
  box-shadow: 0 30px 60px -30px rgba(0, 20, 33, .8);
}

/* Still set explicitly. The card sits inside .hero, which sets a colour for its
   own copy, and a heading with none of its own inherits it. That is how three
   headings went missing once already, so this line stays even though --ink is
   now white anyway. */
.checker, .checker h1, .checker h2, .checker h3, .checker h4 { color: var(--ink); }

/* Inputs need the treatment the console panel uses: a well darker than the card
   rather than a white box, or every field reads as a hole punched in the panel.
   16px is not a style choice. iOS Safari zooms the page in when you focus an
   input smaller than that and does not zoom back out, so a visitor filling this
   in on a phone ends up scrolling sideways through the rest of the form. The
   shared .field rule is .9rem, which is 14.4px, and the home page console panel
   set 16px explicitly to avoid exactly this. */
.checker .field input, .checker .field select, .checker .field textarea {
  background: rgba(0, 20, 33, .5); color: #fff; border-color: rgba(230, 239, 245, .2);
  /* Padding came down with the type scale pass. The 16px did not, and must not:
     see the note above. A shorter field is a style choice, a smaller one is a
     sideways-scrolling phone. */
  font-size: 16px; padding: 10px 12px;
}
.checker .field input::placeholder, .checker .field textarea::placeholder { color: rgba(230, 239, 245, .38); }
.checker .field input:focus, .checker .field select:focus, .checker .field textarea:focus {
  border-color: var(--sky); box-shadow: 0 0 0 3px rgba(127, 212, 240, .28);
}
/* A native select drops its options on a white list whatever the field looks
   like, so the option text has to go back to dark or it is white on white. */
.checker .field select option { color: #16181d; }

/* The green the palette allows, on the one button that moves you forward. */
.checker .btn-primary { background: var(--signal); color: #052b14; border-color: transparent; }
.checker .btn-primary:hover { background: var(--signal-bright); color: #052b14; }

.step h2 { margin: 0 0 7px; font-size: 1.12rem; line-height: 1.28; letter-spacing: -.015em; }
.step-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .1em; font-weight: 700; color: var(--accent); margin: 0 0 9px; }
.step-help { color: var(--muted); font-size: .86rem; line-height: 1.5; margin: 0 0 17px; }
/* The button after a run of fields needs air above it, or it reads as one more
   field rather than the thing that ends the step. */
.step .btn-block { margin-top: 10px; }
.step-nav { display: flex; gap: 10px; margin-top: 20px; }
.step-nav .btn { flex: 1; }
/* Back sits on the dark card, so it is a quiet outline rather than a white
   block. It was given a white background when the card was white; leaving that
   in place now would put near-white type on white, which is how this button
   managed to be invisible for weeks the first time. */
.step-nav .btn-ghost {
  flex: 0 0 auto; padding-left: 20px; padding-right: 20px;
  background: transparent; color: rgba(230, 239, 245, .74); border-color: rgba(230, 239, 245, .28);
}
.step-nav .btn-ghost:hover {
  background: rgba(230, 239, 245, .08); border-color: var(--sky); color: #fff;
}
.step .form-fine { margin-top: 12px; }

/* --------------------------------------------------- the ask, on step three */
/* Step three is the only step that delivers something and asks for something in
   the same view, and the ask was losing. It was two field rows under a hint
   line, with no heading, competing with 200 words of result above it. Boxing it
   gives it a beginning, and the heading gives it a name. */
.ask {
  margin-top: 22px; padding: 18px 18px 16px;
  border: 1px solid var(--line); border-radius: 12px;
  /* One shade off the card, not a bright panel. The result above is the reward
     and should stay the brightest thing; this only has to read as separate. */
  background: var(--surface);
}
.ask-head { margin: 0 0 5px !important; font-size: 1.04rem; letter-spacing: -.01em; }
.ask-why { margin: 0 0 16px; font-size: .86rem; line-height: 1.5; color: var(--ink-2); }
/* What completing actually gets them, next to the button that completes it.
   These three lines were previously scattered across a step-hint above the
   fields and a form-fine below them, where nobody reads them as a set. */
.ask-gets {
  list-style: none; margin: 14px 0 0; padding: 12px 0 0;
  border-top: 1px solid var(--line);
  font-size: .82rem; line-height: 1.45; color: var(--muted);
}
.ask-gets li { position: relative; padding-left: 19px; margin-bottom: 5px; }
.ask-gets li:last-child { margin-bottom: 0; }
/* A tick, not a bullet. Each line is something they get, not a feature. */
.ask-gets li::before {
  content: "\2713"; position: absolute; left: 0; top: 0;
  color: var(--signal); font-weight: 700;
}
.checker .ask-gets li::before { color: var(--signal-bright); }
/* Sits under the button that repeats the submit, so it has to read as a nudge
   toward the fields rather than as another disclaimer. */
.step-hint { font-size: .82rem; color: var(--muted); text-align: center; margin: 8px 0 20px; }
.choices { display: grid; gap: 10px; margin-bottom: 18px; }
.choice { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; }
.choice:hover { border-color: var(--accent); }
.choice input { margin-top: 4px; flex: none; }
.choice span { display: block; font-size: .92rem; color: var(--muted); }
.choice strong { display: block; color: var(--ink); font-size: 1rem; margin-bottom: 2px; }
/* Step two of the checker. This panel is the only place on the site that shows
   a number before anything has been asked for, so it is styled to read as a
   result rather than as another form field. */
/* Every number below is fighting for the same 900px: this panel is the reward
   and the ask underneath it is the point, and if the panel runs past the fold
   the screen ends on a disclaimer with no visible way forward. The DIA bullets
   added about 140px, so the padding here was tightened to buy it back. */
.result { background: var(--accent-soft); border-radius: 10px; padding: 16px 18px; margin-bottom: 14px; }
.result h3 { margin: 0 0 10px; font-size: 1.02rem; letter-spacing: -.01em; }
.res-rows { margin-bottom: 10px; }
.res-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 18px;
  padding: 7px 0; border-bottom: 1px solid var(--line); font-size: .93rem; color: var(--ink-2);
}
.res-row:last-child { border-bottom: none; }
.res-val { font-weight: 700; color: var(--ink); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* The list is the row's third child. flex-wrap plus a 100% basis drops it onto
   its own line under the label and the price, which keeps those two on one line
   together and keeps the reading order label, price, detail. */
.res-row.has-points { flex-wrap: wrap; padding-bottom: 12px; }
.res-points {
  flex: 0 0 100%;
  list-style: none; margin: 7px 0 0; padding: 0;
  /* Quieter than the label it hangs off, or the row reads as three rows. */
  font-size: .84rem; line-height: 1.45; color: var(--muted);
}
.res-points li { position: relative; padding-left: 15px; margin-bottom: 4px; }
.res-points li:last-child { margin-bottom: 0; }
/* Drawn rather than a real bullet, so it picks up the accent in both themes and
   cannot inherit a list marker colour we did not choose. */
.res-points li::before {
  content: ""; position: absolute; left: 0; top: .52em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--accent);
}
/* On the dark card --accent is already rebound to --sky, but --muted there is a
   translucent white that measured fine for running help text and thin for 13px
   list items sitting on the panel's own darker well. Lifted for this one use. */
.checker .res-points { color: rgba(230, 239, 245, .76); }
.result p { margin: 0 0 8px; font-size: .9rem; line-height: 1.5; color: var(--ink-2); }
.result p:last-child { margin-bottom: 0; }
.res-fine { font-size: .8rem !important; color: var(--muted) !important; padding-top: 9px; border-top: 1px solid var(--line); }

/* ------------------------------------------------- the address receipt */
/* Sits at the top of step two. Written by checker.js, so with JavaScript off it
   never renders and none of this applies. Deliberately quiet: a green tick and a
   line of fact, not a success banner. It is confirming that we have the address
   and know the market, which is a smaller claim than a celebration would imply. */
.addr-ok {
  display: flex; align-items: flex-start; gap: 12px;
  margin: 0 0 24px; padding: 13px 15px;
  background: var(--accent-soft); border: 1px solid var(--line);
  border-left: 3px solid var(--signal); border-radius: 10px;
}
.ao-tick {
  flex: 0 0 auto; margin-top: 1px;
  display: grid; place-items: center; width: 20px; height: 20px;
  border-radius: 50%; background: var(--signal); color: #fff;
  font-size: .72rem; font-weight: 700; line-height: 1;
}
.ao-body { display: block; min-width: 0; }
.ao-head {
  display: block; font: 700 .68rem/1 var(--font-mono);
  letter-spacing: .12em; text-transform: uppercase; color: var(--signal);
}
/* The address itself wraps rather than truncating. A cut off address is exactly
   the thing somebody is checking when they read this. */
.ao-addr { display: block; margin-top: 5px; font-size: .95rem; color: var(--ink); overflow-wrap: anywhere; }
.ao-note { display: block; margin-top: 3px; font-size: .84rem; line-height: 1.5; color: var(--ink-2); }

/* On the dark checker card the pale tint and the mid green both disappear, so
   the tint goes translucent and the text picks up the card's own bright green. */
.checker .addr-ok { background: rgba(67, 183, 99, .12); border-color: rgba(127, 224, 160, .3); border-left-color: var(--signal-bright); }
.checker .ao-tick { background: var(--signal-bright); color: #00263c; }
.checker .ao-head { color: var(--signal-bright); }

/* ------------------------------------------------- address suggestions */
/* Drawn by address-suggest.js, which builds this markup itself rather than
   using Google's widget. If that script never runs, none of this renders and
   the address box is an ordinary input. */
.addr-suggest-wrap { position: relative; }
.addr-suggest {
  position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; right: 0;
  list-style: none; margin: 0; padding: 4px;
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 28px rgba(0, 25, 45, .16);
  max-height: 280px; overflow-y: auto;
}
.addr-option {
  padding: 9px 11px; border-radius: 7px; cursor: pointer;
  display: flex; flex-direction: column; gap: 1px;
}
.addr-option:hover, .addr-option.is-active { background: var(--accent-soft); }
.ao-main { font-size: .93rem; font-weight: 600; color: var(--ink); }
.ao-rest { font-size: .82rem; color: var(--muted); }

/* The dropdown stays a white popover even inside the dark checker card, because
   that is what an address suggestion list looks like everywhere else and a
   translucent one over an animated hero is unreadable. But .checker rebinds
   --ink to white and --muted to a pale blue for its own text, and those land on
   this white ground as white on white. So the popover puts the light values
   back for its own subtree. One place, rather than hardcoding a colour into
   every row rule and having the light pages drift away from the dark one. */
.checker .addr-suggest {
  --ink: #16181d;
  --muted: #4b5160;
  --line: #e6e4df;
  --accent-soft: #e5edf2;
  border-color: rgba(0, 25, 45, .18);
}

/* The carrier taste on the market panel. Logos only, no names and no links:
   enough to show there is something real behind the form, not enough to be the
   answer. Greyed back so it reads as a preview rather than a result. */
.res-peek { margin: 12px 0 10px; padding-top: 11px; border-top: 1px solid var(--line); }
.res-peek-label {
  font-size: .72rem !important; text-transform: uppercase; letter-spacing: .1em;
  font-weight: 700; color: var(--muted) !important; margin: 0 0 8px !important;
}
/* Logos come in at wildly different aspect ratios, so each cell holds a fixed
   box and the image is contained inside it. Without the box, one tall wordmark
   sets the height of the whole row and the rest float. */
.res-peek-logos {
  list-style: none; margin: 0 0 9px; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px;
}
/* Same reason as the stage three tiles: a white chip per logo, because the
   artwork is coloured marks drawn for white paper. The teaser used to dim these
   to 72 percent on a white card, which was a nice touch there and would be
   illegible here, so full opacity on a light chip instead. */
.res-peek-logos li {
  height: 34px; display: flex; align-items: center; justify-content: center;
  padding: 0 8px; background: #fff; border-radius: 7px;
}
.res-peek-logos img {
  display: block; max-height: 20px; width: auto; max-width: 100%;
  object-fit: contain; object-position: center;
}
.res-peek-more { font-size: .84rem !important; color: var(--muted) !important; margin: 0 !important; }

@media (max-width: 560px) {
  /* Two, not three. The teaser shows four logos, and three columns leaves the
     fourth alone on a second row looking like a mistake. */
  .res-peek-logos { grid-template-columns: repeat(2, 1fr); }
}

.field-group-label {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .1em; font-weight: 700;
  color: var(--muted); margin: 22px 0 10px;
}

@media (max-width: 560px) {
  .res-row { flex-direction: column; gap: 2px; }
  /* Stays a wrapping row rather than stacking. The label and the price are short
     enough to share a line even at 320px, and the wrap already gives the list
     its own line, so column direction here would only push the price below the
     bullets it belongs to. */
  .res-row.has-points { flex-direction: row; gap: 12px; }
}

/* ------------------------------------------------- checker, stage three */
/* Shown only after the submission goes through. Everything here is the reward
   for handing over an address, so it is styled to feel like a document they
   were given rather than another step in a funnel. */
/* The colour is not decoration. This card sits inside the hero, which sets
   colour to white for its own copy, and a heading with no colour of its own
   inherits that and disappears against the white card. */
.checker-done h3 { margin: 0 0 8px; font-size: 1.2rem; letter-spacing: -.015em; color: var(--ink); }
.checker-done h4 { margin: 22px 0 11px; font-size: .76rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); }
.done-tick {
  width: 36px; height: 36px; border-radius: 50%; background: var(--signal); color: #052b14;
  display: flex; align-items: center; justify-content: center; font-size: 1.15rem; font-weight: 700;
  margin: 0 0 12px;
}
.done-lead { font-size: .98rem; line-height: 1.6; color: var(--ink-2); margin: 0 0 20px; }
.checker-done .res-note { font-size: .89rem; line-height: 1.55; color: var(--ink-2); margin: 0 0 10px; }
.checker-done .res-fine { font-size: .8rem; color: var(--muted); margin: 0 0 4px; }

/* The price is the single thing on this screen somebody screenshots, so it gets
   its own block rather than a row in a table. */
.res-prices { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); margin-bottom: 14px; }
.res-price { background: var(--accent-soft); border-radius: 12px; padding: 18px 20px; }
.rp-label { display: block; font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; font-weight: 700; color: var(--muted); margin-bottom: 8px; }
.rp-value { display: block; font-size: 1.35rem; font-weight: 700; letter-spacing: -.02em; color: var(--ink); font-variant-numeric: tabular-nums; }
.rp-unit { display: block; font-size: .85rem; color: var(--muted); margin-top: 2px; }

/* Logos come in at wildly different aspect ratios, so the tile holds a fixed
   box and the image is contained inside it. Without that, one tall wordmark
   sets the height of every row. */
.res-carriers { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
/* These tiles stay white on the dark card, and that is deliberate rather than
   an oversight. Carrier logos are supplied as coloured marks on transparent
   grounds, drawn for white paper: Segra is #0505D4 and Comcast is #006FBA, and
   both disappear on navy. A white chip per carrier keeps every logo legible
   without recolouring artwork we do not own.
   Because the ground under these is white, the type has to go back to dark. The
   card rebinds --ink to white, so these two rules opt out of that on purpose. */
.res-carriers a {
  display: block; padding: 12px 14px; border: 1px solid rgba(0, 59, 92, .16); border-radius: 10px;
  text-decoration: none; background: #fff; height: 100%;
}
.res-carriers a:hover { border-color: var(--sky); }
.res-carriers img { display: block; height: 26px; width: auto; max-width: 130px; object-fit: contain; object-position: left center; margin-bottom: 8px; }
.rc-name { display: block; font-size: .88rem; font-weight: 650; color: #16181d; }
/* Darker than the site's --muted, which measured 3.62:1 at this size on white
   and had been under the line since these tiles were first drawn. */
.rc-type { display: block; font-size: .76rem; color: #666d80; margin-top: 1px; }

/* The copy under the first of the two quote buttons. It exists to say the
   carrier list is still coming, so the button does not read as the only way
   forward from here. */
.res-cta-note { font-size: .82rem; color: var(--muted); text-align: center; margin: 8px 0 0; }

.res-next { margin-top: 24px; padding-top: 22px; border-top: 1px solid var(--line); }
.res-next h4 { margin-top: 0; }
.res-next p { font-size: .93rem; line-height: 1.6; color: var(--ink-2); margin: 0 0 16px; }

/* The official quote form. Same card, opened underneath the results rather
   than replacing them, so the numbers they are reacting to stay on screen. */
.request-form { margin-top: 26px; padding-top: 24px; border-top: 2px solid var(--accent-soft); }
.request-form h3 { margin: 0 0 6px; font-size: 1.2rem; letter-spacing: -.015em; color: var(--ink); }
.req-echo { font-size: .86rem; line-height: 1.55; color: var(--ink-2); background: var(--accent-soft); border-radius: 8px; padding: 11px 13px; margin: 4px 0 16px; }
.req-echo:empty { display: none; }
.req-done { text-align: left; }
.req-done h3 { margin-bottom: 8px; }
.req-done p { font-size: .95rem; line-height: 1.6; color: var(--ink-2); margin: 0; }

/* -------------------------------------------------------------- cta bar */
.cta-bar {
  /* Same gutter floor as .wrap. This one sets its own width rather than living
     inside a .wrap, so without this it hugs the window edge on the scaled
     monitor while everything above it does not. */
  width: min(var(--wrap), 100% - 2 * var(--gutter));
  margin: 42px auto; padding: 22px 26px;
  background: linear-gradient(120deg, var(--brand-deep), var(--brand));
  border-radius: 16px; color: #fff;
  display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap;
}
.cta-bar p { margin: 0; font-size: 1rem; font-weight: 500; }

/* --------------------------------------------------------------- footer */
.site-foot { background: var(--ink); color: #b8c8d6; margin-top: 50px; padding: 38px 0 22px; font-size: .89rem; }
.foot-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 34px; }
/* Grid tracks size to their longest word by default, and the contact column
   holds an email address with no break point. Without these the footer pushes
   the whole page sideways on a phone. */
.foot-col { min-width: 0; }
.foot-col a { overflow-wrap: anywhere; }
.foot-col h3 { color: #fff; font-size: .82rem; text-transform: uppercase; letter-spacing: .08em; margin: 0 0 12px; }
.foot-col a { display: block; color: #b8c8d6; text-decoration: none; margin-bottom: 8px; }
.foot-col a:hover { color: var(--accent); }
.foot-logo { display: block; width: 210px; max-width: 100%; height: auto; margin-bottom: 14px; }
.foot-brand p { margin: 0 0 10px; line-height: 1.6; }
.foot-parent { color: #8ea3b5; font-size: .86rem; }
.foot-legal { border-top: 1px solid rgba(255,255,255,.1); margin-top: 34px; padding-top: 20px; color: #8ea3b5; font-size: .82rem; }
.foot-legal p { margin: 0 0 6px; }

/* ------------------------------------------------------------ responsive */
@media (max-width: 900px) {
  .foot-grid { grid-template-columns: 1fr 1fr; }
  .split { grid-template-columns: 1fr; gap: 6px; }
  .two-col { columns: 1; }
}
@media (max-width: 760px) {
  body { font-size: 16px; }
  /* Has to track .head-inner's height or the drawer floats or overlaps. */
  .site-nav {
    display: none; position: absolute; top: 60px; left: 0; right: 0;
    background: #fff; border-bottom: 1px solid var(--line); flex-direction: column;
    /* Matches .wrap's gutter, so the drawer's links line up with the logo
       above them rather than sitting 4px inside it. */
    gap: 0; padding: 8px 24px 16px;
  }
  body.nav-open .site-nav { display: flex; }
  .site-nav a { padding: 11px 0; border-bottom: 1px solid var(--line); }
  .nav-toggle { display: block; margin-left: auto; }
  .head-cta { display: none; }
  .brand-logo { height: 40px; }
  .field-row.two { grid-template-columns: 1fr; }
  .hero { padding: 36px 0 34px; }
  .hero-stats { gap: 24px; }
  .form-card, .checker { padding: 20px; }
  /* Stacked, with the action on top. Side by side, Back takes 90px of a 285px
     row and the primary gets 160px, which is not enough for a label that names
     the address: "Check 1908 Ingersoll Ave" wrapped to two lines. Full width
     fits it, and a primary above a secondary is the right order on a phone
     anyway. */
  .step-nav { flex-direction: column-reverse; gap: 8px; }
  .step-nav .btn { width: 100%; }
  .cta-bar { flex-direction: column; align-items: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* --------------------------------------------------------------- thanks */
.thanks-card { border: 1px solid var(--line); border-radius: 16px; padding: 26px; background: var(--bg-soft); }
.thanks-card h2 { margin: 0 0 16px; font-size: 1.28rem; letter-spacing: -.015em; }
.thanks-tick {
  width: 40px; height: 40px; border-radius: 50%; background: var(--signal); color: #052b14;
  display: flex; align-items: center; justify-content: center; font-size: 1.25rem; font-weight: 700;
  margin: 0 0 16px;
}
.thanks-card .steps li { margin-bottom: 14px; }

/* --------------------------------------------- product explainer pop-out */
/* A <details> styled as a small button under the field, with a panel that pops
   out over the form. No script, so it still opens if JavaScript is blocked. */
.field > .field-label { display: block; font-size: .8rem; font-weight: 600; margin-bottom: 5px; color: var(--ink-2); }
.field-explained { position: relative; }

.explainer { display: inline-block; margin-top: 8px; }
.explainer > summary {
  list-style: none; cursor: pointer; user-select: none;
  font-size: .76rem; font-weight: 700; color: var(--brand);
  border: 1px solid var(--line); border-radius: 999px; padding: 4px 11px; white-space: nowrap;
}
.explainer > summary::-webkit-details-marker { display: none; }
.explainer > summary::before { content: "? "; font-weight: 800; opacity: .55; }
.explainer > summary:hover { border-color: var(--brand); background: var(--accent-soft); }
.explainer > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.explainer[open] > summary { background: var(--brand); color: #fff; border-color: var(--brand); }

/* The pill itself. --brand is navy and is deliberately NOT rebound by .checker,
   so on the dark card the closed label was navy on navy at 1:1 and all anybody
   saw was an empty ring. Open used the same navy as a fill, which was no clearer.
   On the dark card the label takes the sky accent, and open inverts to a solid
   sky pill so the active state still reads as pressed. */
.checker .explainer > summary { color: var(--sky); border-color: rgba(230, 239, 245, .34); }
.checker .explainer > summary:hover { background: rgba(127, 212, 240, .14); border-color: var(--sky); }
.checker .explainer > summary:focus-visible { outline-color: var(--sky); }
.checker .explainer[open] > summary { background: var(--sky); color: #00263c; border-color: var(--sky); }

.ex-pop {
  position: absolute; z-index: 30; right: 0; top: calc(100% + 10px); width: min(560px, 84vw);
  background: #fff; border: 1px solid var(--line); border-radius: 14px;
  padding: 20px; box-shadow: var(--shadow-lg);
}
/* Beside the card, not on top of it. In the split hero the form sits in the
   right hand column, so the panel opens leftward across the headline, which is
   the only direction with room and the only one that leaves the form visible.
   Anchoring to the card rather than to the field is what makes it clear the
   whole card instead of just the field it was opened from. */
.hero-aside .checker { position: relative; }
.hero-aside .field-explained { position: static; }
.hero-aside .ex-pop { right: calc(100% + 20px); left: auto; top: 20px; width: min(520px, 42vw); }

/* The panel stays a white card even inside the dark checker, because it is a
   dense two column comparison and a translucent one over an animated hero is
   unreadable. But .checker rebinds --ink, --ink-2, --muted and --line to pale
   blues for its own text, and every one of those lands on this white ground at
   about 1.1:1, which is to say invisible. So the panel puts the light values
   back for its own subtree, in one place rather than per rule. Same fix as the
   address suggestion dropdown, same reason. */
.checker .ex-pop {
  --ink: #16181d;
  --ink-2: #4b5160;
  --muted: #6a7183;
  --line: #e6e4df;
  --accent-soft: #e5edf2;
  --surface: #ffffff;
  color: var(--ink);
}

.ex-close {
  position: absolute; top: 8px; right: 10px; width: 30px; height: 30px;
  border: 0; border-radius: 8px; background: transparent; color: var(--muted);
  font-size: 1.4rem; line-height: 1; cursor: pointer;
}
.ex-close:hover { background: var(--accent-soft); color: var(--ink); }
.ex-close:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* Both columns are the same shape, so the prices should sit on the same line
   however many words a bullet runs to. Pushing the price down with auto margin
   does that without guessing at heights. */
.ex-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: stretch; }
.ex-side { display: flex; flex-direction: column; }
.ex-side ul { flex: 1 1 auto; }
.ex-side .ex-price { margin-top: auto; }
.ex-side h4 { margin: 0 0 2px; font-size: .98rem; }
/* One column's subtitle wraps to two lines and the other's does not, which
   started both bullet lists at different heights. */
.ex-note { margin: 0 0 10px; font-size: .8rem; line-height: 1.45; color: var(--muted); min-height: 2.9em; }
.ex-side ul { list-style: none; padding: 0; margin: 0 0 14px; }
.ex-side li { position: relative; padding-left: 18px; margin-bottom: 8px; font-size: .84rem; line-height: 1.45; color: var(--ink-2); }
/* Ticks read as endorsements, so only the dedicated column gets them. The
   broadband column takes plain bullets, because half of what it lists is a
   limitation rather than a feature. */
.ex-ticks li::before {
  content: ""; position: absolute; left: 2px; top: .5em; width: 5px; height: 9px;
  border-right: 2px solid var(--signal); border-bottom: 2px solid var(--signal); transform: rotate(42deg);
}
.ex-plain li::before {
  content: ""; position: absolute; left: 3px; top: .62em; width: 5px; height: 5px;
  border-radius: 50%; background: var(--muted);
}
.ex-price { margin: 0; padding-top: 12px; border-top: 1px solid var(--line); }
.ex-price strong { display: block; font-size: 1.05rem; color: var(--brand); letter-spacing: -.01em; }
.ex-price span { display: block; margin-top: 2px; font-size: .74rem; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.ex-fine { margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--line); font-size: .76rem; line-height: 1.5; color: var(--muted); }
.ex-more { margin: 10px 0 0; font-size: .82rem; font-weight: 600; }

/* Below this width the floating panel would hang off the left of the card, so
   it drops into the flow and pushes the form down instead. */
@media (max-width: 900px) {
  .ex-pop, .hero-aside .ex-pop { position: static; width: auto; margin-top: 10px; }
  /* In the flow the panel is only as wide as its half of the field row, which
     is too narrow for two columns of bullets. */
  .ex-grid { grid-template-columns: 1fr; gap: 18px; }
  /* Stacked, the columns cannot be out of line with each other, so the
     reserved space is just dead space. */
  .ex-note { min-height: 0; }
  .ex-side .ex-price { margin-top: 0; }
}
