/* --- Start-here console ----------------------------------------------------
   The homepage leads with the address check. The service cards below route
   visitors to each line of business without repeating them in a carousel. */
.hero {
    background: linear-gradient(140deg, var(--blue-deep) 0%, var(--blue-dark) 100%);
    color: var(--npt-white);
}

/* Sized by the art, not the viewport: every desktop banner is 8:3 and every
   mobile one 4:5, so matching that ratio shows the whole image at any width.
   (A viewport-height box cropped the sides — ~44% of the width on a 1080px
   portrait monitor.) */
.hero-carousel { position: relative; aspect-ratio: 8 / 3; overflow: hidden; border-bottom: 4px solid var(--blue-deep); }
.hero-slide {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    opacity: 0;
    pointer-events: none;
    text-decoration: none;
    color: inherit;
    transition: opacity 1s ease;
}
.hero-slide[aria-hidden="false"] { pointer-events: auto; }
.hero-slide:first-child { opacity: 1; }
.hero-slide-name {
    width: min(1180px, 90%);
    margin: 0 auto;
    padding-bottom: clamp(28px, 4vw, 48px);
    font-family: var(--font-heading);
    font-size: clamp(2rem, 5vw, 3.75rem);
    font-weight: 800;
    letter-spacing: -.02em;
    line-height: 1;
}
.hero-slide--cfn { background: var(--cfn) url('../images/banner/outdoor-eero-7-web.webp') center / cover no-repeat; }
.hero-slide--cfn-residential { background: #fff url('../images/banner/cfn-residential-web.webp') center / cover no-repeat; }
.hero-slide--qc { background: var(--qc) url('../images/banner/quality-cablevision-web.webp') center / cover no-repeat; }
.hero-slide--simplify { background: #fff url('../images/banner/simplify tech help-07.webp') center / cover no-repeat; }
.hero-slide--apg { background: #fff url('../images/banner/grandstream_web.webp') center / cover no-repeat; }
.hero-slide--cfn .hero-slide-name,
.hero-slide--cfn-residential .hero-slide-name,
.hero-slide--qc .hero-slide-name,
.hero-slide--simplify .hero-slide-name,
.hero-slide--apg .hero-slide-name { display: none; }

.hero-carousel-nav { position: absolute; right: clamp(18px, 3vw, 40px); bottom: clamp(18px, 3vw, 32px); z-index: 1; display: flex; gap: 8px; }
.hero-carousel-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid rgba(255, 255, 255, .55);
    border-radius: var(--radius-pill);
    background: rgba(20, 20, 20, .3);
    color: #fff;
    cursor: pointer;
    transition: background .2s ease, border-color .2s ease;
}
.hero-carousel-btn:hover { background: rgba(20, 20, 20, .55); border-color: #fff; }
.hero-carousel-btn:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.hero-carousel-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

@media (max-width: 640px) {
    .hero-slide--cfn { background-image: url('../images/banner/outdoor_eero_mobile.webp'); }
    .hero-slide--cfn-residential { background-image: url('../images/banner/cfn-residential-mobile.webp'); }
    .hero-slide--qc { background-image: url('../images/banner/qc_mobile.webp'); }
    .hero-slide--simplify { background-image: url('../images/banner/simplify tech help-08.webp'); }
    .hero-slide--apg { background-image: url('../images/banner/grandstream_mobile.webp'); }
    .hero-carousel { aspect-ratio: 4 / 5; }
    .hero-slide { align-items: center; justify-content: center; text-align: center; }
    .hero-slide-name { padding-bottom: 0; font-size: clamp(1.5rem, 7vw, 2.1rem); }
    .hero-carousel-nav { right: 0; left: 0; bottom: 14px; justify-content: center; }
    .hero-carousel-btn { width: 38px; height: 38px; }
}

/* eero sits behind everything as a big, quiet background piece; the search
   copy stacks on top of it, and the field itself is stretched wide enough
   that its solid white pill sits over part of the photo where they meet —
   that overlap is intentional, not an artifact to avoid. */
.hero-search-row { position: relative; }
/* Anchored to the section's bottom edge and pushed past it, so the router
   hangs over the blue band's lower edge into the mosaic below. The image
   has ~12% transparent padding under the device, hence the extra offset. */
.hero-bg-media {
    position: absolute;
    right: clamp(-30px, -2vw, 10px);
    bottom: calc(-1 * var(--section-y) - clamp(0px, 9vw - 70px, 80px));
    z-index: 0;
    width: clamp(340px, 38vw, 680px);
    height: auto;
    pointer-events: none;
}
.hero-search-copy { position: relative; z-index: 1; }

/* The page's h1 lives here, on the tool, rather than in a band of its own:
   one heading carries both the search phrase and the task. The section sits
   on brand blue and stacks above the mosaic so the eero can overlap it. */
.availability-section {
    position: relative;
    z-index: 1;
    padding: var(--section-y) 0;
    background: var(--blue);
    color: var(--card);
    scroll-margin-top: 100px;
}
.availability-heading {
    max-width: 22ch;
    color: var(--card);
    font-size: clamp(1.75rem, 3.4vw, 2.7rem);
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -.02em;
}
/* Second sentence stays solid white and steps down in weight instead of
   colour; a little air above it is the only separator. */
.availability-heading span { display: block; margin-top: .3em; font-weight: 500; }

/* Address check — the lead action, stretched to be the widest thing here */
.hero-availability { margin-top: clamp(24px, 3.5vw, 34px); max-width: min(920px, 100%); }
.availability-label {
    display: block;
    margin-bottom: 8px;
    font-family: var(--font-heading);
    font-size: .8rem;
    font-weight: 700;
    color: var(--on-dark);
}
.availability-field {
    display: flex;
    gap: 6px;
    padding: 6px;
    background: var(--card);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-sm);
    transition: box-shadow .18s ease;
}
/* A blue focus ring would vanish on the blue band; go dark-on-white instead. */
.availability-field:focus-within { box-shadow: 0 0 0 3px var(--card), 0 0 0 6px var(--ink); }
.availability-input {
    flex: 1;
    min-width: 0;
    padding: 0 8px 0 16px;
    border: 0;
    background: none;
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 1rem;
}
.availability-input:focus { outline: none; }
.availability-input::placeholder { color: var(--ink-soft); }
.availability-submit {
    flex: none;
    min-height: 48px;
    padding: 0 24px;
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--ink);
    color: var(--paper);
    font-family: var(--font-heading);
    font-size: .82rem;
    font-weight: 700;
    cursor: pointer;
    transition: background .18s ease;
}
.availability-submit::after { content: '\203A'; margin-left: 8px; }
.availability-submit:hover { background: var(--blue); }

/* Error sits above the field (GOV.UK pattern). Red text fails on the blue
   band, so it's white and bold with a white rule marking it instead. */
.availability-error {
    margin-bottom: 10px;
    padding-left: 12px;
    border-left: 4px solid var(--card);
    color: var(--card);
    font-weight: 700;
}

/* Suggestions drop below the field as a plain white list — the one place a
   dropdown shadow is allowed. */
.availability-form { position: relative; }
.availability-suggest {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 5;
    overflow: hidden;
    background: var(--card);
    border: 1px solid var(--rule);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
}
.availability-suggest[hidden] { display: none; }
.availability-suggestions { margin: 0; padding: 0; list-style: none; }
.availability-suggestion {
    display: flex;
    align-items: center;
    min-height: 48px;
    padding: 10px 18px;
    border-bottom: 1px solid var(--rule);
    color: var(--ink);
    cursor: pointer;
    transition: background-color .15s ease;
}
.availability-suggestion:hover,
.availability-suggestion[aria-selected="true"] { background: var(--surface); }
.availability-suggestion[aria-selected="true"] { box-shadow: inset 4px 0 0 var(--blue); }
/* Loading rows: same height as a real suggestion so nothing shifts when
   results replace them. A slow opacity pulse, not a sweeping shimmer. */
.availability-suggestion--loading { cursor: default; }
.availability-suggestion--loading:hover { background: none; }
.availability-skeleton {
    display: block;
    height: 12px;
    border-radius: var(--radius-sm);
    background: var(--paper);
    animation: availability-pulse 1.2s ease-in-out infinite;
}
.availability-suggestion--loading:nth-child(2) .availability-skeleton { animation-delay: .15s; }
.availability-suggestion--loading:nth-child(3) .availability-skeleton { animation-delay: .3s; }
@keyframes availability-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .45; }
}
.availability-attribution { padding: 8px 18px; color: var(--ink-soft); font-size: .75rem; }

@media (prefers-reduced-motion: reduce) {
    .availability-suggestion { transition: none; }
    .availability-skeleton { animation: none; opacity: .7; }
}

@media (max-width: 720px) {
    .hero-bg-media { display: none; }
}
@media (max-width: 440px) {
    .availability-field { flex-direction: column; border-radius: var(--radius-lg); }
    .availability-input { padding: 12px 14px; }
    .availability-submit { width: 100%; }
}
@media (max-width: 440px) {
    .availability-field { flex-direction: column; border-radius: var(--radius-lg); }
    .availability-input { padding: 12px 14px; }
    .availability-submit { width: 100%; }
}


/* --- Service mosaic (intuit.com/products/ collage treatment) -------------
   Five distinct sizes — tall, wide, two small, one full-width banner —
   framed around the specific services people ask for, not just the company
   names. Each card gradients from the standard brand colour into a lighter
   same-hue variant (communityfiber.net does this for its own hero
   lettering — brand green into a lighter green, not a fade to white).
   Dark ink text doesn't hold AA across that whole range (fine at the light
   end, ~4:1 at the saturated end, worse depending on exactly where text
   lands), so the copy sits on its own near-white backing chip
   (.service-card-copy) rather than floating directly on the gradient — the
   "Photo idea" tag is already its own white pill for the same reason.
   No real photography yet: each card names the photo it needs instead of
   showing a generic gray box, so it's obvious what to source. Swap a
   card's background for a real photo (same pattern as the hero banners)
   once one exists, and the tag/chip can go. */
/* A cool tint separates the service router from the dark fiber-availability
   console above it and ends before the heritage section. */
.service-mosaic { padding: var(--section-y) 0; background: var(--surface); }
.service-mosaic h2 { font-size: clamp(1.9rem, 3vw, 2.7rem); font-weight: 700; }
.service-mosaic-note { max-width: 640px; margin-top: 12px; color: var(--ink-soft); font-size: 1.05rem; line-height: 1.6; }
.service-mosaic-grid {
    margin-top: 34px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: clamp(170px, 18vw, 220px) clamp(170px, 18vw, 220px) minmax(clamp(120px, 12vw, 150px), auto);
    gap: clamp(12px, 1.6vw, 18px);
}
.service-card--home { grid-column: 1 / 2; grid-row: 1 / 3; }
.service-card--business { grid-column: 2 / 4; grid-row: 1 / 2; }
/* The phone product shot is square, not landscape — it sits in a small
   squarish cell instead of the wide banner (a square image cover-cropped
   into a very wide short strip would lose the handset off one side). The
   still-placeholder cable/IT cards take the wide banner and the other
   small cell instead, since a solid gradient doesn't care about aspect
   ratio. */
.service-card--phone { grid-column: 2 / 3; grid-row: 2 / 3; }
.service-card--cable { grid-column: 3 / 4; grid-row: 2 / 3; }
.service-card--it { grid-column: 1 / 4; grid-row: 3 / 4; }

.service-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: clamp(18px, 2.2vw, 24px);
    border-radius: var(--radius-lg);
    overflow: hidden;
    text-decoration: none;
    color: var(--ink);
    box-shadow: var(--shadow-sm);
    transition: box-shadow .25s var(--ease), transform .2s var(--ease);
}
.service-card:hover, .service-card:focus-visible { transform: translateY(-2px); box-shadow: var(--shadow-card); }
.service-card--home, .service-card--business { background: linear-gradient(45deg, var(--cfn) 0%, var(--cfn-light) 100%); }
.service-card--cable { background: linear-gradient(45deg, var(--qc) 0%, var(--qc-light) 100%); }
.service-card--phone { background: linear-gradient(45deg, var(--apg) 0%, var(--apg-light) 100%); }
/* Real photo instead of the gradient: full-bleed image behind everything.
   The phone product shot has its background removed (real transparency),
   so it sits directly on the card's own brand gradient — "contain" so the
   whole phone stays in frame instead of being cropped like the two
   environmental photos, which fill the frame with "cover" as normal. */
.service-card-photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}
.service-card--phone .service-card-photo { object-fit: contain; padding: 3%; }
/* One layer doing two jobs: a brand-colour flare top-left (so the photo
   cards still carry their company's colour, not just a neutral scrim) and
   a dark wash at the bottom where the white copy sits, for legibility
   regardless of what's in the shot. */
.service-card.has-photo::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    background:
        linear-gradient(160deg, var(--flare-color, transparent) 0%, transparent 55%),
        linear-gradient(0deg, rgba(20, 20, 20, .72) 0%, rgba(20, 20, 20, 0) 55%);
}
.service-card--home.has-photo::after, .service-card--business.has-photo::after { --flare-color: var(--cfn-flare); }
.service-card--phone.has-photo::after { --flare-color: var(--apg-flare); }
.service-card--cable.has-photo::after { --flare-color: var(--qc-flare); }

/* The IT card: SimplifyTech's device lineup. The product shots are
   cut out (transparent), so they sit straight on a light gray card instead
   of over the green gradient — text left, devices right on desktop;
   devices above the text on mobile. The headline carries Simplify's own
   blue → teal → green wordmark gradient (.text-gradient-simplify). */
.service-card--it {
    display: grid;
    grid-template-columns: minmax(300px, 36%) 1fr;
    align-items: center;
    gap: clamp(16px, 2vw, 28px);
    background: var(--paper);
}
.service-card--it .service-card-copy { margin-top: 0; }
.service-card--it .service-card-headline { color: var(--blue); text-shadow: none; }
.service-card--it .service-card-desc { color: var(--ink-soft); text-shadow: none; }
.service-card-devices { display: block; order: 2; height: 100%; min-width: 0; }
.service-card-devices img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: right center; }

@media (max-width: 780px) {
    .service-card--it { grid-template-columns: 1fr; align-items: start; }
    .service-card-devices { order: 0; height: auto; }
    .service-card-devices img { height: auto; }
}

.service-card-tag {
    padding: 6px 14px;
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, .9);
    color: var(--ink-soft);
    font-family: var(--font-heading);
    font-size: .72rem;
    font-weight: 700;
    line-height: 1.3;
}
/* pushes the copy to the bottom of the card, leaving the space above it —
   where the real photo will sit — visibly empty. White text straight on
   the gradient, same as communityfiber.net's own card; the text-shadow
   does the legibility work the way their heavy display weight does. */
.service-card-copy { position: relative; z-index: 1; margin-top: auto; }
.service-card-headline {
    display: block;
    font-family: var(--font-heading);
    font-size: 1.1rem;
    font-weight: 800;
    line-height: 1.2;
    color: var(--paper);
    text-shadow: 0 1px 3px rgba(20, 20, 20, .35);
}
.service-card-desc {
    display: block;
    margin-top: 6px;
    color: rgba(242, 242, 242, .95);
    font-size: .92rem;
    line-height: 1.45;
    text-shadow: 0 1px 3px rgba(20, 20, 20, .3);
}

@media (max-width: 780px) {
    .service-mosaic-grid { grid-template-columns: 1fr; grid-template-rows: none; }
    .service-card--home, .service-card--business, .service-card--cable, .service-card--it, .service-card--phone {
        grid-column: auto;
        grid-row: auto;
        min-height: 200px;
    }
}

/* SmartHub account access, directly after the service mosaic. Built as the
   same contained panel as the history and numbers blocks below it: white copy
   side, a flat blue plate carrying the phone, which sits whole inside it
   rather than bleeding off the edge. */
.bill-pay-section { padding: var(--section-y) 0 0; }
.bill-pay-panel { width: min(1300px, 92%); display: grid; grid-template-columns: 1.1fr .9fr; align-items: stretch; background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius-xl); box-shadow: var(--shadow-card); overflow: hidden; }
.bill-pay-copy { display: flex; flex-direction: column; justify-content: center; padding: clamp(40px, 5.5vw, 84px); }
.bill-pay-copy h2 { margin-bottom: 22px; font-size: clamp(2.25rem, 3.7vw, 3.5rem); font-weight: 700; }
.bill-pay-copy > p { max-width: 560px; color: var(--ink-soft); font-size: 1.08rem; }
.bill-pay-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 22px 32px; margin-top: 34px; }
.bill-pay-quick { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin: 0; }
.bill-pay-quick span { color: var(--ink-soft); font-size: .9rem; }
.bill-pay-visual { display: flex; align-items: center; justify-content: center; padding: clamp(36px, 4vw, 56px) 24px; background: var(--blue); }
.bill-pay-visual img { display: block; width: auto; height: clamp(360px, 34vw, 470px); max-width: 100%; object-fit: contain; }
#bill-pay-title { scroll-margin-top: 110px; }

@media (max-width: 860px) {
    .bill-pay-panel { grid-template-columns: 1fr; }
    .bill-pay-visual { padding: 36px 24px; }
    .bill-pay-visual img { height: 340px; }
}

@media (max-width: 480px) {
    .bill-pay-actions .btn-action { width: 100%; }
}

/* A New Paris street photograph from the company's telephone era sits against
   a black copy panel — a single contained, rounded panel, matching the
   operating companies' feature-panel style. */
.heritage-section {
    display: grid;
    grid-template-columns: .88fr 1.12fr;
    align-items: stretch;
    min-height: 600px;
    width: min(1300px, 92%);
    margin: var(--section-y) auto 0;
    background: #000;
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-card);
    overflow: hidden;
}
.heritage-copy { display: flex; flex-direction: column; justify-content: center; padding: clamp(44px, 5.5vw, 84px); color: var(--npt-white); }
.heritage-copy h2 { color: var(--npt-white); font-size: clamp(2.25rem, 3.7vw, 3.5rem); font-weight: 700; }
.heritage-copy p { max-width: 600px; margin: 30px 0; color: var(--on-dark); font-size: 1.08rem; }
.heritage-copy .text-link { align-self: flex-start; color: var(--npt-white); }
.heritage-section > img { width: 100%; height: 100%; min-height: clamp(320px, 40vw, 640px); object-fit: cover; object-position: center; background: #000; }

.numbers-section { padding: clamp(52px, 7vw, 92px) 0; background: transparent; }
.numbers-grid {
    display: grid;
    grid-template-columns: repeat(3,1fr);
    padding: clamp(44px, 5.5vw, 68px) clamp(30px, 4vw, 56px);
    background: var(--blue);
    color: var(--npt-white);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-card);
}
.numbers-item { padding: 0 clamp(20px, 3vw, 44px); border-left: 1px solid rgba(255,255,255,.35); }
.numbers-item:first-child { border-left: 0; }
.numbers-grid strong { display: block; font-family: var(--font-heading); font-size: clamp(2.8rem, 4.8vw, 4.5rem); font-weight: 700; line-height: 1; }
.numbers-label { display: block; margin-top: 12px; font-size: .95rem; }

.shareholder-grid { display: grid; grid-template-columns: 1.12fr .88fr; gap: 11%; align-items: start; }
.shareholder-grid h2 { max-width: 690px; font-size: clamp(2.25rem, 3.8vw, 3.55rem); font-weight: 700; }
.shareholder-grid > div { padding-top: 12px; }

.shareholder-section { padding: var(--section-y) 0; background: var(--dark); color: var(--npt-white); }
.shareholder-grid h2 { color: var(--npt-white); }
.shareholder-grid p { margin-bottom: 28px; color: var(--on-dark); font-size: 1.08rem; }
.shareholder-link { display: inline-block; padding-bottom: 6px; color: var(--npt-white); border-bottom: 1px solid var(--npt-white); font-family: var(--font-heading); font-size: .86rem; font-weight: 700; text-decoration: none; }
.shareholder-link::after { content: '\203A'; margin-left: 14px; }


@media (max-width: 900px) {
    .shareholder-grid { grid-template-columns: 1fr; gap: 42px; }
    .heritage-section { grid-template-columns: 1fr; }
    .heritage-copy { min-height: 580px; }
    .heritage-section > img { min-height: 440px; }
}

@media (max-width: 700px) {
    .numbers-grid { grid-template-columns: 1fr; gap: 34px; }
    .numbers-item { padding: 0 0 34px; border-left: 0; border-bottom: 1px solid rgba(255,255,255,.35); }
    .numbers-item:last-child { padding-bottom: 0; border-bottom: 0; }
}


/* --- Contact band -------------------------------------------------------
   Closes the page with the three things people phone about. Same ledger
   vocabulary as the numbers band; the brand rule sits on top of it. */
.contact-band { background: var(--surface); }
.contact-band > .section-shell { padding: var(--section-y) 0; }

.contact-band h2 {
    margin-bottom: 40px;
    font-size: clamp(1.9rem, 3vw, 2.8rem);
    font-weight: 700;
}

.contact-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    margin: 0;
    border-top: 1px solid var(--rule);
}

.contact-row > div {
    padding: 30px 34px 30px 0;
    border-bottom: 1px solid var(--rule);
}

.contact-row > div + div {
    padding-left: 34px;
    border-left: 1px solid var(--rule);
}

.contact-row dt {
    margin-bottom: 12px;
    color: var(--ink-soft);
    font-family: var(--font-heading);
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
}

.contact-row dd {
    margin: 0;
    font-family: var(--font-heading);
    font-size: clamp(1.3rem, 2.1vw, 1.75rem);
    font-weight: 700;
    line-height: 1.25;
}

.contact-row dd a { color: var(--ink); text-decoration: none; }
.contact-row dd a:hover { color: var(--blue); }

.contact-hours { font-size: clamp(1.05rem, 1.5vw, 1.25rem); }

@media (max-width: 820px) {
    .contact-row { grid-template-columns: 1fr; }
    .contact-row > div,
    .contact-row > div + div {
        padding: 24px 0;
        border-left: 0;
    }
}

@media (max-width: 900px) {
    .heritage-section { grid-template-columns: 1fr; }
    .heritage-section > img { height: clamp(240px, 52vw, 460px); }
}
