/* Northline Heating & Air, direction D: Tesla-style, dark and premium (the owner, 22 Oct).
   23 Oct, studio pass (the owner: "like Tesla, so clean"): one type family (Instrument Sans, 600 and 400), the real logo, a short menu,
   list-and-picture sections with a thin line on the active item, the care plan on a full photo, the app as tabs.
   One full screen on top (the house video). Then What We Do as one pinned section (names left, one large picture right),
   the cut-away as one band (summer turns to winter), Our Work, Care, the app, reviews and the form.
   Dark graphite and near-black by default, logo blue the one action colour. Each section can switch to Dark, Light
   or Logo Blue with the preview control (mock-controls.css holds the three themes).
   4 text sizes: --s1 headlines, --s2 section titles and readouts, --s3 lead lines, --s4 text and buttons. */

@font-face { font-family: "Bricolage Grotesque"; src: url("assets/fonts/bricolage-latin.woff2") format("woff2"); font-weight: 200 800; font-style: normal; font-display: swap; }
@font-face { font-family: "Instrument Sans"; src: url("assets/fonts/instrument-sans-latin.woff2") format("woff2"); font-weight: 400 700; font-style: normal; font-display: swap; }

:root {
  --ink: #0B1117;            /* the page: near-black */
  --ink-2: #121A22;          /* graphite: raised sections, the estimate band */
  --ink-3: #18222C;          /* cards, menu */
  --stone: #F2F1EE;          /* text, 14:1 or more */
  --line: rgba(242, 241, 238, .14);
  --line-strong: rgba(242, 241, 238, .42);
  --muted: #A9B3BB;          /* second text, 7.5:1 or more */
  --accent: #22709F;         /* logo blue button, white on it 5.4:1 */
  --on-accent: #FFFFFF;
  --accent-text: #9CC4E2;    /* 8.7:1 or more */
  --night: #0B1117;
  --error: #FF9C8F;

  --display: "Instrument Sans", "Segoe UI", system-ui, sans-serif;
  --text: "Instrument Sans", "Segoe UI", system-ui, sans-serif;
  --s1: 56px; --s2: 36px; --s3: 20px; --s4: 16px;
  --pad: 48px; --gap: 32px; --section: 128px; --head-h: 72px;
  --ease: cubic-bezier(.2, .7, .2, 1);
}
@media (max-width: 760px) {
  :root { --s1: 40px; --s2: 28px; --s3: 18px; --pad: 24px; --gap: 16px; --section: 88px; --head-h: 64px; }
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; background: var(--ink); scroll-padding-top: var(--head-h); }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body { margin: 0; background: var(--ink); color: var(--stone); font: 400 var(--s4)/1.6 var(--text); -webkit-font-smoothing: antialiased; }
img, video, svg, picture { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, h3, p, ul, figure, blockquote { margin: 0; padding: 0; }
ul { list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3 { font-family: var(--display); }
h1, h2 { font-size: var(--s1); line-height: 1.08; font-weight: 600; letter-spacing: -.025em; text-wrap: balance; }
h3 { font-size: var(--s3); line-height: 1.3; font-weight: 600; }
svg { width: 20px; height: 20px; flex: none; }
.skip { position: absolute; left: 16px; top: -80px; background: var(--ink-3); color: var(--stone); padding: 8px 16px; z-index: 100; }
.skip:focus { top: 16px; }
:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 3px; }
.note { display: none; }
html.notes .note { display: inline-block; background: #FFE58A; color: #13212C; padding: 0 8px; }

/* Buttons: Tesla's wide, calm pair. 48 px tall, 4 px corners. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 48px; padding: 0 32px; border-radius: 4px; border: 1px solid transparent; font: 600 var(--s4)/1 var(--text); text-decoration: none; white-space: nowrap; cursor: pointer; transition: background-color .2s, border-color .2s, color .2s; }
.btn-sm { height: 44px; padding: 0 20px; }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { background: color-mix(in srgb, var(--accent) 86%, #000); }
.btn-light { background: rgba(255, 255, 255, .92); color: #12181E; }
.btn-light:hover { background: #fff; }
.btn-line { border-color: var(--line-strong); background: transparent; color: var(--stone); }
.btn-line:hover { border-color: var(--stone); }
.btn svg { width: 18px; height: 18px; }
.phone-only { display: none; }
@media (max-width: 760px) { .phone-only { display: inline; } .wide-only { display: none; } }

/* ---------- Header: white over the pictures, solid once you scroll ---------- */
.site-head { position: fixed; top: 0; left: 0; right: 0; z-index: 50; color: #fff; transition: background-color .3s, color .3s, box-shadow .3s; }
.site-head.solid, body.page .site-head, .site-head.open-mega { background: color-mix(in srgb, var(--ink) 94%, transparent); color: var(--stone); box-shadow: 0 1px 0 var(--line); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.head-row { display: flex; align-items: center; gap: 32px; height: var(--head-h); padding: 0 var(--pad); max-width: 1600px; margin: 0 auto; position: relative; }
.wordmark { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; }
.wordmark img { height: 34px; width: auto; }   /* 23 Oct: the real logo, white, like Tesla's logotype */
@media (max-width: 760px) { .wordmark img { height: 28px; } }
.nav { display: flex; align-items: center; gap: 4px; margin: 0 auto; }
.nav-link { display: inline-flex; align-items: center; gap: 4px; height: 44px; padding: 0 14px; border: 0; border-radius: 4px; background: none; font-weight: 500; text-decoration: none; cursor: pointer; transition: background-color .2s; }
.nav-link:hover, .mega-toggle[aria-expanded="true"] { background: rgba(128, 128, 128, .16); }
.nav-link svg { width: 16px; height: 16px; transition: transform .2s; }
.mega-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
.head-actions { display: flex; align-items: center; gap: 16px; }
.head-call { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; font-weight: 600; text-decoration: none; font-variant-numeric: tabular-nums; }
.head-call svg { width: 16px; height: 16px; }
.head-call:hover { text-decoration: underline; text-underline-offset: 6px; }
.menu-toggle { display: none; }
.home .site-head:not(.solid):not(.open-mega):not(.menu-open) .head-call, .home .site-head:not(.solid):not(.open-mega):not(.menu-open) .wordmark, .home .site-head:not(.solid):not(.open-mega):not(.menu-open) .nav-link { text-shadow: 0 1px 8px rgba(0, 0, 0, .45); }

/* Services menu: two columns in two columns, plus the company links */
.has-mega { position: static; }
.mega { position: absolute; left: 0; right: 0; top: var(--head-h); display: none; grid-template-columns: minmax(0, 400px) minmax(0, 360px) minmax(0, 280px); justify-content: center; gap: 48px; padding: 40px var(--pad) 48px; background: var(--ink-3); color: var(--stone); box-shadow: 0 1px 0 var(--line), 0 24px 40px rgba(0, 0, 0, .3); }
.mega.open { display: grid; }
.mega-head { font-weight: 700; margin-bottom: 8px; }
.mega li { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 8px; }
.mega a { display: inline-flex; align-items: center; min-height: 40px; text-decoration: none; }
.mega a:hover { text-decoration: underline; text-underline-offset: 6px; }
.tbc { margin-left: 8px; font-style: italic; }
html.notes .mega-note { display: block; margin-top: 16px; max-width: 30ch; }

@media (max-width: 900px) {
  .nav > .nav-link { display: none; }
}
@media (max-width: 960px) {
  .head-est { display: none; }
}
@media (max-width: 760px) {
  .head-row { gap: 8px; }
  .head-actions { margin-left: auto; gap: 8px; }
  .menu-toggle { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; background: none; border: 0; color: inherit; cursor: pointer; }
  .menu-toggle svg { width: 24px; height: 24px; }
  .nav { display: none; position: fixed; inset: var(--head-h) 0 0 0; margin: 0; padding: 8px var(--pad) 120px; overflow-y: auto; background: var(--ink-3); color: var(--stone); flex-direction: column; align-items: stretch; }
  .nav.open { display: flex; }
  .nav > .nav-link { display: flex; }
  .has-mega, .mega-toggle { width: 100%; }
  .nav-link { height: 52px; padding: 0; border-bottom: 1px solid var(--line); border-radius: 0; text-shadow: none !important; justify-content: space-between; }
  .nav-link:hover { background: none; }
  .mega { position: static; grid-template-columns: 1fr; gap: 24px; padding: 16px 0 24px; box-shadow: none; background: none; border-bottom: 1px solid var(--line); }
  .site-head.menu-open { background: var(--ink-3); color: var(--stone); }
}

/* ---------- Panels: one full screen each ---------- */
.panel { position: relative; height: 100vh; height: 100svh; min-height: 560px; overflow: hidden; isolation: isolate; background: var(--night); color: #fff; }
.scene { position: absolute; inset: 0; z-index: -2; transform-origin: 50% 60%; will-change: transform; }
/* A tiny blurred copy of the picture shows at once, so a screen is never empty black while its picture loads */
.scene::before { content: ""; position: absolute; inset: -48px; background: var(--ph-wide, none) center / cover no-repeat; filter: blur(24px); }
.scene img, .scene video { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; }
.scene .air { position: absolute; inset: 0; width: 100%; height: 100%; }
.top-video { opacity: 0; transition: opacity 1.2s var(--ease); }
.top-video.playing { opacity: 1; }
/* Soft dark fades top and bottom so white text passes 4.5:1 on every picture */
.shade { position: absolute; inset: 0; z-index: -1; pointer-events: none; background:
  radial-gradient(44% 22% at 50% 20%, rgba(6, 10, 14, .34) 0%, rgba(6, 10, 14, 0) 100%),
  linear-gradient(180deg, rgba(6, 10, 14, .72) 0%, rgba(6, 10, 14, .48) 24%, rgba(6, 10, 14, 0) 42%),
  linear-gradient(0deg, rgba(6, 10, 14, .62) 0%, rgba(6, 10, 14, .3) 16%, rgba(6, 10, 14, 0) 30%); }
.panel-copy { position: absolute; left: var(--pad); right: var(--pad); top: calc(var(--head-h) + 48px); text-align: center; text-shadow: 0 1px 12px rgba(0, 0, 0, .35); }
.panel-copy p { margin: 12px auto 0; font-size: var(--s3); line-height: 1.45; max-width: 48ch; }
.panel-foot { position: absolute; left: var(--pad); right: var(--pad); bottom: 88px; display: flex; justify-content: center; }
.panel-actions { display: flex; gap: 24px; justify-content: center; }
.panel-actions .btn { min-width: 248px; }
.readouts { position: absolute; right: 0; bottom: 0; display: flex; gap: 8px; }
.readout { display: grid; justify-items: center; min-width: 88px; padding: 8px 16px; background: rgba(6, 10, 14, .62); border: 1px solid rgba(255, 255, 255, .2); border-radius: 4px; }
.readout b { font: 600 var(--s2)/1.1 var(--display); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.readout span { color: #DDE3E8; }
.video-ctl { position: absolute; left: var(--pad); bottom: 160px; height: 44px; display: inline-flex; align-items: center; gap: 8px; padding: 0 16px; background: rgba(6, 10, 14, .55); border: 1px solid rgba(255, 255, 255, .24); border-radius: 4px; color: #fff; cursor: pointer; }
.video-ctl svg { width: 16px; height: 16px; }
/* Tablets and small computers: the temperature boxes sit above the buttons, not beside them */
@media (max-width: 1100px) {
  .panel-foot { flex-direction: column; align-items: center; gap: 16px; }
  .readouts { position: static; order: -1; }
  .video-ctl { left: auto; right: var(--pad); bottom: auto; top: calc(var(--head-h) + 8px); }
}
/* Tall tablet screens get the phone pictures (the heat pump stays in view), and their tiny stand-ins */
@media (max-aspect-ratio: 4/5) { .scene::before { background-image: var(--ph-phone, none); } }

/* Air: the scroll story's lines. A soft glow drawn in on scroll, then light pulses that keep flowing along it. */
.air path { stroke-dasharray: 1 1; stroke-dashoffset: 0; }
.air .glow path { stroke-width: 24; stroke-opacity: .8; filter: blur(6px); }   /* 23 Oct: stronger, so the air reads against bright rooms */
.air .flow path { stroke-width: 6; stroke-opacity: .9; stroke-dasharray: .08 .1; animation: flow 6s linear infinite; }   /* 23 Oct: slower and calmer */
.air.cool .glow path { stroke: #8FD3FF; }
.air.cool .flow path { stroke: #EAF7FF; }
.air.warm .glow path { stroke: #FFB062; }
.air.warm .flow path { stroke: #FFE2B8; }
@keyframes flow { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -.18; } }

/* Weather: light rain and snow, only where the scene has it. Runs only while its panel shows. */
.rain, .snow { position: absolute; top: -240px; right: -240px; bottom: 0; left: 0; pointer-events: none; animation-play-state: paused; }
.rain { background: url("assets/layers/rain-light.svg") repeat; opacity: .35; animation: rain 1.4s linear infinite paused; }
.snow { background: url("assets/layers/snow.svg") repeat; opacity: .55; animation: snow 14s linear infinite paused; }
.panel.on .rain, .panel.on .snow { animation-play-state: running; }
@keyframes rain { to { transform: translate3d(-48px, 240px, 0); } }
@keyframes snow { to { transform: translate3d(-60px, 240px, 0); } }
.sun { position: absolute; left: 66%; top: 14%; width: 360px; height: 360px; margin: -180px 0 0 -180px; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 240, 200, .5), rgba(255, 220, 150, 0)); mix-blend-mode: screen; pointer-events: none; animation: sun 6s ease-in-out infinite alternate; }
@keyframes sun { from { transform: scale(.9); opacity: .7; } to { transform: scale(1.1); opacity: 1; } }

/* Phone: each panel full height with the tall phone picture; the headline on the sky, the buttons on the ground, the Call bar always in reach */
@media (max-width: 760px) {
  .panel { min-height: 480px; }
  .scene::before { background-image: var(--ph-phone, none); }
  .panel-copy { top: calc(var(--head-h) + 24px); }
  .panel-copy p { margin-top: 8px; }
  /* the Call bar is 73 px tall: the buttons stay 31 px clear of it on every screen */
  .panel-foot { bottom: calc(104px + env(safe-area-inset-bottom)); flex-direction: column; align-items: center; gap: 12px; }
  .panel-actions { width: 100%; gap: 12px; }
  .panel-actions .btn { min-width: 0; flex: 1 1 0; padding: 0 16px; }
  .readouts { position: static; order: -1; }
  .readout { min-width: 72px; padding: 4px 12px; }
  .video-ctl { left: auto; right: 16px; bottom: auto; top: calc(var(--head-h) + 8px); }
  .sun { display: none; }
  .shade { background:
    linear-gradient(180deg, rgba(6, 10, 14, .62) 0%, rgba(6, 10, 14, .3) 26%, rgba(6, 10, 14, 0) 38%),
    linear-gradient(0deg, rgba(6, 10, 14, .7) 0%, rgba(6, 10, 14, .35) 26%, rgba(6, 10, 14, 0) 40%); }
}

/* Less motion, and ?still: stills only. No zoom, no weather, no flowing pulses, the video stays a still. */
.still .rain, .still .snow, .still .air .flow path, .still .sun { animation: none !important; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---------- After the top: the dark page ---------- */
.wrap { max-width: 1344px; margin: 0 auto; padding: 0 var(--pad); }
.section { padding: var(--section) 0; background: var(--ink); }
.section + .section { border-top: 1px solid var(--line); }
.section h2 { font-size: var(--s2); line-height: 1.1; }
.section-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 16px 32px; margin-bottom: 48px; }
.lead { font-size: var(--s3); line-height: 1.5; color: var(--muted); max-width: 40ch; }

.tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); }
.ph { margin: 0; }
.ph img { width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; background: var(--ink-2); }
.ph figcaption { margin-top: 12px; font-weight: 600; }
@media (max-width: 760px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } .ph figcaption { margin-top: 8px; } }

.quotes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); }
.quote { display: flex; flex-direction: column; justify-content: space-between; gap: 24px; padding: 24px 0 0; border-top: 1px solid var(--line); }
.quote p { font-size: var(--s3); line-height: 1.5; }
.quote figcaption { color: var(--muted); }
.quote figcaption b { color: var(--stone); margin-right: 8px; }
@media (max-width: 960px) { .quotes { grid-template-columns: 1fr; } .quote { padding: 24px 0 0; } }

.brands { padding: 72px 0; }
.brands .brands-title { font: 600 var(--s4)/1.6 var(--text); color: var(--muted); letter-spacing: 0; margin-bottom: 16px; text-align: center; }
.brand-list { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 32px; font: 500 var(--s3)/1.6 var(--display); }

.call-band { background: var(--ink-2); }
.two-col { display: grid; grid-template-columns: 5fr 6fr; gap: 64px; align-items: start; }
.call-side h2 { margin-bottom: 16px; }
.big-call { display: inline-flex; align-items: center; min-height: 48px; margin-top: 32px; font: 600 var(--s2)/1 var(--display); letter-spacing: -.02em; text-decoration: none; font-variant-numeric: tabular-nums; border-bottom: 1px solid var(--accent-text); }
.big-call:hover { color: var(--accent-text); }
.form-card { background: var(--ink-3); border: 1px solid var(--line); padding: 40px; }
.progress { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 16px; }
.progress span { height: 2px; background: var(--line); }
.progress span.on { background: var(--accent-text); }
.step-label { color: var(--muted); margin-bottom: 24px; }
fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
legend { font: 700 var(--s3)/1.3 var(--display); padding: 0; margin-bottom: 24px; }
.choices { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.choice { position: relative; display: flex; align-items: center; min-height: 52px; padding: 8px 16px; border: 1px solid var(--line-strong); border-radius: 4px; background: var(--ink); cursor: pointer; }
.choice:hover { border-color: var(--stone); }
.choice input { position: absolute; opacity: 0; }
.choice:has(input:checked) { border-color: var(--accent-text); box-shadow: inset 0 0 0 1px var(--accent-text); }
.choice:has(input:focus-visible) { outline: 2px solid var(--accent-text); outline-offset: 2px; }
.field { display: grid; gap: 8px; margin-bottom: 16px; }
.field label { font-weight: 600; }
.field input, .field select, .field textarea { width: 100%; min-height: 48px; padding: 8px 16px; border: 1px solid var(--line-strong); border-radius: 4px; background: var(--ink); }
.field textarea { min-height: 112px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--accent-text); outline: none; box-shadow: inset 0 0 0 1px var(--accent-text); }
.two { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-error { color: var(--error); }
.form-error:not(:empty) { margin-top: 16px; }
.form-nav { display: flex; justify-content: space-between; gap: 16px; margin-top: 32px; }
.form-nav #f-next { margin-left: auto; }
.form-done h3 { margin-bottom: 8px; }
.form-done p { color: var(--muted); }
@media (max-width: 960px) { .two-col { grid-template-columns: 1fr; gap: 48px; } }
@media (max-width: 760px) { .form-card { padding: 24px; } .choices, .two { grid-template-columns: 1fr; } }

.site-foot { background: var(--ink); color: var(--muted); border-top: 1px solid var(--line); padding: 80px 0 40px; }
.site-foot a { text-decoration: none; color: var(--stone); display: inline-flex; align-items: center; min-height: 32px; }
.site-foot a:hover { text-decoration: underline; text-underline-offset: 6px; }
.foot-top { display: grid; grid-template-columns: 2fr 2fr 1.4fr 1.4fr; gap: 40px var(--gap); padding-bottom: 48px; border-bottom: 1px solid var(--line); }
.foot-logo { width: 168px; height: auto; margin-bottom: 24px; }
.foot-col h3 { font: 600 var(--s4)/1.6 var(--text); color: var(--stone); margin-bottom: 12px; }
.foot-col li + li, .foot-col p + p { margin-top: 4px; }
.foot-base { padding-top: 32px; }
@media (max-width: 960px) { .foot-top { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .foot-top { grid-template-columns: 1fr; } }

/* Calm rise, once */
.js:not(.still) .rise { opacity: 0; transform: translateY(24px); transition: opacity .9s var(--ease), transform .9s var(--ease); }
.js:not(.still) .rise.in { opacity: 1; transform: none; }

.call-bar { display: none; }
@media (max-width: 760px) {
  .call-bar { display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; padding: 12px var(--pad); padding-bottom: calc(12px + env(safe-area-inset-bottom)); background: color-mix(in srgb, var(--ink) 94%, transparent); border-top: 1px solid var(--line); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
  .call-bar .btn { width: 100%; }
  body { padding-bottom: 72px; }
}

/* ---------- Inner pages (services, about) ---------- */
body.page main { padding-top: var(--head-h); }
.page-head { padding: 96px 0 64px; }
.page-head h1 { margin-bottom: 16px; }
.page-head + .section { padding-top: 32px; border-top: 0; }
.svc-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; }
.svc-list li { padding: 24px 0; border-top: 1px solid var(--line); }
.svc-list li:last-child { border-bottom: 1px solid var(--line); }
.svc-list h3 { margin-bottom: 4px; }
.svc-list p { color: var(--muted); max-width: 52ch; }
.svc-list .soon p { font-style: italic; }
.svc-list a { color: var(--accent-text); text-underline-offset: 4px; }
.col-head { font-size: var(--s2); margin-bottom: 24px; }
@media (max-width: 960px) { .svc-cols { grid-template-columns: 1fr; gap: 48px; } }
.shop-pic img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
.facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); margin-top: 48px; }
.facts li { padding-top: 16px; border-top: 1px solid var(--line-strong); }
.facts b { display: block; font: 700 var(--s3)/1.3 var(--display); margin-bottom: 4px; }
.facts span { color: var(--muted); }
@media (max-width: 760px) { .facts { grid-template-columns: 1fr; } .page-head { padding: 56px 0 40px; } }

/* ---------- What We Do: one pinned section. Names on the left, one large picture on the right (the owner, 22 Oct) ---------- */
.svc { position: relative; background: var(--ink); color: var(--stone); }
.js .svc { height: calc(100vh + 6 * 45vh); height: calc(100svh + 6 * 45svh); }
.svc-pin { position: sticky; top: 0; height: 100vh; height: 100svh; display: flex; align-items: center; padding: var(--head-h) 0 72px; overflow: hidden; }
/* (72 px at the bottom keeps the names clear of the preview bar) */
.svc-grid { width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 64px; align-items: center; }
.svc-side h2 { font: 600 var(--s4)/1.6 var(--text); letter-spacing: 0; color: var(--muted); margin-bottom: 16px; }
.svc-names { list-style: none; padding: 0; border-bottom: 1px solid var(--line); }
.svc-item { position: relative; border-top: 1px solid var(--line); }
.svc-item::before { content: ""; position: absolute; left: 0; top: -1px; width: 0; height: 2px; background: var(--accent-text); transition: width .7s var(--ease); }
.svc-item.is-on::before { width: 100%; }
.svc-name { display: inline-block; padding: 12px 0; font: 600 var(--s2)/1.15 var(--display); letter-spacing: -.02em; color: var(--muted); text-decoration: none; transition: color .3s; }
.svc-name:hover, .svc-item.is-on .svc-name { color: var(--stone); }
.svc-item .tbc { margin-left: 16px; }
.svc-more { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .5s var(--ease); }
.svc-more > div { overflow: hidden; }
.svc-item.is-on .svc-more { grid-template-rows: 1fr; }
.svc-more p { font-size: var(--s3); line-height: 1.45; color: var(--muted); }
.svc-actions { display: flex; flex-wrap: wrap; gap: 16px; padding: 20px 0 24px; }
.svc-ph { display: none; }
.svc-stage { position: relative; justify-self: end; width: min(100%, calc((100svh - var(--head-h) - 136px) * .8)); aspect-ratio: 4 / 5; overflow: hidden; background: var(--ink-2); }
.svc-stage img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transform: scale(1.06); transition: opacity .7s var(--ease), transform 1.4s var(--ease); }
.svc-stage img.is-on { opacity: 1; transform: none; }
.svc-count { position: absolute; left: 16px; bottom: 16px; padding: 4px 12px; border-radius: 4px; background: rgba(6, 10, 14, .62); color: #F2F1EE; font-variant-numeric: tabular-nums; }
.svc-count b { font-weight: 600; }
@media (max-width: 1100px) { .svc-grid { gap: 32px; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); } }
@media (max-width: 760px) {
  .js .svc { height: auto; }
  .svc-pin { position: static; height: auto; display: block; padding: var(--section) 0; }
  .svc-grid { display: block; }
  .svc-stage { display: none; }
  .svc-item { display: flex; flex-direction: column; padding-top: 24px; }
  .svc-item::before { content: none; }
  .svc-ph { display: block; order: -1; margin: 0 0 8px; }
  .svc-ph img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; background: var(--ink-2); }
  .svc-name { color: var(--stone); padding: 8px 0 4px; }
  .svc-item .tbc { margin: 0 0 4px; align-self: flex-start; }
  .svc-more { grid-template-rows: 1fr; }
  .svc-actions { padding: 16px 0 24px; }
  .svc-actions .btn { flex: 1 1 0; padding: 0 16px; }
}

/* ---------- The cut-away: one band. Summer turns to winter as you scroll, or tap. ----------
   23 Oct (the owner: "too quick, can't tell what's going on"): on a computer the band holds still while you scroll (.cut.pinned)
   and the air draws as fast as you scroll: cool air into every room, then a slow turn to winter, then warm air. */
.cut { position: relative; background: var(--night); color: #fff; }
.cut-pin { position: relative; isolation: isolate; overflow: hidden; height: clamp(560px, 56.25vw, 92vh); }
.js .cut.pinned { height: calc(100vh - var(--head-h) + 170vh); }
.js .cut.pinned .cut-pin { position: sticky; top: var(--head-h); height: calc(100vh - var(--head-h)); min-height: 560px; }
.cut.scrub .cut-scene { transition: none; }
.cut-copy p span { display: block; transition: opacity .5s var(--ease); }
.cut-copy p { display: grid; }
.cut-copy p span { grid-area: 1 / 1; }
.cut-l2 { opacity: 0; }
.still .cut-l2 { display: none; }
.still .cut-l1::after { content: " Warm air in winter."; }
.cut-stage { position: absolute; inset: 0; z-index: -2; }
.cut-stage::after { content: ""; position: absolute; inset: 0; pointer-events: none; background:
  linear-gradient(180deg, rgba(6, 10, 14, .7) 0%, rgba(6, 10, 14, .4) 20%, rgba(6, 10, 14, 0) 36%),
  linear-gradient(0deg, rgba(6, 10, 14, .7) 0%, rgba(6, 10, 14, .3) 16%, rgba(6, 10, 14, 0) 30%); }
.cut-scene { position: absolute; inset: 0; opacity: 0; transition: opacity .9s var(--ease); }
.cut-scene.is-on { opacity: 1; }
/* a tiny blurred copy shows at once, so the band is never empty black while its picture loads */
.cut-scene::before { content: ""; position: absolute; inset: -48px; background: var(--ph-wide, none) center / cover no-repeat; filter: blur(24px); }
@media (max-width: 760px) { .cut-scene::before { background-image: var(--ph-phone, none); } }
.cut-stage { overflow: hidden; }
.cut-scene img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; }
.cut-scene .air { position: absolute; inset: 0; width: 100%; height: 100%; }
.cut.on .cut-scene.is-on .snow { animation-play-state: running; }
.cut-copy { position: absolute; left: var(--pad); right: var(--pad); top: 56px; text-align: center; text-shadow: 0 1px 12px rgba(0, 0, 0, .35); }
.cut-copy p { margin: 12px auto 0; font-size: var(--s3); line-height: 1.45; max-width: 48ch; }
.cut-foot { position: absolute; left: var(--pad); right: var(--pad); bottom: 72px; display: grid; grid-template-columns: auto auto 1fr; align-items: end; gap: 16px; }
/* the switch and the button sit left, the readouts right: the house in the middle stays clear */
.cut-foot .btn { min-width: 248px; }
.cut .readouts { position: static; justify-self: end; }
.season-switch { justify-self: start; display: inline-flex; border: 1px solid rgba(255, 255, 255, .3); border-radius: 4px; background: rgba(6, 10, 14, .62); }
.season-switch button { height: 44px; padding: 0 20px; border: 0; border-radius: 3px; background: none; color: #fff; font-weight: 600; cursor: pointer; transition: background-color .3s, color .3s; }
.season-switch button[aria-pressed="true"] { background: #fff; color: #12181E; }
/* Tablets and phones: the words above the picture, the switch and the button below it, the house stays clear */
@media (max-width: 1100px) {
  .cut-pin { height: auto; display: flex; flex-direction: column; overflow: visible; }
  .cut-copy { position: static; padding: var(--section) var(--pad) 32px; text-shadow: none; }
  .cut-stage { position: relative; z-index: 0; aspect-ratio: 1600 / 1060; }
  .cut-stage::after { background: none; }
  .cut-foot { position: static; grid-template-columns: 1fr; justify-items: center; padding: 24px var(--pad) var(--section); gap: 16px; }
  .season-switch, .cut .readouts { justify-self: center; }
}
@media (max-width: 760px) {
  .cut-copy h2 { font-size: var(--s2); }
  .cut-stage { aspect-ratio: 4 / 5; }
  .cut-foot .btn { width: 100%; min-width: 0; }
  .cut .readout { min-width: 72px; padding: 4px 12px; }
}

/* ---------- Northline Care: one strip ---------- */
.care { background: var(--ink-2); }
.care-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 32px; }
.care-row h2 { margin-bottom: 12px; }
.care-actions { display: flex; flex-wrap: wrap; gap: 16px; }
@media (max-width: 760px) { .care-actions { width: 100%; flex-direction: column; } .care-actions .btn { width: 100%; } }

/* Preview controls (mock-controls.css): a button height this site already uses */
:root { --mc-h: 44px; }
@media (max-width: 760px) { :root { --mc-h: 44px; } }

/* ---------- 23 Oct studio pass (the owner: "like Tesla, so clean") ---------- */
/* Readouts sit on the picture with no boxes, one thin line between them (Tesla's numbers row) */
.readouts { gap: 0; }
.readout { min-width: 0; padding: 0 20px; background: none; border: 0; border-radius: 0; text-shadow: 0 1px 10px rgba(0, 0, 0, .55); }
.readout + .readout { border-left: 1px solid rgba(255, 255, 255, .45); }
.readout b { font-weight: 500; }
/* The pause button: one round glass button */
.video-ctl { width: 44px; padding: 0; justify-content: center; border-radius: 50%; }
.video-ctl span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* What We Do: one action per service, Learn more is a quiet link */
.svc-link { display: inline-flex; align-items: center; min-height: 48px; font-weight: 600; color: var(--stone); text-underline-offset: 6px; }
.svc-link:hover { color: var(--accent-text); }
.svc-cta { display: none; }
@media (max-width: 760px) {
  /* a swipe row: one service at a time, the next one peeks in */
  .svc-names { display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-left: var(--pad); border: 0; margin: 0 calc(-1 * var(--pad)); padding: 0 var(--pad) 8px; scrollbar-width: none; }
  .svc-names::-webkit-scrollbar { display: none; }
  .svc-item { flex: 0 0 82%; scroll-snap-align: start; border: 0; padding-top: 0; }
  .svc-actions { display: none; }
  .svc-cta { display: flex; gap: 12px; margin-top: 24px; }
  .svc-cta .btn { flex: 1 1 0; padding: 0 16px; }
}

/* Northline Care: the evening photo, then the title left and the words right (Tesla's pattern) */
.care-panel { position: relative; isolation: isolate; background: var(--night); color: #fff; }
.care-pic { position: relative; display: block; }
.care-pic img { width: 100%; height: auto; aspect-ratio: 16 / 8; object-fit: cover; object-position: 50% 62%; }
.care-pic::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(180deg, rgba(11, 17, 23, 0) 50%, rgba(11, 17, 23, .7) 78%, var(--night) 100%); }
.care-copy { position: relative; margin-top: -136px; padding-bottom: var(--section); display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 48px; align-items: start; }
.care-copy p { font-size: var(--s3); line-height: 1.5; color: #DDE3E8; max-width: 52ch; }
.care-actions { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 32px; }
@media (max-width: 760px) {
  .care-pic img { aspect-ratio: 4 / 5; }
  .care-copy { grid-template-columns: 1fr; gap: 16px; margin-top: -96px; }
  .care-actions { flex-direction: column; }
  .care-actions .btn { width: 100%; }
}

/* ==================== 23 Oct, judges round 2 (design 5/10, UX 3/10) ==================== */
/* Three weights only: 400 text, 500 for buttons, nav, numbers and the phone, 600 for headings */
.btn { font-weight: 500; }
legend, .mega-head, .facts b { font-weight: 600; }
.head-call { font-weight: 500; }
.nowrap { white-space: nowrap; }
/* No text shadows: the shade gradients carry the contrast */
.panel-copy, .cut-copy, .readout { text-shadow: none; }
.home .site-head:not(.solid):not(.open-mega):not(.menu-open) .head-call,
.home .site-head:not(.solid):not(.open-mega):not(.menu-open) .nav-link { text-shadow: none; }

/* Header: the menu centred on the page, not between the logo and the number */
@media (min-width: 901px) {
  .head-row { display: grid; grid-template-columns: 1fr auto 1fr; }
  .nav { margin: 0; }
  .head-actions { justify-self: end; }
}
/* The header's Estimate waits until the first screen's buttons have scrolled away (one blue button per screen) */
.head-est { transition: opacity .3s; }
.home .head-est.wait { opacity: 0; pointer-events: none; visibility: hidden; }

/* The first screen: the words higher, one trust line, the pause button in line with the buttons */
.panel-copy { top: calc(var(--head-h) + 24px); }
.panel-copy .panel-trust { margin-top: 16px; max-width: none; color: #DDE3E8; }
.panel-foot { bottom: 112px; }
.video-ctl { bottom: 114px; }
.rain { opacity: .15; }
.top-video.playing + .rain { opacity: 0; }
/* Snow in two layers that never line up, so it never looks like a grid */
.snow { background: none; opacity: 1; animation: none; }
.snow::before, .snow::after { content: ""; position: absolute; inset: 0; background: url("assets/layers/snow.svg") repeat; animation: snow 18s linear infinite paused; }
.snow::before { background-size: 380px; opacity: .35; }
.snow::after { background-size: 240px; opacity: .25; animation-duration: 11s; }
.panel.on .snow::before, .panel.on .snow::after, .cut.on .cut-scene .snow::before, .cut.on .cut-scene .snow::after { animation-play-state: running; }
.still .snow::before, .still .snow::after { animation: none; }

/* What We Do: the list starts with the picture, inactive names step back, closed items cannot be reached by Tab */
.svc-grid { align-items: start; }
.svc-name { color: rgba(242, 241, 238, .4); }
@media (min-width: 761px) { .js .svc { height: calc(100vh + 6 * 25vh); height: calc(100svh + 6 * 25svh); } }
.svc-actions { gap: 24px; }
.svc-dots { display: none; }
@media (min-width: 761px) { .svc-item:not(.is-on) .svc-more { visibility: hidden; } }
@media (max-width: 760px) {
  .svc-actions { display: flex; padding: 8px 0 0; }
  .svc-actions .svc-link { min-height: 44px; }
  .svc-dots { display: flex; gap: 8px; margin-top: 16px; }
  .svc-dots i { flex: 1; height: 2px; background: var(--line); transition: background-color .3s; }
  .svc-dots i.on { background: var(--stone); }
}

/* Every Room, All Year: the title on the page, the band clear for the house */
.cut-head { padding: var(--section) var(--pad) 48px; text-align: center; background: var(--night); color: #fff; }
.cut-scene img { object-position: 50% 100%; }
.cut-scene[data-season="summer"] img { filter: saturate(.72) brightness(.86) contrast(1.06); }
.js .cut.pinned { height: calc(100vh - var(--head-h) + 120vh); }
.js .cut.pinned .cut-pin { height: calc(100vh - var(--head-h) - 72px); }
.cut-foot { top: 40px; bottom: auto; left: 48px; right: 48px; grid-template-columns: 1fr auto; align-items: start; }
.cut-left { display: grid; gap: 16px; justify-items: start; }
.cut-season { display: grid; font-size: var(--s3); line-height: 1.45; }
.cut-season span { grid-area: 1 / 1; transition: opacity .5s var(--ease); }
.cut-l2 { opacity: 0; }
.cut .readouts { align-self: start; }
.season-switch.indicator { pointer-events: none; }
.air .glow path { stroke-width: 12; stroke-opacity: .45; filter: blur(8px); }
.air .flow path { stroke-width: 3; stroke-dasharray: .02 .12; }
@keyframes flow { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -.14; } }
@media (max-width: 1100px) {
  .cut-head { padding: var(--section) var(--pad) 32px; }
  .cut-foot { position: static; grid-template-columns: 1fr; justify-items: center; padding: 24px var(--pad) var(--section); }
  .cut-left { justify-items: center; text-align: center; }
  .cut-season { justify-items: center; }
}
@media (max-width: 760px) {
  .cut-head h2 { font-size: var(--s2); }
  .cut-stage::after { background: linear-gradient(180deg, rgba(6, 10, 14, .6) 0%, rgba(6, 10, 14, 0) 20%); }
}

/* Northline Care: soft at the top and the bottom, the words kept short */
.care-pic::after { background: linear-gradient(180deg, var(--night) 0%, rgba(11, 17, 23, .6) 14%, rgba(11, 17, 23, 0) 34%, rgba(11, 17, 23, 0) 50%, rgba(11, 17, 23, .7) 78%, var(--night) 100%); }
.care-pic img { filter: saturate(.8) brightness(.85); }
.care-copy p { max-width: 40ch; }
#care-title { font-size: var(--s2); }

/* The estimate form: one surface, no nested boxes */
.form-card { background: none; border: 0; padding: 0; }
.choice:last-child { grid-column: 1 / -1; }
@media (max-width: 760px) { .form-card { padding: 0; } }

/* Brands: a quiet list on the grid */
.brands .brands-title { text-align: left; }
.brand-list, .brands ul { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 16px 32px; font: 500 var(--s4)/1.5 var(--text); color: var(--muted); text-align: left; justify-content: start; }
@media (max-width: 760px) { .brand-list, .brands ul { grid-template-columns: 1fr 1fr; } }

/* Footer: links step back, easy to tap on a phone */
.site-foot a { color: var(--muted); }
.site-foot a:hover { color: var(--stone); }
@media (max-width: 760px) { .site-foot a { min-height: 44px; } }
@media (max-width: 560px) {
  .foot-top { grid-template-columns: 1fr 1fr; }
  .foot-top > :first-child, .foot-top > :nth-child(2) { grid-column: 1 / -1; }
}

/* The phone menu: main items first, Services closed, 48 px rows, Call and Estimate at the bottom */
.nav-cta { display: none; }
.menu-toggle .i-x { display: none; }
@media (max-width: 760px) {
  .head-call { width: 44px; justify-content: center; }
  .hc-num { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .head-call svg { width: 20px; height: 20px; }
  .nav > .nav-link { order: 1; height: 56px; }
  .nav > .has-mega { order: 2; }
  .nav-cta { order: 3; display: grid; gap: 12px; margin-top: 24px; }
  .nav-cta .btn { width: 100%; height: 48px; }
  .mega a { min-height: 48px; }
  .menu-open .menu-toggle .i-x { display: block; }
  .menu-open .menu-toggle .i-burger { display: none; }
  /* the bottom bar: Call, Estimate and Ask; the first screen's buttons stay in the bar */
  .call-bar { display: flex !important; gap: 8px; }
  .call-bar .btn { flex: 1; width: auto; padding: 0 12px; }
  .panel-top .panel-actions { display: none; }
}

/* The app section's tour pause */
.app-pause { display: inline-flex; align-items: center; gap: 8px; height: 44px; margin-top: 16px; padding: 0; border: 0; background: none; color: var(--muted); font: 500 var(--s4)/1 var(--text); cursor: pointer; }
.app-pause svg { width: 16px; height: 16px; }
.app-pause:hover { color: var(--stone); }
@media (min-width: 1101px) { .svc-pin { padding-bottom: 112px; } }

/* The services page (round 2): a picture row for each confirmed service, like the home page */
.svc-rows { display: grid; gap: 0; }
.svc-row { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: 48px; align-items: center; padding: 40px 0; border-top: 1px solid var(--line); }
.svc-row:last-child { border-bottom: 1px solid var(--line); }
.svc-row figure img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
.svc-row h2 { font-size: var(--s2); margin-bottom: 12px; }
.svc-row p { font-size: var(--s3); line-height: 1.5; color: var(--muted); max-width: 44ch; }
.svc-row-links { display: flex; flex-wrap: wrap; gap: 24px; margin-top: 16px; }
.svc-row-links .svc-link { font-size: var(--s4); }
@media (max-width: 760px) { .svc-row { grid-template-columns: 1fr; gap: 16px; padding: 24px 0; } }

/* ==================== 23 Oct, judges round 3 (design 5, UX 6) ==================== */
html { scroll-padding-top: 88px; scroll-padding-bottom: 88px; }
/* Header on the content grid: the logo, the menu columns and the page share one left edge; a readable logo */
.head-row { max-width: 1344px; }
.wordmark img { height: 40px; }
@media (max-width: 760px) { .wordmark img { height: 32px; } }
.mega { grid-template-columns: repeat(3, minmax(0, 280px)); justify-content: start; padding-left: max(var(--pad), calc((100vw - 1344px) / 2 + var(--pad))); }

/* Hero: brighter picture, the buttons under the words, a soft end */
.panel-top .scene img, .panel-top .scene video { filter: brightness(1.22) contrast(1.05); }
.panel-copy .panel-trust { font-size: var(--s4); color: #C9D1D8; }
.panel-trust span { white-space: nowrap; }
.panel-copy .panel-actions { justify-content: center; margin-top: 32px; }
.panel-top::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 160px; background: linear-gradient(180deg, rgba(11, 17, 23, 0), var(--ink)); pointer-events: none; z-index: 0; }
.btn-light { background: #FFFFFF; }
@media (max-width: 760px) {
  .panel-top .panel-actions { display: flex; }
  .panel-top .shade { background: linear-gradient(180deg, var(--ink) 0%, rgba(11, 17, 23, .55) 22%, rgba(11, 17, 23, 0) 45%); }
  .panel-copy .panel-actions .btn { flex: 1 1 0; min-width: 0; padding: 0 12px; }
}

/* What We Do: one big name, the rest small and quiet; a shorter hold */
@media (min-width: 761px) {
  .js .svc { height: calc(100vh + 6 * 16vh); height: calc(100svh + 6 * 16svh); }
  .svc-name { font: 500 var(--s3)/1.3 var(--display); padding: 16px 0; color: var(--muted); }
  .svc-item.is-on .svc-name { font: 600 var(--s2)/1.15 var(--display); letter-spacing: -.02em; padding: 12px 0; color: var(--stone); }
}

/* Every Room, All Year: closer to What We Do, clear air with arrows, the season as plain labels */
.cut-head { padding-top: 64px; }
.air .glow path { stroke-width: 14; stroke-opacity: .6; filter: blur(6px); }
.air .flow path { stroke-width: 4; stroke-opacity: 1; stroke-dasharray: .1 .04; }
@keyframes flow { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -.14; } }
.cut-scene[data-season="summer"] img { filter: saturate(.6) brightness(.8) contrast(1.06); }
.cut-scene[data-season="summer"]::after { content: ""; position: absolute; inset: 0; background: rgba(18, 38, 66, .28); mix-blend-mode: multiply; pointer-events: none; }
.season-switch.indicator { border: 0; background: none; gap: 20px; }
.season-switch.indicator button { height: 44px; padding: 0; background: none; color: rgba(255, 255, 255, .55); border-bottom: 2px solid transparent; border-radius: 0; }
.season-switch.indicator button[aria-pressed="true"] { background: none; color: #fff; border-bottom-color: #fff; }
/* phone: the band holds too, the whole house shows, the season and readings under it */
@media (max-width: 1100px) {
  .js .cut.pinned { height: calc(100svh + 140svh); }
  .js .cut.pinned .cut-pin { position: sticky; top: var(--head-h); height: calc(100svh - var(--head-h) - 72px); display: flex; flex-direction: column; overflow: hidden; }
  .js .cut.pinned .cut-stage { flex: 1; min-height: 0; aspect-ratio: auto; }
  .js .cut.pinned .cut-foot { position: static; padding: 16px var(--pad); gap: 12px; grid-template-columns: 1fr auto; justify-items: start; align-items: center; }
  .js .cut.pinned .cut-left { justify-items: start; text-align: left; gap: 8px; }
  .js .cut.pinned .cut-season { justify-items: start; font-size: var(--s4); }
  .js .cut.pinned .readout { padding: 0 12px; }
}

/* Care: the house reads, the picture is closer, the section ends sooner */
.care-pic img { transform: scale(1.4); transform-origin: 78% 68%; filter: saturate(.85) brightness(.95); }
.care-pic { overflow: hidden; }
.care-pic::after { background: linear-gradient(180deg, var(--night) 0%, rgba(11, 17, 23, .45) 12%, rgba(11, 17, 23, 0) 30%, rgba(11, 17, 23, 0) 55%, rgba(11, 17, 23, .6) 80%, var(--night) 100%); }
.care-copy { padding-bottom: 0; }
.care-panel { padding-bottom: 96px; }

/* Reviews: the line under the heading */
.rev-sub { color: var(--muted); width: 100%; margin-top: -4px; }
#reviews .section-head, #about-reviews .section-head { display: grid; gap: 12px; }

/* Brands: two calm centred rows */
.brands .brands-title { text-align: center; }
.brand-list, .brands ul { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px 48px; max-width: 1040px; margin: 0 auto; }
@media (max-width: 760px) { .brand-list, .brands ul { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; } }

/* The form: a picked choice is filled with a tick; a hint under the postal code; a real thank you */
.choice:has(input:checked) { background: var(--accent); border-color: var(--accent); box-shadow: none; color: #fff; padding-right: 44px; }
.choice:has(input:checked)::after { content: ""; position: absolute; right: 16px; top: 50%; width: 14px; height: 8px; margin-top: -6px; border-left: 2px solid #fff; border-bottom: 2px solid #fff; transform: rotate(-45deg); }
.hint { color: var(--muted); }
.form-step { scroll-margin-top: 104px; }
.form-done { display: grid; gap: 12px; justify-items: start; }
.done-tick { display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: var(--accent); color: #fff; }
.done-tick svg { width: 28px; height: 28px; }
.done-acts { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 12px; }
@media (max-width: 760px) { .done-acts .btn { width: 100%; } }

/* The phone menu: Services first, every row 48 px, nothing repeated */
@media (max-width: 760px) {
  .nav > * { flex-shrink: 0; }
  .nav > .has-mega { order: 1; }
  .nav > .nav-link { order: 2; height: 52px; }
  .mega .mega-col:first-child .mega-head { display: none; }
  .mega .mega-col:last-child { display: none; }
}

/* Corners: 4 px for the strip's bar and the phone bar too (pills only inside the app) */
.ask-pill, .ask-mini { border-radius: 4px; }

/* The services page: rows that alternate, bigger pictures; contact that fits */
.svc-row { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 64px; }
.svc-row:nth-child(even) figure { order: 2; }
.svc-row figure img { aspect-ratio: 4 / 3; }
.facts span { overflow-wrap: anywhere; }
#rebates h2, #contact h2, #care-head, #financing { margin-bottom: 16px; }
@media (max-width: 760px) { .svc-row:nth-child(even) figure { order: 0; } }

/* About: the crew picture */
.crew-pic img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
.crew-pic figcaption { margin-top: 8px; }
@media (max-width: 760px) { .cut-scene img { object-position: 50% 50%; } }

/* ==================== 23 Oct, judges round 4 (design 6, UX 6) ==================== */
.skip { min-height: 44px; display: inline-flex; align-items: center; }
.head-call { white-space: nowrap; }
@media (max-width: 1199px) { .hc-num { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); } .head-call { width: 44px; justify-content: center; } }

/* Hero: the picture sits lower with the words on the dark above it; one line, two buttons */
@media (min-width: 761px) {
  .panel-top .scene img, .panel-top .scene video { top: 20%; height: 80%; object-position: 50% 30%;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 22%); mask-image: linear-gradient(180deg, transparent 0%, #000 22%); }
  .panel-top .scene::before { display: none; }
}
.panel-top { background: var(--ink); }
.btn-on-pic { background: rgba(11, 17, 23, .35); border-color: rgba(255, 255, 255, .7); color: #fff; }
.btn-on-pic:hover { border-color: #fff; background: rgba(11, 17, 23, .55); }

/* What We Do: a real section title, room under the header, the line only on the open item */
.svc-side h2 { font: 600 var(--s2)/1.15 var(--display); letter-spacing: -.02em; color: var(--stone); margin-bottom: 24px; }
@media (min-width: 761px) { .svc-pin { padding-top: calc(var(--head-h) + 56px); padding-bottom: 72px; } }
.svc-item::before { transition: none; }
.svc-item.is-on::before { transition: width .7s var(--ease); }
@media (max-width: 760px) {
  .svc-pin { padding: 48px 0; }
  .svc-item:not(.is-on) .svc-name { color: var(--stone); }
}

/* Every Room, All Year: summer like summer, summer air you can see, a soft hand-over to Care */
.cut { overflow: clip; }
.cut-scene[data-season="summer"]::after { content: none; }
.cut-scene[data-season="summer"] img { filter: saturate(.9) brightness(.95); }
.air.cool .glow path { stroke: #3FA9F5; stroke-opacity: .75; }
.air.cool .flow path { stroke: #D6F0FF; }
.air .flow { filter: drop-shadow(0 0 1px rgba(6, 10, 14, .85)); }
.cut-stage::after { background: linear-gradient(0deg, var(--night) 0%, rgba(11, 17, 23, 0) 120px); }
@media (max-width: 760px) { .cut-head { padding-top: 32px; } }
.care-panel { padding-top: 128px; }
.care-pic img { transform: none; aspect-ratio: 16 / 8; object-position: 70% 70%; filter: saturate(.85) brightness(.95); }
@media (max-width: 760px) { .care-panel { padding-top: 48px; padding-bottom: 48px; } }

/* The estimate form: the two boxes on one line, one height, our own arrow; errors under the field */
.two { align-items: start; }
.field select { height: 48px; min-height: 48px; padding-right: 44px; -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23A9B3BB' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 16px center; background-size: 16px; }
.field input { height: 48px; }
.field-err { color: var(--error); }
.field-err:empty { display: none; }
.field input[aria-invalid="true"] { border-color: var(--error); box-shadow: inset 0 0 0 1px var(--error); }

/* The menu: a picture card; one column on a phone with every heading */
.mega { grid-template-columns: repeat(3, minmax(0, 240px)) 280px; gap: 48px; }
.mega-card { display: grid; gap: 12px; align-content: start; text-decoration: none; }
.mega-card img { width: 100%; height: auto; aspect-ratio: 14 / 9; object-fit: cover; border-radius: 4px; }
.mega-card span { font-weight: 500; }
@media (max-width: 760px) {
  .mega { grid-template-columns: 1fr; gap: 16px; }
  .mega .mega-col:first-child .mega-head, .mega .mega-col:last-child { display: block; }
  .mega-card { display: none; }
  .mega a { white-space: nowrap; }
}

/* Services and About: a wide picture under the title */
.page-banner { margin: 0 0 var(--section); }
.page-banner img { width: 100%; height: auto; aspect-ratio: 12 / 5; object-fit: cover; border-radius: 4px; }
.page-banner figcaption { margin-top: 8px; }
@media (max-width: 760px) { .page-banner img { aspect-ratio: 4 / 3; } }
/* services rows stack on a phone */
@media (max-width: 760px) { .svc-row { grid-template-columns: 1fr; gap: 16px; } .svc-row:nth-child(even) figure { order: 0; } }
.panel-copy p { max-width: none; }
@media (min-width: 761px) {
  .panel-top .scene img, .panel-top .scene video { top: 26%; height: 74%;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, transparent 8%, #000 40%); mask-image: linear-gradient(180deg, transparent 0%, transparent 8%, #000 40%); }
}
.mega .mega-card { display: grid; align-items: start; min-height: 0; }

/* ==================== 23 Oct, judges round 5 (design 5, UX 6) ==================== */
/* Rhythm: 96 px around each section on a computer, 64 px on a phone */
:root { --section: 96px; }
@media (max-width: 760px) { :root { --section: 64px; } }

/* One picture grade across the site: cool night, warm window light */
.cut-scene[data-season="summer"] img { filter: saturate(.7) brightness(.85); }
.care-pic img { filter: saturate(.8); }
.banner-about img { filter: brightness(.8) saturate(.75); }      /* the crew close-up on About has the same grade made into its file */
.banner-services img { filter: saturate(.65); }

/* Hero, computer: the heat pump centred under the headline, a soft halo behind it (like the Powerwall page), the picture lower than the words */
@media (min-width: 761px) and (min-aspect-ratio: 4/5) {
  .panel-copy p { max-width: 44em; margin-left: auto; margin-right: auto; text-wrap: balance; }
  .panel-top .scene img, .panel-top .scene video { transform-origin: 64% 52%; transform: translate(-14%, 3%);
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, transparent 12%, #000 36%), linear-gradient(90deg, transparent 28%, #000 40%, #000 88%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0%, transparent 12%, #000 36%), linear-gradient(90deg, transparent 28%, #000 40%, #000 88%, transparent 100%);
    -webkit-mask-composite: source-in; mask-composite: intersect; }
  .panel-top .scene::after { content: ""; position: absolute; left: 50%; top: 66%; width: 700px; height: 700px; margin: -350px 0 0 -350px; pointer-events: none;
    background: radial-gradient(closest-side, rgba(156, 196, 226, .17), rgba(156, 196, 226, .08) 55%, rgba(156, 196, 226, 0)); mix-blend-mode: screen; }
}
/* Hero, phone: the unit lower and about 15% bigger, so there is no empty dark band under it */
@media (max-width: 760px) {
  .panel-top .scene img { transform-origin: 50% 50%; transform: translateY(16%) scale(1.15); }
}

/* Northline Care, phone: a 4:5 picture with the house and the heat pump, the words on a dark fade at its foot */
@media (max-width: 760px) {
  .care-panel { display: grid; padding: 0; }
  .care-pic, .care-copy { grid-area: 1 / 1; }
  /* (35% put the words over the house: 64% keeps the house and the heat pump above them) */
  .care-pic img { aspect-ratio: 4 / 5; object-position: 50% 64%; }
  .care-pic::after { background: linear-gradient(180deg, var(--night) 0%, rgba(11, 17, 23, 0) 6%, rgba(11, 17, 23, 0) 50%, rgba(11, 17, 23, .82) 70%, var(--night) 100%); }
  .care-copy { align-self: end; margin: 0; padding: 0 var(--pad) 24px; gap: 12px; z-index: 1; }
  .care-copy .care-actions { margin-top: 20px; }
}

/* Every Room, All Year: a section title like the others; the season, Summer and Winter and the temperatures in a bar under the picture */
.cut-head h2 { font-size: var(--s2); line-height: 1.1; }
.cut-pin { display: flex; flex-direction: column; }
.js .cut.pinned .cut-pin { position: sticky; top: var(--head-h); height: calc(100svh - var(--head-h) - 72px); min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.cut .cut-stage, .js .cut.pinned .cut-stage { position: relative; inset: auto; z-index: 0; flex: 1 1 auto; min-height: 0; container-type: size; }
.js .cut.pinned .cut-stage { aspect-ratio: auto; }
.cut .cut-foot, .js .cut.pinned .cut-foot { position: static; inset: auto; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; justify-items: stretch; gap: 12px 32px;
  padding: 16px max(var(--pad), calc((100% - 1344px) / 2 + var(--pad))); }
.cut .cut-left, .js .cut.pinned .cut-left { display: flex; flex-wrap: wrap; align-items: center; gap: 0 32px; text-align: left; }
.cut .cut-season, .js .cut.pinned .cut-season { justify-items: start; font-size: var(--s3); }
.cut .readouts, .js .cut.pinned .readouts { order: 0; justify-self: end; align-self: center; }
.cut .readout:last-child { padding-right: 0; }
/* the picture and its air drawing share one box with the picture's own shape (like object-fit: cover), so the air stays on the ducts */
/* computer: as big as the band allows, but never so big that the roof or the basement is cut (then the sides go soft) */
.cut-scene img, .cut-scene .air { inset: auto; left: 50%; transform: translateX(-50%); max-width: none; object-fit: fill;
  --ch: min(max(66.25cqw, 100cqh), 126cqh);
  width: calc(var(--ch) * 1.50943); height: var(--ch); top: calc((100cqh - var(--ch)) * .9); }
@media (min-width: 761px) {
  .cut-scene img { -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%); mask-image: linear-gradient(90deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%); }
  .cut-stage::after { background: linear-gradient(0deg, var(--night) 0%, rgba(11, 17, 23, 0) 40px); }
}
@media (max-width: 760px) {
  .cut-scene img, .cut-scene .air { width: max(100cqw, 46.243cqh); height: max(216.25cqw, 100cqh); top: calc((100cqh - max(216.25cqw, 100cqh)) * .5); }
  .cut .cut-season, .js .cut.pinned .cut-season { font-size: var(--s4); }
  .cut .cut-left, .js .cut.pinned .cut-left { gap: 0 24px; }
  .cut .cut-foot, .js .cut.pinned .cut-foot { gap: 8px 16px; }
  .cut .readout, .js .cut.pinned .readout { padding: 0 12px; }
}
/* Summer air like winter air: crisp dashes about 3 px wide with arrowheads, in the site blue (widths set by tesla.js for the picture's size) */
.cut .air .flow path { stroke-width: var(--flow-w, 3.4); stroke-opacity: 1; }
.cut .air .glow path { stroke-width: var(--glow-w, 11); }
.air.cool .flow path { stroke: #9CC4E2; }
.air.cool .glow path { stroke: #9CC4E2; stroke-opacity: .5; }

/* What We Do: the same list as the app (20 px names; the open one white and 600, one 16 px line, the links, the 2 px blue line) */
@media (min-width: 761px) {
  .svc-name { font: 500 var(--s3)/1.3 var(--display); letter-spacing: 0; padding: 14px 0; color: var(--muted); }
  .svc-item.is-on .svc-name { font: 600 var(--s3)/1.3 var(--display); letter-spacing: 0; padding: 14px 0 4px; color: var(--stone); }
  .svc-more p { font-size: var(--s4); line-height: 1.5; }
  .svc-actions { padding: 8px 0 16px; }
  /* about 35% of a screen of held scroll for each service, so one turn of the wheel never skips to the end */
  .js .svc { height: calc(100vh + 6 * 35vh); height: calc(100svh + 6 * 35svh); }
}
@media (max-width: 760px) {
  .svc-name { font: 600 var(--s3)/1.3 var(--display); letter-spacing: 0; }
  .svc-more p { font-size: var(--s4); line-height: 1.5; }
}

/* Services menu: the words start on the page grid, one Services column and one More column, the panel as big as its content plus 48 px */
.mega { left: 0; right: auto; width: max-content; max-width: 100%; grid-template-columns: auto auto 280px; justify-content: start; gap: 64px; padding: 48px; border-radius: 0 0 4px 4px; }
@media (max-width: 760px) {
  .mega { width: auto; max-width: none; grid-template-columns: 1fr; gap: 16px; padding: 8px 0 24px; border-radius: 0; }
  .mega .mega-col:first-child .mega-head { display: none; }     /* the Services button is right above it */
  .mega .mega-dup { display: none; }                             /* Care Plan and About are already in the menu */
  .mega .mega-card { display: none; }                            /* the picture card is for the computer menu */
}

/* Brands: a tidy grid with thin lines between the names */
.brands { padding: 80px 0; }   /* a quiet strip: with the lines either side, about 180 px between its neighbours */
@media (max-width: 760px) { .brands { padding: 56px 0; } }
.brands .brand-list { display: grid; grid-template-columns: repeat(14, minmax(0, 1fr)); gap: 8px 0; max-width: none; margin: 0; }
.brands .brand-list li { grid-column: span 2; display: flex; align-items: center; justify-content: center; min-height: 40px; padding: 4px 12px; text-align: center; border-left: 1px solid var(--line); }
.brands .brand-list li:nth-child(1), .brands .brand-list li:nth-child(8) { border-left: 0; }
.brands .brand-list li:nth-child(8) { grid-column: 2 / span 2; }
@media (max-width: 960px) {
  .brands .brand-list { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 0; }
  .brands .brand-list li, .brands .brand-list li:nth-child(8) { grid-column: span 2; min-height: 64px; padding: 8px; border-left: 1px solid var(--line); }
  .brands .brand-list li:nth-child(3n+1) { border-left: 0; }
  .brands .brand-list li:nth-child(n+4) { border-top: 1px solid var(--line); }
  .brands .brand-list li:nth-child(13) { grid-column: 3 / span 2; }
}

/* The estimate: a keyboard jump lands on the step or the picked choice, with a ring */
.step-label { width: fit-content; }
.step-label:focus { outline: none; }
.step-label:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 4px; border-radius: 4px; }

/* Services and About: 48 px from the words to the banner; a smaller banner and jump links on Services */
.page-head { padding: 64px 0 0; }
.page-head .page-banner { margin: 48px 0 0; }
.page-head + .section { padding-top: var(--section); }
.banner-services img { aspect-ratio: 3 / 1; }
.jump { display: flex; flex-wrap: wrap; gap: 0 32px; margin-top: 16px; }
.jump a { display: inline-flex; align-items: center; min-height: 44px; font-weight: 500; text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 6px; }
.jump a:hover { color: var(--accent-text); text-decoration-color: currentColor; }
.page-head:has(.jump) + .section { padding-top: 48px; }
@media (min-width: 761px) {
  /* every service picture the same size (646 x 484 at 1440) */
  .svc-row { grid-template-columns: minmax(0, 646fr) minmax(0, 538fr); gap: 64px; }
  .svc-row:nth-child(even) { grid-template-columns: minmax(0, 538fr) minmax(0, 646fr); }
}
@media (max-width: 760px) {
  .page-head { padding: 40px 0 0; }
  .page-head .page-banner { margin-top: 32px; }
  .banner-services img { aspect-ratio: 16 / 9; }
  .jump { gap: 0 24px; }
  .page-head:has(.jump) + .section { padding-top: 32px; }
}
/* Care, Financing and Rebates: one row of three, each with its next step */
.trio { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 48px 64px; }
.trio-col h2 { margin-bottom: 16px; }
#financing { margin-bottom: 0; }
.trio-col .lead { max-width: 34ch; }
.trio-links { margin-top: 16px; }
@media (max-width: 960px) { .trio { grid-template-columns: minmax(0, 1fr); gap: 40px; } }
/* the email breaks only after the @ */
.facts .email { overflow-wrap: normal; word-break: normal; }
/* the soft sides are the picture itself, blurred (the tiny stand-in stays under it while the picture loads) */
@media (min-width: 761px) {
  .cut-scene[data-season="summer"]::before { background-image: url("assets/story/cut-day-tall.webp"), var(--ph-wide, none); filter: blur(28px) saturate(.7) brightness(.7); }
  .cut-scene[data-season="winter"]::before { background-image: url("assets/story/cut-night-tall.webp"), var(--ph-wide, none); filter: blur(28px) brightness(.8); }
  .cut-scene::before { background-size: cover; background-position: center 90%; }
}
/* Northline Care, computer: no empty band above the picture; a link to #care lands with the title, the words and the button above the Ask bar */
@media (min-width: 761px) {
  .care-panel { padding-top: 0; padding-bottom: var(--section); }
  .care-pic::after { background: linear-gradient(180deg, var(--night) 0%, rgba(11, 17, 23, .4) 8%, rgba(11, 17, 23, 0) 20%, rgba(11, 17, 23, 0) 55%, rgba(11, 17, 23, .6) 80%, var(--night) 100%); }
}
/* a heading and the line under it never touch (About: Our Own Crew, Get an Estimate) */
.two-col h2 + .lead { margin-top: 16px; }

/* ==================== 23 Oct, judges round 6 (design 6.5, UX 7) ==================== */
/* Hero, computer: the picture full width with only a soft top edge, its top just under the buttons (tesla.js measures --pic-top),
   so the lit window sits under the buttons as in the poster still; 15% brighter, no halo, no side fades */
@media (min-width: 761px) and (min-aspect-ratio: 4/5) {
  .panel-top .scene img, .panel-top .scene video { inset: auto; left: 0; top: var(--pic-top, 336px); width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; object-position: 50% 0;
    transform: none; filter: brightness(1.4) contrast(1.05);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 40px); mask-image: linear-gradient(180deg, transparent 0, #000 40px); -webkit-mask-composite: source-over; mask-composite: add; }
  .panel-top .scene::after { content: none; }
  .panel-top .rain { display: none; }
}
/* the pause button: one place on every size, bottom right on the content grid's right edge, clear of the Ask button and the phone bar */
.video-ctl { left: auto; top: auto; right: max(var(--pad), calc((100% - 1344px) / 2 + var(--pad))); bottom: 88px; }
/* Hero, phone: the window starts about 330 px down, the words on a clean dark fade, Book a Repair on its own dark fill */
@media (max-width: 760px) {
  .panel-top .scene img { transform: translateY(14.3%) scale(1.15); }
  .panel-top .shade { background: linear-gradient(180deg, #0B1117 0, rgba(11, 17, 23, .94) 140px, rgba(11, 17, 23, .72) 220px, rgba(11, 17, 23, .3) 270px, rgba(11, 17, 23, 0) 300px); }
}
.btn-on-pic { background: rgba(11, 17, 23, .6); }
.btn-on-pic:hover { background: rgba(11, 17, 23, .75); }

/* Every Room, All Year, computer: the band framed inside the content box with 4 px corners; the picture always covers it
   (no blurred sides); the sky meets the page on a soft dark fade, not a hard line */
@media (min-width: 761px) {
  .cut .cut-stage, .js .cut.pinned .cut-stage { margin: 0 max(var(--pad), calc((100% - 1344px) / 2 + var(--pad))); border-radius: 4px; overflow: hidden; isolation: isolate; }
  .cut-scene img, .cut-scene .air { --ch: max(66.25cqw, 100cqh); top: calc((100cqh - var(--ch)) * .8); -webkit-mask-image: none; mask-image: none; }
  .cut-scene::before, .cut-scene[data-season="summer"]::before, .cut-scene[data-season="winter"]::before { inset: 0; background-image: var(--ph-wide, none); filter: blur(16px); }
  .cut-stage::after { background: linear-gradient(180deg, var(--night) 0, rgba(11, 17, 23, .55) 40px, rgba(11, 17, 23, 0) 128px); }
}
/* the air: crisp 2 px dashes with arrowheads in both seasons (summer in cool blue #7CC4FF), drawn along each duct as you scroll
   (tesla.js reveals the dashes with a mask); a faint halo under them */
.cut .air .flow path { stroke-width: var(--flow-w, 2.2); }
.cut .air .glow path { stroke-width: var(--glow-w, 8); stroke-opacity: .32; filter: blur(5px); }
.air.cool .flow path { stroke: #7CC4FF; }
.air.cool .glow path { stroke: #7CC4FF; }
/* Summer and Winter work: a tap scrolls the held scene to that season (tesla.js) */
.season-switch.indicator { pointer-events: auto; }
.season-switch.indicator button { cursor: pointer; }
.season-switch.indicator button:hover { color: #fff; }

/* One picture grade across the site (the SVG filter in each page): cool shadows near #0B1117, warm highlights, 15% less colour.
   The About crew pictures are graded in their files (greens cut, more contrast) and get a dark vignette. */
.svc-stage img, .svc-ph img, .svc-row figure img, .shop-pic img, .mega-card img { filter: url(#grade); }
.banner-services img { filter: url(#grade) saturate(.8); }
.banner-about img { filter: none; }
.svc-stage, .svc-ph, .svc-row figure, .shop-pic { border-radius: 4px; overflow: hidden; }
.pic-frame { position: relative; display: block; overflow: hidden; border-radius: 4px; }
.pic-frame img { border-radius: 0; }
.pic-frame.vignette::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse 75% 75% at 50% 45%, rgba(11, 17, 23, 0) 55%, rgba(11, 17, 23, .55) 100%); }

/* Services menu, computer: a full-width panel under the header, the words on the grid, the picture card at the grid's right edge;
   the page behind dims and blurs */
@media (min-width: 761px) {
  .mega { position: fixed; top: var(--head-h); left: 0; right: 0; width: auto; max-width: none; border-radius: 0;
    grid-template-columns: max-content max-content minmax(0, 1fr) 360px; column-gap: 64px; padding: 48px max(var(--pad), calc((100% - 1344px) / 2 + var(--pad))); }
  .mega .mega-card { grid-column: 4; }
  .mega-card img { width: 360px; height: 230px; aspect-ratio: auto; }
  .mega-dim { position: fixed; inset: 0; z-index: 45; background: rgba(5, 8, 12, .6); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); opacity: 0; visibility: hidden; transition: opacity .25s, visibility 0s .25s; }
  .mega-dim.on { opacity: 1; visibility: visible; transition: opacity .25s; }
}
.mega-dim { display: none; }
@media (min-width: 761px) { .mega-dim { display: block; } }

/* Brands: no lines; one centred row that wraps, 48 px apart, a name never breaks (computer); two columns on a phone */
.brands .brand-list { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px 48px; max-width: 1248px; margin: 0 auto; }
.brands .brand-list li:nth-child(n) { grid-column: auto; min-height: 0; padding: 0; border: 0; white-space: nowrap; }
@media (max-width: 760px) {
  .brands .brands-title { text-align: left; }
  .brands .brand-list { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); justify-content: start; gap: 12px 24px; }
  .brands .brand-list li:nth-child(n) { justify-content: flex-start; text-align: left; white-space: normal; }
}

/* services.html: Care, Financing and Rebates share one line for their links; the last service has no second rule under it */
.trio-col { display: flex; flex-direction: column; }
.trio-col .trio-links { margin-top: auto; padding-top: 16px; }
.svc-row:last-child { border-bottom: 0; }

/* Header, top of the home page: while Get an Estimate waits, the number sits at the grid's right edge and slides left as the button comes in */
@media (min-width: 961px) {
  .head-est { max-width: 240px; overflow: hidden; transition: opacity .3s .15s, max-width .45s var(--ease), padding .45s var(--ease), margin .45s var(--ease), border-width .45s; }
  .home .head-est.wait { max-width: 0; padding-left: 0; padding-right: 0; margin-left: -16px; border-width: 0;
    transition: opacity .2s, max-width .45s var(--ease), padding .45s var(--ease), margin .45s var(--ease), border-width .45s, visibility 0s .45s; }
}

/* Phone: a link lands right under the header (64 px), no strip of the section before */
@media (max-width: 760px) { html { scroll-padding-top: var(--head-h); } }

/* Phone estimate: the form right under the words, the phone number after it (a link to #estimate lands on the form: tesla.js) */
@media (max-width: 760px) {
  #estimate .two-col { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
  #estimate .call-side { display: contents; }
  #estimate .form-card { order: 1; margin-top: 32px; }
  #estimate .big-call { order: 2; align-self: flex-start; }
}
/* The thank you: the phone number never breaks */
.done-recap .nowrap { white-space: nowrap; }

/* Phone, What We Do: the six names as a row of 44 px buttons above the cards, the one in view filled; card titles 44 px tall */
.svc-pills { display: none; }
@media (max-width: 760px) {
  .svc-pills { display: flex; gap: 8px; overflow-x: auto; margin: 0 calc(-1 * var(--pad)) 16px; padding: 0 var(--pad) 4px; scrollbar-width: none; }
  .svc-pills::-webkit-scrollbar { display: none; }
  .svc-pills button { flex: none; height: 44px; padding: 0 16px; border-radius: 22px; border: 1px solid var(--line-strong); background: none; color: var(--stone); font: 500 var(--s4)/1 var(--text); white-space: nowrap; cursor: pointer; }
  .svc-pills button[aria-pressed="true"] { background: var(--stone); border-color: var(--stone); color: var(--ink); }
  .svc-item .svc-name { display: flex; align-items: center; min-height: 44px; padding: 0; }
  .svc-dots { display: none; }
}

/* The email is a link (footer and Contact) */
.facts a.email { display: inline-block; padding: 12px 0; margin: -12px 0; color: var(--stone); text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 6px; overflow-wrap: normal; word-break: normal; }
.facts a.email:hover { color: var(--accent-text); text-decoration-color: currentColor; }

/* ==================== 23 Oct, judges round 7 (design 7, UX 5) ==================== */
/* 1. The phone menu: a header with a blur (scrolled, or Services and About) made the fixed menu size itself to the 64 px header,
      so the menu was cut off. While the menu is open the header is solid, so it needs no blur. */
.site-head.menu-open, body.page .site-head.menu-open { -webkit-backdrop-filter: none; backdrop-filter: none; }
@media (max-width: 760px) { body.page .site-head.menu-open { background: var(--ink-3); } }

/* 12. Phone header 56 px with no phone icon (Call is in the bar); the bar 60 px: Call filled, Estimate and Ask as plain words (44 px to tap) */
@media (max-width: 760px) {
  :root { --head-h: 56px; }
  .head-call { display: none; }
  .call-bar { padding: 7px var(--pad) calc(8px + env(safe-area-inset-bottom)); gap: 8px; }
  .call-bar .btn { height: 44px; padding: 0 8px; }
  .call-bar .btn-line, .call-bar .btn-line:hover { border-color: transparent; background: none; }
  .call-bar .btn-line:hover { text-decoration: underline; text-underline-offset: 6px; }
  body { padding-bottom: calc(60px + env(safe-area-inset-bottom)); }
}
/* the held bands leave room for the 60 px bar on a phone (72 px for the Ask button on a computer) */
@media (max-width: 760px) {
  .js .cut.pinned .cut-pin { height: calc(100svh - var(--head-h) - 60px); }
}

/* 8. 761 to 1199 px (1024 tablets): the number shows beside the phone icon whenever the Estimate button is not there
      (the first screen, or while another blue button is on screen); it slides shut as Estimate comes in */
@media (min-width: 761px) and (max-width: 1199px) {
  .head-call { width: auto; min-width: 44px; justify-content: center; gap: 0; }
  .hc-num { position: static; display: inline-block; width: auto; height: auto; clip: auto; overflow: hidden; max-width: 0; margin-left: 0; white-space: nowrap;
    transition: max-width .45s var(--ease), margin-left .45s var(--ease); }
  .head-actions:has(.head-est.wait) .hc-num { max-width: 9em; margin-left: 8px; }
}
@media (min-width: 761px) and (max-width: 960px) { .hc-num { max-width: 9em; margin-left: 8px; } }

/* 10. One blue button per screen on every page (tesla.js watches every blue button in the page) */
.head-est.wait { opacity: 0; pointer-events: none; visibility: hidden; }
@media (min-width: 961px) {
  .head-est.wait { max-width: 0; padding-left: 0; padding-right: 0; margin-left: -16px; border-width: 0;
    transition: opacity .2s, max-width .45s var(--ease), padding .45s var(--ease), margin .45s var(--ease), border-width .45s, visibility 0s .45s; }
}

/* 13. Phone top: the picture ends 24 px under the heat pump's pad. The picture is sized by the screen width (115%) and placed so the lit
       window starts 30 px under the buttons (tesla.js measures --pic-top); the window is 27.8% down the picture and the pad ends at 68.8%. */
@media (max-width: 760px) {
  .panel-top { height: calc(var(--pic-top, 330px) + 101.96vw + 24px); min-height: 0; }
  .panel-top .scene img { inset: auto; left: -7.5vw; top: calc(var(--pic-top, 330px) - 69.14vw); width: 115vw; height: 248.69vw; max-width: none; transform: none; object-fit: cover; }
  .panel-top::after { height: 32px; }
  /* 18. Book a Repair on the picture: a solid dark fill and a 1 px line */
  .panel-top .btn-on-pic, .panel-top .btn-on-pic:hover { background: rgba(11, 17, 23, .75); border-color: rgba(255, 255, 255, .4); }
}
/* 13. Phone cut-away: the house's base sits 24 px above the caption bar (the base is 67.3% down the picture); the picture is never
       shorter than the stage, so the sky always reaches the top */
@media (max-width: 760px) {
  .cut-scene img, .cut-scene .air { --cph: max(216.25cqw, 100cqh, (100cqh - 24px) / .673); width: calc(var(--cph) / 2.1625); height: var(--cph); top: calc(100cqh - 24px - .673 * var(--cph)); }
  /* the base stays clear (a short soft edge at the foot); the sky meets the page on a soft edge at the top */
  .cut-stage::after { background: linear-gradient(180deg, var(--night) 0, rgba(11, 17, 23, 0) 56px), linear-gradient(0deg, var(--night) 0, rgba(11, 17, 23, 0) 20px); }
}

/* 11. The summer cut-away is graded in its file now (sunny, calmer greens, a deeper sky); no extra filter on top */
.cut-scene[data-season="summer"] img { filter: none; }

/* 15. services.html: the jump links are one 48 px bar that stays under the header; the service you are reading is underlined in blue.
       On a phone the bar is a sideways row. Rows about 400 px tall: the picture over 7 columns, the words over 5, in the middle. */
.jump-area .page-banner { margin: 48px 0 0; }
.jump-bar { position: sticky; top: var(--head-h); z-index: 30; margin-top: 40px; background: color-mix(in srgb, var(--ink) 94%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); box-shadow: 0 1px 0 var(--line); }
.jump-bar .jump { display: flex; flex-wrap: nowrap; gap: 0 32px; height: 48px; margin: 0; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
.jump-bar .jump::-webkit-scrollbar { display: none; }
.jump-bar .jump a { position: relative; flex: none; display: inline-flex; align-items: center; height: 48px; min-height: 0; font-weight: 400; color: var(--muted);
  text-decoration: none; white-space: nowrap; transition: color .2s; }
.jump-bar .jump a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--accent); opacity: 0; transition: opacity .2s; }
.jump-bar .jump a:hover, .jump-bar .jump a[aria-current] { color: var(--stone); }
.jump-bar .jump a[aria-current]::after { opacity: 1; }
.jump-bar .jump a:focus-visible { outline-offset: -2px; }
html:has(.jump-bar) { scroll-padding-top: calc(var(--head-h) + 48px + 24px); }
.svc-list-sec { padding-top: var(--section); }
.svc-row, .svc-row:last-child { border: 0; }
@media (min-width: 761px) {
  .svc-rows { gap: 96px; }
  .svc-row { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 64px; padding: 0; align-items: center; }
  .svc-row:nth-child(even) { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .svc-row figure img { aspect-ratio: 16 / 9; }
}
@media (max-width: 760px) {
  .jump-bar { margin-top: 24px; }
  .jump-bar > .wrap { padding: 0; }
  .jump-bar .jump { gap: 0 24px; padding: 0 var(--pad); }
  .jump-area .page-banner { margin-top: 32px; }
  .svc-rows { gap: 56px; }
  .svc-row { padding: 0; }
}

/* 16. Brands: plain words, calm. Computer: two rows of 7 and 6 set to the full grid width, 60% white, 16 px.
       Phone: one sideways row about 56 px tall. */
.brands .brand-list { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 0 32px; max-width: none; margin: 8px 0 0;
  font: 400 var(--s4)/1.5 var(--text); color: color-mix(in srgb, var(--stone) 60%, transparent); }
.brands .brand-list li:nth-child(n) { order: 0; padding: 8px 0; white-space: nowrap; }
.brands .brand-list li:nth-child(n+8) { order: 2; }
.brands .brand-list::after { content: ""; order: 1; flex-basis: 100%; height: 0; }
@media (max-width: 760px) {
  .brands { padding: 56px 0 32px; }
  .brands .brand-list { flex-wrap: nowrap; justify-content: flex-start; height: 56px; margin: 8px calc(-1 * var(--pad)) 0; padding: 0 var(--pad); gap: 0 32px;
    overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
  .brands .brand-list::-webkit-scrollbar { display: none; }
  .brands .brand-list::after { content: none; }
  .brands .brand-list li:nth-child(n) { order: 0; flex: none; padding: 0; }
}

/* 17. Corners: 4 px for buttons, tiles, chips, tabs and pictures (only the Ask button is fully round). The phone pills are 4 px tabs. */
.video-ctl { border-radius: 4px; }
@media (max-width: 760px) { .svc-pills button { border-radius: 4px; } }

/* 19. Northline Care: one full-height scene like the top. The heading, the sentence and the button centred at the top on a dark fade,
       the house below, a fade to the page at the end, then about 120 px to My Northline. */
/* (the scene is one screen under the header, so a link to #care shows all of it, the fade at its foot too) */
.care-panel { display: block; height: calc(100vh - var(--head-h)); height: calc(100svh - var(--head-h)); min-height: 600px; max-height: 1000px; padding: 0; margin-bottom: 24px; overflow: hidden; }
.care-panel .care-pic { position: absolute; inset: 0; overflow: hidden; }
.care-panel .care-pic img { width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover; object-position: 50% 40%; transform: none; filter: none; }
.care-panel .care-pic::after { background: linear-gradient(180deg, var(--night) 0%, rgba(11, 17, 23, .84) 12%, rgba(11, 17, 23, .5) 24%, rgba(11, 17, 23, 0) 38%,
  rgba(11, 17, 23, 0) 78%, rgba(11, 17, 23, .7) 92%, var(--night) 100%); }
.care-panel .care-copy { position: absolute; z-index: 1; left: 0; right: 0; top: 48px; margin: 0 auto; padding: 0 var(--pad);
  display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 12px; text-align: center; }
.care-panel .care-copy p { margin: 0 auto; max-width: 46ch; color: #DDE3E8; }
.care-panel .care-actions { justify-content: center; margin-top: 24px; }
/* short computer screens (1024 x 768, 1280 x 720): the house sits a little lower, so the button never touches the roof
   (the strip it leaves at the top is under the dark fade) */
@media (min-width: 761px) and (max-height: 820px) { .care-panel .care-pic img { transform: translateY(48px); } }
@media (max-width: 760px) {
  .care-panel { display: block; height: 620px; min-height: 0; max-height: none; margin-bottom: 0; }
  .care-panel .care-pic img { object-position: 50% 0%; }
  .care-panel .care-copy { top: 40px; gap: 8px; }
  .care-panel .care-actions { flex-direction: row; margin-top: 20px; }
  .care-panel .care-actions .btn { width: auto; }
  .care-panel .care-pic::after { background: linear-gradient(180deg, var(--night) 0%, rgba(11, 17, 23, .86) 22%, rgba(11, 17, 23, .4) 37%, rgba(11, 17, 23, 0) 47%,
    rgba(11, 17, 23, 0) 80%, rgba(11, 17, 23, .7) 92%, var(--night) 100%); }
}

/* services.html Contact at 961 to 1199 px (1024 tablets): the three facts under the heading, full width, so the email never runs
   off the page (it made the page scroll sideways by 1 px at 1024) */
@media (min-width: 961px) and (max-width: 1199px) { #contact .two-col { grid-template-columns: minmax(0, 1fr); gap: 48px; } #contact .facts { margin-top: 0; } }

/* 20. One page colour (#0B1117): sections are kept apart by space, not by lighter bands or thin lines (the estimate, contact and
       About's last band were #121A22; the brands had lines) */
.call-band { background: var(--ink); }
.section + .section { border-top: 0; }

/* 21. Two weights only: 400 and 600 */
b, strong { font-weight: 600; }
.btn { font-weight: 600; }
.nav-link, .head-call, .mega-card span, .jump a, .svc-pills button, .app-pause, .readout b, .brand-list { font-weight: 400; }
@media (min-width: 761px) { .svc-name { font-weight: 400; } .svc-item.is-on .svc-name { font-weight: 600; } }
/* the "Sample picture until the photo visit." lines in the second text colour */
.muted { color: var(--muted); }

/* Light look: the white logo turns dark wherever it sits on a light surface (header once solid, inner pages, the footer) */
[data-theme="light"] .site-head.solid .wordmark img, [data-theme="light"] body.page .site-head .wordmark img,
[data-theme="light"] .site-head.open-mega .wordmark img, [data-theme="light"] .site-head.menu-open .wordmark img,
[data-theme="light"] .foot-logo { filter: brightness(0) opacity(.88); }

/* ==================== 23 Oct, judges round 8 (design 7, UX 8) ==================== */
/* 1. services.html: the top is one full-screen picture like the home page's Care panel: "Our Services" (56 px) and one line on a dark
      fade over the night sky. Then the six services as a 3 by 2 grid of 4:5 picture cards (about 395 px wide at 1440): the name (20 px),
      one line (16 px) and the two links. Phone: the same top, then one column of cards under the sideways jump bar. The jump bar is for
      the phone only: on a computer the two rows show in one scroll. */
.svc-hero { position: relative; isolation: isolate; height: calc(100vh - var(--head-h)); height: calc(100svh - var(--head-h)); min-height: 600px; max-height: 1000px;
  overflow: hidden; background: var(--night); color: #fff; }
.svc-hero-pic { position: absolute; inset: 0; display: block; }
.svc-hero-pic img { width: 100%; height: 100%; max-width: none; object-fit: cover; object-position: 50% 80%; }
.svc-hero-pic::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(180deg, var(--night) 0%, rgba(11, 17, 23, .84) 12%,
  rgba(11, 17, 23, .5) 24%, rgba(11, 17, 23, 0) 38%, rgba(11, 17, 23, 0) 78%, rgba(11, 17, 23, .7) 92%, var(--night) 100%); }
.svc-hero-copy { position: absolute; z-index: 1; left: 0; right: 0; top: 96px; margin: 0 auto; display: grid; justify-items: center; gap: 16px; text-align: center; }
.svc-hero-copy h1 { font-size: var(--s1); }
.svc-hero-copy p { max-width: 40ch; font-size: var(--s3); line-height: 1.45; color: #DDE3E8; }
.svc-grid-sec { padding-top: var(--section); }
.svc-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 64px 32px; }
.svc-card figure { border-radius: 4px; overflow: hidden; }
.svc-card figure img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; filter: url(#grade); }
.section .svc-card h2 { margin-top: 20px; font: 600 var(--s3)/1.3 var(--display); letter-spacing: 0; }
.svc-card > p { margin-top: 4px; color: var(--muted); text-wrap: pretty; }
.svc-card > p.svc-card-links { display: flex; flex-wrap: wrap; gap: 0 24px; margin-top: 4px; color: var(--stone); }
@media (min-width: 761px) {
  .jump-bar { display: none; }
  html:has(.jump-bar) { scroll-padding-top: 88px; }
}
@media (min-width: 761px) and (max-width: 960px) { .svc-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px) {
  .svc-hero { height: calc(100svh - var(--head-h) - 60px); min-height: 520px; max-height: none; }
  .svc-hero-pic img { object-position: 50% 34%; }
  .svc-hero-pic::after { background: linear-gradient(180deg, var(--night) 0%, rgba(11, 17, 23, .8) 18%, rgba(11, 17, 23, 0) 34%, rgba(11, 17, 23, 0) 80%, var(--night) 100%); }
  .svc-hero-copy { top: 40px; gap: 8px; padding: 0 var(--pad); }
  .jump-bar { margin-top: 0; }
  .svc-cards { grid-template-columns: minmax(0, 1fr); gap: 48px; }
  .section .svc-card h2 { margin-top: 16px; }
}

/* 2. Phone, Every Room, All Year: the title and the season line in the empty sky, about 96 px from the top of the held scene
      (tesla.js moves them there); no separate title block above it. Computer: the title stays above the band (the roof fills the top). */
.cut-sky { display: none; }
@media (max-width: 760px) {
  .js .cut-head { display: none; }
  .cut-sky { position: absolute; z-index: 2; left: var(--pad); right: var(--pad); top: 96px; display: grid; justify-items: center; gap: 8px; text-align: center; color: #fff; pointer-events: none; }
  .cut-sky h2 { font-size: var(--s2); line-height: 1.1; }
  .cut .cut-sky .cut-season, .js .cut.pinned .cut-sky .cut-season { justify-items: center; font-size: var(--s3); line-height: 1.4; max-width: 24ch; }
}

/* 3. Phone first screen: the window's glow starts under the buttons. The picture sits 48 px lower and the shade stays .92 dark down to
      320 px, so both buttons are on a calm dark ground; Book a Repair keeps its solid dark fill. */
@media (max-width: 760px) {
  .panel-top { height: calc(var(--pic-top, 330px) + 48px + 101.96vw + 24px); }
  .panel-top .scene img { top: calc(var(--pic-top, 330px) + 48px - 69.14vw); }
  .panel-top .shade { background: linear-gradient(180deg, #0B1117 0, rgba(11, 17, 23, .92) 140px, rgba(11, 17, 23, .92) 320px, rgba(11, 17, 23, 0) 372px); }
}

/* 4. Tablets (761 to 1100 px), the top of the Care panel: no hard edge. The picture sits 80 px down (so Ask About Care stays clear of the
      roof) and its top edge is under solid page colour, then a soft fade to clear (dark enough under the words for 4.5:1); 96 px of
      space above the title.
      Short computer screens (the 48 px lower picture of round 7): the same solid top over the picture's edge. */
@media (min-width: 761px) and (max-width: 1100px) {
  .care-panel .care-pic img { transform: translateY(80px); }
  .care-panel .care-pic::after { background: linear-gradient(180deg, var(--night) 0, var(--night) 80px, rgba(11, 17, 23, .84) 200px, rgba(11, 17, 23, .5) 300px, rgba(11, 17, 23, 0) 400px),
    linear-gradient(0deg, var(--night) 0, rgba(11, 17, 23, .7) 64px, rgba(11, 17, 23, 0) 160px); }
  .care-panel .care-copy { top: 96px; }
}
@media (min-width: 1101px) and (max-height: 820px) {
  .care-panel .care-pic::after { background: linear-gradient(180deg, var(--night) 0, var(--night) 48px, rgba(11, 17, 23, 0) 128px), linear-gradient(180deg, var(--night) 0%,
    rgba(11, 17, 23, .84) 12%, rgba(11, 17, 23, .5) 24%, rgba(11, 17, 23, 0) 38%, rgba(11, 17, 23, 0) 78%, rgba(11, 17, 23, .7) 92%, var(--night) 100%); }
}

/* 5. Services menu, computer: the second column starts at x 360 (1440 wide), and three picture cards (about 224 px wide, 4:5) fill
      x 640 to 1344: Heat Pumps, Every Room All Year, Northline Care. Narrower screens show fewer cards. */
.mega-cards { display: none; }
@media (min-width: 761px) {
  .mega { grid-template-columns: 200px 216px minmax(0, 1fr); column-gap: 64px; }
  .mega .mega-cards { grid-column: 3; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; align-content: start; }
  .mega .mega-cards .mega-card { grid-column: auto; display: grid; gap: 12px; align-content: start; }
  .mega-cards .mega-card img { width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 4px; }
  .mega-cards .mega-card:nth-child(2) img { object-position: 50% 55%; }
  .mega-cards .mega-card:nth-child(3) img { object-position: 44% 64%; }
  .mega-cards .mega-card span { line-height: 1.3; }
}
@media (min-width: 961px) and (max-width: 1199px) { .mega .mega-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } .mega-cards .mega-card:nth-child(3) { display: none; } }
@media (min-width: 761px) and (max-width: 960px) { .mega .mega-cards { grid-template-columns: minmax(0, 1fr); } .mega-cards .mega-card:nth-child(1), .mega-cards .mega-card:nth-child(3) { display: none; } }

/* 6. Brands (home and About), computer: a 7 column grid; each name starts at the left of its cell, so the two rows line up.
      761 to 1199 px: 5 columns. Phone: the sideways row stays. */
.brands .brands-title { text-align: left; }
@media (min-width: 761px) {
  .brands .brand-list { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 0 32px; justify-content: stretch; align-items: center; }
  .brands .brand-list::after { content: none; }
  .brands .brand-list li:nth-child(n) { order: 0; display: block; padding: 8px 0; text-align: left; white-space: nowrap; }
}
@media (min-width: 761px) and (max-width: 1199px) { .brands .brand-list { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0 24px; } }

/* 7. Home top picture, computer: the left window was redder and darker than the right one. One soft colour-dodge patch over the left
      pane lifts it to the right pane's warm yellow, on the still and the video alike (they share one frame). */
.win-box { display: none; }
@media (min-width: 761px) and (min-aspect-ratio: 4/5) {
  .win-box { display: block; position: absolute; left: 0; top: var(--pic-top, 336px); width: 100%; aspect-ratio: 16 / 9; pointer-events: none; mix-blend-mode: color-dodge;
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 40px); mask-image: linear-gradient(180deg, transparent 0, #000 40px); }
  .win-warm { position: absolute; left: 53.4%; top: 0; width: 9.5%; height: 10.4%; background: rgb(0, 118, 78); filter: blur(2px); }
}

/* 10. Small type: About's three facts read as a band of big words (36 px); panel lines never break badly */
#shop .facts b { font-size: var(--s2); line-height: 1.1; letter-spacing: -.02em; margin-bottom: 8px; }
.panel-copy p, .care-copy p, .svc-hero-copy p, .trio-col .lead, .page-head .lead { text-wrap: balance; }

/* 13. After a jump from another page the place itself has the keyboard focus (tesla.js), without a ring */
.land-focus:focus { outline: none; }

/* 12. Less motion (the band does not hold): the band is one screen tall all the same, so a link to #all-year shows the picture, the line,
       Summer and Winter and the temperatures together, clear of the Ask button (computer) or the call bar (phone) */
.cut:not(.pinned) .cut-pin { height: calc(100vh - var(--head-h) - 72px); height: calc(100svh - var(--head-h) - 72px); min-height: 480px; }
@media (max-width: 760px) { .cut:not(.pinned) .cut-pin { height: calc(100svh - var(--head-h) - 60px); } }

/* ==================== 23 Oct, judges round 9 (design 7.5, UX 8) ==================== */
/* 2. Phone first screen: the computer's picture cropped to the heat pump (assets/phone/top-night-r9.webp, PIL): no orange sky, the
      window whole with its top frame, the left pane as yellow as the right. The window's panes start 48 px under the buttons
      (20.89vw down the picture), the wall above them fades into the page colour, and the dark shade over the buttons fades out
      over the 120 px above the window. The old picture's tiny blurred stand-in (orange) is not drawn. */
@media (max-width: 760px) {
  .panel-top .scene::before { display: none; }
  .panel-top { height: calc(var(--pic-top, 330px) + 48px + 96.83vw + 24px); }
  .panel-top .scene img { left: -7.5vw; top: calc(var(--pic-top, 330px) + 48px - 20.89vw); width: 115vw; height: 129.81vw; filter: brightness(1.4) contrast(1.05);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, rgba(0, 0, 0, .45) 7%, #000 12.6%); mask-image: linear-gradient(180deg, transparent 0, rgba(0, 0, 0, .45) 7%, #000 12.6%); }
  .panel-top .shade { background: linear-gradient(180deg, #0B1117 0, rgba(11, 17, 23, .92) 140px, rgba(11, 17, 23, .92) calc(var(--pic-top, 330px) + 48px - 120px),
    rgba(11, 17, 23, 0) calc(var(--pic-top, 330px) + 48px)); }
}
/* 3. Computer first screen (1440 and 1024): the poster with the window's top frame and some wall mirrored above it
      (assets/story/top-night-poster-r9.webp: 138 rows on top of the 720). The panes still start at --pic-top, where the video starts,
      so the video and the still line up; the wall above the frame fades in over its 120 px. A shade from the page colour to clear
      over the first 22% of the width calms the speckled wall on the left. The picture sits 32 px lower than before, so the new
      top frame of the window is clear of the buttons. */
@media (min-width: 761px) and (min-aspect-ratio: 4/5) {
  .panel-top .scene video, .win-box { top: calc(var(--pic-top, 336px) + 32px); }
  .panel-top .scene img { top: calc(var(--pic-top, 336px) + 32px); margin-top: -10.78%; aspect-ratio: 1280 / 858;
    -webkit-mask-image: linear-gradient(180deg, transparent 0, rgba(0, 0, 0, .3) 4%, rgba(0, 0, 0, .75) 8%, #000 12.6%);
    mask-image: linear-gradient(180deg, transparent 0, rgba(0, 0, 0, .3) 4%, rgba(0, 0, 0, .75) 8%, #000 12.6%); }
  .panel-top .scene video, .win-box { -webkit-mask-image: none; mask-image: none; }
  .panel-top .shade { background:
    linear-gradient(90deg, #0B1117 0, rgba(11, 17, 23, .6) 9%, rgba(11, 17, 23, 0) 22%),
    radial-gradient(44% 22% at 50% 20%, rgba(6, 10, 14, .34) 0%, rgba(6, 10, 14, 0) 100%),
    linear-gradient(180deg, rgba(6, 10, 14, .72) 0%, rgba(6, 10, 14, .48) 24%, rgba(6, 10, 14, 0) 42%),
    linear-gradient(0deg, rgba(6, 10, 14, .62) 0%, rgba(6, 10, 14, .3) 16%, rgba(6, 10, 14, 0) 30%); }
}

/* 4. services.html top: the same calm grade as the home page (no royal blue or violet in the snowy night) */
.svc-hero-pic img { filter: saturate(.6) hue-rotate(-8deg) brightness(.9); }
@media (max-width: 760px) { .svc-hero-pic img { filter: saturate(.45) hue-rotate(-8deg) brightness(.85); } }   /* the phone picture is bluer in its file */

/* 5. services.html: Care, Financing and Rebates on the same 3 columns and 32 px gap as the cards above them */
.trio { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 48px 32px; }
.trio-col .lead { max-width: none; }
@media (min-width: 761px) and (max-width: 960px) { .trio { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px) { .trio { grid-template-columns: minmax(0, 1fr); gap: 40px; } }

/* 11. services.html cards: three short points under the line, as a quiet list with thin rules; one link (Get an Estimate).
       A link like services.html#heating lands on its card and outlines it for 2 seconds (tesla.js), then the ring fades. */
.svc-points { margin-top: 12px; border-bottom: 1px solid var(--line); color: var(--muted); }
.svc-points li { padding: 8px 0; border-top: 1px solid var(--line); }
.svc-card > p.svc-card-links { margin-top: 8px; }
.svc-card, .svc-card.land-focus:focus { border-radius: 4px; outline: 2px solid transparent; outline-offset: 12px; transition: outline-color .6s var(--ease); }
.svc-card.ring, .svc-card.ring.land-focus:focus { outline-color: var(--accent-text); transition: none; }
@media (max-width: 760px) { .svc-card, .svc-card.land-focus:focus { outline-offset: 8px; } }

/* 7. About: the shop picture as a wide 16:7 band (the duct fitting fills it); Our Own Crew's words centred against its picture */
.shop-pic img { aspect-ratio: 16 / 7; object-position: 50% 52%; }
#about-crew .two-col { align-items: center; }

/* 9. Brands (final): one centred row that wraps, 48 px between names, a name never breaks. Phone: the sideways row (round 7). */
@media (min-width: 761px) {
  .brands .brands-title { text-align: center; }
  .brands .brand-list { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px 48px; max-width: none; margin: 8px 0 0; }
  .brands .brand-list::after { content: none; }
  .brands .brand-list li:nth-child(n) { order: 0; display: block; flex: none; padding: 8px 0; text-align: center; white-space: nowrap; }
}

/* 18. Every Room, All Year, computer: the title sits inside the held picture, top left on the dark fade of the sky (tesla.js moves it
       there), so a jump from the menu card shows it with the house. The empty title block above the band keeps only a little room.
       Winter air in amber like the assistant's (#FFB062), with the same thin dark edge as summer's, so it reads on the lit rooms. */
@media (min-width: 761px) {
  .cut-head:empty { padding: 48px 0 0; }
  .cut-sky { position: absolute; z-index: 2; left: 32px; top: 24px; display: block; pointer-events: none; color: #fff; text-align: left; }
  .cut-sky h2 { font-size: var(--s2); line-height: 1.1; }
}
.air.warm .flow path { stroke: #FFB062; }
.air.warm .glow path { stroke: #FFB062; }
/* (the thin dark edge a touch stronger in both seasons, so the dashes read on the lit rooms and the bright summer walls alike) */
.cut .air .flow { filter: drop-shadow(0 0 1.5px rgba(6, 10, 14, .95)) drop-shadow(0 0 .5px rgba(6, 10, 14, .9)); }

/* ==================== 23 Oct, judges round 10 (design 8, UX 7) ==================== */
/* 1. The lit windows: warm amber (about 240, 170, 90 on screen, nothing above 245) with a soft darker band at the top of each pane, so
      they read as lit glass, not flat lemon. The still, the phone picture, the menu's Heat Pumps card and the assistant's No Heat Right
      Now card are graded in their files (-r10, PIL; the originals are in work/r10-originals). The video is not re-encoded: while it plays,
      two amber panes with the same top band sit over its panes (they never move in the clip), and fade in with it. The colour-dodge
      patch of round 8 is gone. */
@media (min-width: 761px) and (min-aspect-ratio: 4/5) {
  .win-box { mix-blend-mode: normal; opacity: 0; transition: opacity 1.2s var(--ease); }
  .top-video.playing ~ .win-box { opacity: 1; }
  .win-pane { position: absolute; top: 0; filter: blur(.6px); background: linear-gradient(180deg, rgb(140, 99, 52) 0%, rgb(147, 104, 55) 6%,
    rgb(164, 116, 62) 12%, rgb(187, 132, 70) 18%, rgb(210, 148, 79) 24%, rgb(227, 161, 85) 30%, rgb(235, 166, 88) 36%, rgb(240, 170, 90) 100%); }
  .win-l { left: 53.2%; width: 9.92%; height: 10.4%; }
  .win-r { left: 64.8%; width: 10.27%; height: 10.86%; }
}

/* 2. Headlines: the tight tracking squeezed the gaps between words ("What WeDo") */
h1, h2 { word-spacing: .05em; }

/* 6. Get an Estimate, every size: the choices are filled boxes (#18222C, a faint 1 px line); the picked one has a 2 px light blue line
      and keeps its tick. Phone: Next fills the row and is 48 px tall. */
.choice, .choice:has(input:checked) { background: var(--ink-3); color: var(--stone); }
.choice { border: 1px solid var(--line); }
.choice:hover { border-color: var(--line-strong); }
.choice:has(input:checked) { border-color: var(--accent-text); box-shadow: inset 0 0 0 1px var(--accent-text); }
.choice:has(input:checked)::after { border-color: var(--accent-text); }
@media (max-width: 760px) { .form-nav #f-next { flex: 1 1 auto; height: 48px; margin-left: 0; } }

/* 8. Brands: one centred row that wraps, on a phone too (8 px by 24 px, the title centred). Computer: the list is capped, so it breaks
      7 and 6. */
@media (min-width: 761px) { .brands .brand-list { max-width: 920px; margin: 8px auto 0; } }
@media (max-width: 760px) {
  .brands .brands-title { text-align: center; }
  .brands .brand-list { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px 24px; height: auto; margin: 8px 0 0; padding: 0; overflow: visible; }
  .brands .brand-list li:nth-child(n) { order: 0; flex: none; padding: 0; text-align: center; white-space: nowrap; }
}

/* 9. About: the sheet metal picture is a 1248 x 520 crop centred on the fitting (assets/story/shop-detail-r10.webp); 4:3 on a phone */
.shop-pic img { aspect-ratio: 1248 / 520; object-position: 50% 50%; }
@media (max-width: 760px) { .shop-pic img { aspect-ratio: 4 / 3; } }

/* 10. Phone, Every Room, All Year: no empty sky between the line and the roof. The title block sits so the line ends 48 px above the
       roof's peak (32% down the picture, whose box is worked out the same way as the picture's, so it holds on any phone). The house
       and the air drawing are not moved. */
@media (max-width: 760px) {
  .cut-sky { top: auto; bottom: calc(24px + .353 * max(216.25cqw, 100cqh, (100cqh - 24px) / .673) + 48px); }
}

/* 13. The site tour: the held bands leave the tour bar's room under them (assistant.js sets --tour-room), so Summer and Winter and
       the temperatures end 16 px above the bar */
html.js.cq-touring .cut.pinned .cut-pin, html.cq-touring .cut:not(.pinned) .cut-pin { height: calc(100svh - var(--head-h) - var(--tour-room, 72px)); }

/* 15. services.html, phone: 4:3 card pictures, so a card from the menu or the footer shows whole, its Get an Estimate above the call bar */
@media (max-width: 760px) { .svc-card figure img { aspect-ratio: 4 / 3; } }

/* 16. services.html, computer: the jump bar with the six names shows at the foot of a shorter first screen (above the Ask button), then
       stays under the header while you read the cards */
@media (min-width: 761px) {
  .jump-bar { display: block; margin-top: 0; }
  html:has(.jump-bar) { scroll-padding-top: calc(var(--head-h) + 48px + 24px); }
  .svc-hero { height: calc(100vh - var(--head-h) - 48px - 80px); height: calc(100svh - var(--head-h) - 48px - 80px); min-height: 440px; }
  .svc-grid-sec { padding-top: 64px; }
}
@media (min-width: 761px) and (max-width: 1199px) { .jump-bar .jump { gap: 0 24px; } }
/* 19. Phone: after Ask About Care or Book a Repair a link lands on the form itself, so the step line starts with the form's title */
.step-label .step-title { color: var(--stone); font-weight: 600; }

/* ==================== 23 Oct, judges round 11 (design 7, UX 6) ==================== */
/* 7. The lit windows over the video: lit glass like the still (-r11 files). A soft radial glow (245, 185, 110 in the middle to 190, 125, 60
      at the edges), faint blinds (7%), 1.5 px soft edges, and a 4 px ring in the frame's own colour that covers the video's red rim.
      The right pane a touch wider and 1 px higher (the still's pane showed 1 px above it). The lid patch (assets/story/lid-r11.webp, cut
      from the graded still) turns the pink band on the unit's lid amber; it takes the video's filter so it matches. */
@media (min-width: 761px) and (min-aspect-ratio: 4/5) {
  .win-pane { filter: blur(.75px); box-shadow: 0 0 0 4px rgb(2, 6, 24);
    background: repeating-linear-gradient(180deg, rgba(40, 20, 0, 0) 0, rgba(40, 20, 0, 0) 2px, rgba(40, 20, 0, .07) 4px, rgba(40, 20, 0, 0) 6px),
      radial-gradient(closest-side, rgb(245, 185, 110) 0%, rgb(224, 162, 91) 50%, rgb(202, 138, 71) 75%, rgb(190, 125, 60) 100%); }
  .win-l { top: -1px; height: calc(10.4% + 1px); }
  .win-r { left: 64.76%; top: -1px; width: 10.4%; height: calc(10.86% + 1px); }
  .panel-top .scene .win-box .win-lid { position: absolute; inset: auto; left: 57.03%; top: 19.72%; width: 21.09%; height: 4.17%; max-width: none; margin: 0;
    aspect-ratio: auto; object-fit: fill; transform: none; -webkit-mask-image: none; mask-image: none; filter: brightness(1.4) contrast(1.05); }
}

/* 8. The header's Get an Estimate always keeps its room (hidden, not removed), so 555-010-0100 never moves. 961 to 1199 px: the phone
      icon only (the number is in its label), so nothing slides there either. */
.head-est.wait, .home .head-est.wait { opacity: 0; visibility: hidden; pointer-events: none; }
@media (min-width: 961px) {
  .head-est, .head-est.wait, .home .head-est.wait { max-width: none; padding-left: 20px; padding-right: 20px; margin-left: 0; border-width: 1px; transition: opacity .3s, visibility 0s; }
  .head-est.wait, .home .head-est.wait { transition: opacity .2s, visibility 0s .2s; }
}
@media (min-width: 961px) and (max-width: 1199px) {
  .hc-num, .head-actions:has(.head-est.wait) .hc-num { max-width: 0; margin-left: 0; transition: none; }
}

/* 9. One gap between sections everywhere: 160 px from the last thing in one section to the first in the next on a computer, 96 px on a
      phone (each plain section has half of it above and below) */
:root { --section: 80px; --sec-gap: 160px; }
@media (max-width: 760px) { :root { --section: 48px; --sec-gap: 96px; } }
.brands { padding: var(--section) 0; }
@media (max-width: 760px) { .brands { padding: var(--section) 0; } }
.site-foot { padding-top: var(--section); }
.page-head + .section { padding-top: var(--sec-gap); }
/* Northline Care: 160 px of plain page under the readouts, then the picture starts (its fade starts under that gap) with the title at its top;
   its foot fades out about 160 px above My Northline */
.care-panel { margin-top: calc(var(--sec-gap) - 16px); }
.care-panel .care-copy { top: 0; }
@media (min-width: 761px) { .care-panel { margin-bottom: 60px; } }
/* (an in-page link to #care leaves 48 px of that gap under the header, 24 on a phone; tesla.js does the same for jumps from other pages) */
#care { scroll-margin-top: 32px; }
@media (max-width: 760px) { #care { scroll-margin-top: 24px; } }
/* Every Room, All Year: the picture starts about 160 px (96 on a phone) under the reviews */
@media (min-width: 761px) { .cut-head:empty { padding: 64px 0 0; } }
@media (max-width: 760px) { .cut { margin-top: 32px; } }

/* 10. What We Do, computer (1440 and 1024): the held part is as tall as its words. The picture ends on the list's last line (about 554 x 482
       at 1440), so there is no empty block under the list; it holds centred between the header and the Ask button (tesla.js sets
       --svc-top), and the section's spacer gives the same held scroll as before */
.svc-names { margin: 0; }
@media (min-width: 761px) {
  .js .svc { height: auto; padding: 113px 0 var(--section); }
  .js .svc::after { content: ""; display: block; height: calc(6 * 35vh); height: calc(6 * 35svh); }
  .svc-pin, .js .svc-pin { position: sticky; top: var(--svc-top, calc(var(--head-h) + 56px)); height: auto; display: block; padding: 0; overflow: visible; }
  .svc-grid { align-items: stretch; }
  .svc-stage { width: min(100%, 554px); height: auto; aspect-ratio: auto; align-self: stretch; }
}
/* phone: every card's links sit at its foot, so the gap under the row is the same whichever card shows */
@media (max-width: 760px) {
  .svc-pin { padding: 80px 0 40px; }
  .svc-names { margin: 0 calc(-1 * var(--pad)); }
  .svc-item .svc-more { flex: 1 1 auto; }
  .svc-item .svc-more > div { display: flex; flex-direction: column; height: 100%; }
  .svc-item .svc-actions { margin-top: auto; }
}

/* 13. What We Do: the links fade in over 200 ms once the item has fully opened (no half-cut links); they go at once when it closes */
@media (min-width: 761px) {
  .svc-actions { opacity: 0; transition: opacity .2s linear 0s; }
  .svc-item.is-on .svc-actions { opacity: 1; transition: opacity .2s linear .5s; }
}

/* 11. services.html, phone: the top picture ends about 48 px under the heat pump (its foot is 130.25% of the screen width down the
       picture), so the jump bar and the first card show on the first screen; the fade at its foot is only the last 40 px */
@media (max-width: 760px) {
  .svc-hero { height: calc(130.25vw + 48px); min-height: 0; max-height: none; }
  .svc-hero-pic img { object-position: 50% 0; }
  .svc-hero-pic::after { background: linear-gradient(180deg, var(--night) 0%, rgba(11, 17, 23, .8) 18%, rgba(11, 17, 23, 0) 34%, rgba(11, 17, 23, 0) calc(100% - 40px), var(--night) 100%); }
}

/* 14. A picked chip (the phone's What We Do buttons): the card colour, light words and a 2 px light blue line under them */
@media (max-width: 760px) {
  .svc-pills button[aria-pressed="true"] { background: #18222C; border-color: #18222C; color: var(--stone); box-shadow: inset 0 -2px 0 #9CC4E2; }
}
/* (with less motion Summer and Winter are a pair of buttons: the picked one the same way, not a white fill) */
.season-switch:not(.indicator) button[aria-pressed="true"] { background: #18222C; color: var(--stone); box-shadow: inset 0 -2px 0 #9CC4E2; }

/* 15. About: the shop line starts on the third column (x 949 at 1440, 395 px wide), over the third fact, with balanced lines */
@media (min-width: 761px) {
  #shop .section-head { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: var(--gap); align-items: baseline; }
  #shop .section-head h2 { grid-column: 1 / 3; }
  #shop .section-head .lead { grid-column: 3; max-width: none; text-wrap: balance; }
}

/* 16. Every Room, All Year: about half a screen of held scroll (the season turns halfway through it, tesla.js) on a computer and a phone */
.js .cut.pinned { height: calc(100vh - var(--head-h) - 72px + 50vh); height: calc(100svh - var(--head-h) - 72px + 50svh); }
@media (max-width: 760px) { .js .cut.pinned { height: calc(100svh - var(--head-h) - 60px + 50svh); } }

/* 17. The page you are on is marked in the main menu (Services on services.html, About on about.html) */
.nav-link[aria-current="page"], .mega a[aria-current="page"] { text-decoration: underline; text-decoration-thickness: 2px; text-decoration-color: var(--accent-text); text-underline-offset: 8px; }

/* 19. One quiet line in every footer: "Pictures are samples until the photo visit." (no captions under the photos) */
.foot-base { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 32px; }
.foot-base p { margin: 0; }
.foot-note { color: var(--muted); }

/* ==================== 23 Oct, judges round 12 (design 8, UX 7) ==================== */
/* 10. The lit windows over the video: one smooth radial glow (#E9B877 in the middle to #9A6A3A at the edges, eased like a smoothstep
       through its in-between stops, so there is no bright point in the middle and no ring at the edge), a 2% noise layer
       (an SVG feTurbulence) and a soft 6 px inner shadow where the glass meets the frame, at 85%. No blinds, no stepped bands.
       The still and the phone picture are painted the same way in their files (-r12, PIL: work/tools/r12_windows.py); the -r11
       files are in work/r12-originals. Under the 85% panes the video's uneven panes (one red, one lemon) are covered by one even
       amber backing per pane (the box's ::before and ::after), so both panes read the same. */
@media (min-width: 761px) and (min-aspect-ratio: 4/5) {
  .win-pane { z-index: 1; opacity: .85; filter: blur(.5px); box-shadow: inset 0 0 6px rgba(40, 20, 0, .6);
    background:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.02'/%3E%3C/svg%3E") 0 0 / 160px 160px,
      radial-gradient(closest-side, #E9B877 0%, #E1B071 20%, #CD9D62 40%, #B68650 60%, #A2723F 80%, #9A6A3A 100%); }   /* eased: no bright point, no ring */
  .win-box::before, .win-box::after { content: ""; position: absolute; z-index: 0; top: -1px; background: #B58A55;
    box-shadow: 0 0 0 4px rgb(2, 6, 24); filter: blur(.5px); }
  .win-box::before { left: 53.2%; width: 9.92%; height: calc(10.4% + 1px); }
  .win-box::after { left: 64.76%; width: 10.4%; height: calc(10.86% + 1px); }
}

/* 11. Header, computer: Get an Estimate never hides. Where it used to step aside (the first screen, Care, the form, an open menu) it
       turns to the outline style, the same size, so there is no hole and the phone number never stands alone */
@media (min-width: 961px) {
  .head-est.wait, .home .head-est.wait { opacity: 1; visibility: visible; pointer-events: auto; background: transparent; border-color: var(--line-strong);
    color: var(--stone); transition: background-color .2s, border-color .2s, color .2s; }
  .head-est.wait:hover, .home .head-est.wait:hover { border-color: var(--stone); }
  .home .site-head:not(.solid):not(.open-mega):not(.menu-open) .head-est.wait { border-color: rgba(255, 255, 255, .7); color: #fff; background: rgba(11, 17, 23, .35); }
}

/* 7. Get an Estimate: with "No heat or urgent repair" picked, one line and a Call button under the choices (tesla.js). The form still
      goes on with Next, which turns to the outline style meanwhile, so Call is the one blue button. */
.urgent-call > div { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; margin-top: 24px; }
.urgent-call > div[hidden] { display: none; }
.urgent-call p { margin: 0; font-weight: 600; color: var(--stone); }
@media (max-width: 760px) {
  .urgent-call > div { flex-direction: column; align-items: stretch; }
  .urgent-call .btn { width: 100%; }
}

/* 14. services.html Contact: the email never breaks (the third column is the wider one, and the address stays on one line) */
#contact .facts a.email { white-space: nowrap; }
@media (min-width: 1200px) { #contact .facts { grid-template-columns: auto auto auto; } }   /* each column as wide as its words, the room shared */

/* 15. services.html and about.html: the footer has no phone and email lines under the logo (taken out of the pages; the page's own
       Contact or Get an Estimate block and the header have them) */

/* 17. Phone, the sliding rows (the jump bar, What We Do's buttons): a 24 px fade at both ends, so words are never cut hard at the
       edge; at rest the fade covers only the row's 24 px side room. Scroll padding keeps a picked one clear of the fade. */
@media (max-width: 760px) {
  .jump-bar .jump, .svc-pills {
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
    scroll-padding-left: 24px; scroll-padding-right: 24px; }
}

/* 18. About, Get an Estimate (computer): the two buttons end at the page's right edge (x 1344 at 1440), level with the words */
.cta-actions { justify-content: flex-start; }
@media (min-width: 961px) { .cta-actions { justify-content: flex-end; align-self: center; } }

/* 8. services.html: a link to a card lands with the card's top at the jump bar's foot, every card and every size (tesla.js) */
/* ==================== 23 Oct, judges round 13 (design 8, UX 7) ==================== */
/* 6. (tesla.js) Get an Estimate under another title (Book a Repair, Ask About Northline Care): "At your home. Urgent calls answered 24 hours." */

/* 7. Header, 961 to 1199 px (1024 tablets): never the phone icon alone. 961 to 1099: the word "Call" beside it; 1100 to 1199: the number.
      The menu links are 4 px tighter on each side there, so the logo keeps its full size. (761 to 960 already shows the number.) */
.hc-word { display: none; }
@media (min-width: 961px) and (max-width: 1199px) { .nav-link { padding: 0 10px; } }
@media (min-width: 961px) and (max-width: 1099px) { .head-call .hc-word { display: inline; margin-left: 8px; } }
@media (min-width: 1100px) and (max-width: 1199px) {
  .hc-num, .head-actions:has(.head-est.wait) .hc-num { max-width: 9em; margin-left: 8px; }
}

/* 8. Phone menu: Call 555-010-0100 and Get an Estimate stay at the foot of the open menu, also with Services open (the list scrolls
      under them); with a short list they sit at the foot too */
@media (max-width: 760px) {
  .nav { padding-bottom: 0; }
  .nav-cta { position: sticky; bottom: 0; z-index: 2; margin-top: auto; padding: 16px 0 calc(16px + env(safe-area-inset-bottom)); background: var(--ink-3); box-shadow: 0 -1px 0 var(--line); }
  .nav > .nav-link:last-of-type { margin-bottom: 24px; }
}

/* 9. services.html cards (1440 and 1024): each card is a column, its Get an Estimate at the foot, so the links of a row line up */
.svc-card { display: flex; flex-direction: column; }
.svc-card > p.svc-card-links { margin-top: auto; padding-top: 8px; }

/* 12. One footer on every page: the logo, the phone, the email and both offices. The email and each address never break. At 1100 px
       and below the logo and its phone and email take the first row, the offices the next, then Services and Company side by side. */
.foot-email, .foot-addr { white-space: nowrap; }
@media (max-width: 1100px) {
  .foot-top { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .foot-top > .foot-brand, .foot-top > .foot-col:nth-child(2) { grid-column: 1 / -1; }
  .foot-logo { margin-bottom: 16px; }
}

/* 13. About's top picture: recropped to its top 600 rows (assets/img/banner-about-r13.webp, the r7 file is in work/r13-originals), so
       the crouching second technician is fully out at every size; the standing one and the unit stay in the middle (the picture is wider than every banner box, so it is cut
       only at its sides) */

/* 14. About, Get an Estimate band, below 480 px: the two buttons stack, full width */
@media (max-width: 479px) {
  .cta-actions { flex-direction: column; align-items: stretch; width: 100%; }
  .cta-actions .btn { width: 100%; flex: none; min-width: 0; }
}

/* 15. Home, phone: the big phone number sits under "Free, at your home", above the form (as on a computer) */
@media (max-width: 760px) {
  #estimate .big-call { order: 0; align-self: flex-start; margin-top: 24px; }
  #estimate .form-card { order: 1; }
}

/* 16. Every Room, All Year: the picture, its title and the bar under it come in together, once the summer picture is ready (tesla.js
       .cut-wait); never a title over an empty blue sky. With less motion they simply appear. */
.cut-stage, .cut-foot { transition: opacity .6s var(--ease); }
.cut.cut-wait .cut-stage, .cut.cut-wait .cut-foot { opacity: 0; }

/* 17. services.html, phone: the card lines and the Care, Financing and Rebates lines run the full width (no balanced, short lines) */
@media (max-width: 760px) {
  .svc-card > p, .trio-col .lead { text-wrap: wrap; max-width: none; }
}

/* 18. services.html, phone jump bar: a label never rests half under the 24 px fades. A swipe snaps each label to start 24 px in (the
       end of the left fade), the current one is put there too (tesla.js), and room after the last label lets Gas Fireplaces get there. */
@media (max-width: 760px) {
  .jump-bar .jump { scroll-snap-type: x mandatory; scroll-padding-left: 24px; scroll-padding-right: 24px; }
  .jump-bar .jump a { scroll-snap-align: start; }
  .jump-bar .jump::after { content: ""; flex: none; width: var(--jump-end, 0px); height: 1px; }
}
/* (16, phone) while the band comes up from below, its title waits until the house's roof is in view, then fades in (tesla.js .sky-wait) */
@media (max-width: 760px) {
  .cut-sky { transition: opacity .5s var(--ease); }
  .cut.sky-wait .cut-sky { opacity: 0; }
}

/* 19. Every Room, All Year in stops (23 Oct, the owner: "to see the full animation you scroll down, you miss it"): the band holds and each
       scroll plays one part, then waits (tesla.js holdStops): cool air, the turn to winter, warm air. Skip shows while the band holds,
       top right of the picture. */
.cut-skip { position: absolute; z-index: 3; top: 24px; right: 24px; display: inline-flex; align-items: center; height: 44px; padding: 0 16px;
  border: 1px solid rgba(255, 255, 255, .3); border-radius: 4px; background: rgba(6, 10, 14, .62); color: #fff; font: 600 var(--s4)/1 var(--text);
  cursor: pointer; opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility .3s, border-color .2s; }
.cut-skip:hover { border-color: #fff; }
.cut.is-held .cut-skip { opacity: 1; visibility: visible; }
@media (max-width: 760px) { .cut-skip { top: 16px; right: 16px; } }
/* while it holds the finger plays the parts, the page does not slide under it; at the first and the last part it scrolls on as always */
@supports (touch-action: pan-down) {
  .cut.is-held .cut-pin { touch-action: pan-x pinch-zoom; }
  .cut.is-held.at-first .cut-pin { touch-action: pan-x pan-up pinch-zoom; }
  .cut.is-held.at-last .cut-pin { touch-action: pan-x pan-down pinch-zoom; }
}
html.stops-lock { overflow: hidden; }

/* ==================== 23 Oct, judges round 14 (design 8, UX 7) ==================== */
/* 8. What We Do (computer) steps like Every Room, All Year (tesla.js): one service per gesture. Skip shows while it holds, top right of
      the picture, the same as Every Room's. */
.svc.is-held .svc-skip { opacity: 1; visibility: visible; }

/* 11. Header, 961 to 1099 px (1024 tablets): the number 555-010-0100 shows, never "Call" alone. One row: the logo, the menu in the middle
       of the room that is left, the number and Get an Estimate. The menu links are tighter there (6 px each side) and the button 16. */
@media (min-width: 961px) and (max-width: 1099px) {
  .head-row { display: flex; gap: 16px; }
  .head-row > .nav { margin: 0 auto; }
  .nav-link { padding: 0 6px; }
  .head-call .hc-word { display: none; }
  .hc-num, .head-actions:has(.head-est.wait) .hc-num { max-width: 9em; margin-left: 8px; }
  .head-est, .head-est.wait, .home .head-est.wait { padding-left: 16px; padding-right: 16px; }
}

/* 12. services.html: the service strip lets go exactly where the cards end (the room under the cards is outside the strip's area), so it
       never sits over Northline Care and Financing and is never an empty strip. Phone: the current label is centred, a swipe snaps
       each label to the middle, and room before the first and after the last label lets each one get there (tesla.js). */
.jump-area > .svc-grid-sec { padding-bottom: 0; }
.jump-area { margin-bottom: var(--section); }
@media (max-width: 760px) {
  .jump-bar .jump { scroll-padding-left: 0; scroll-padding-right: 0; }
  .jump-bar .jump a { scroll-snap-align: center; }
  .jump-bar .jump::before { content: ""; flex: none; width: var(--jump-start, 0px); height: 1px; }
}

/* 13. Footer, 900 to 1100 px: a 2 by 2 grid (the logo with the phone and email beside the offices, then Services and Company), so
       the right half is never empty */
@media (min-width: 900px) and (max-width: 1100px) {
  .foot-top { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .foot-top > .foot-brand, .foot-top > .foot-col:nth-child(2) { grid-column: auto; }
}

/* 14. services.html title, 761 to 1199 px on a wide screen (1024): the picture sits 64 px lower, so the line under Our Services ends
       above the lit windows */
@media (min-width: 761px) and (max-width: 1199px) and (min-aspect-ratio: 1/1) {
  .svc-hero-pic img { object-position: 50% calc(80% + 64px); }
}

/* 15. The estimate form's choice tiles are 48 px tall at every size */
.choice { min-height: 48px; height: 48px; padding-top: 0; padding-bottom: 0; }

/* 16. About (computer): "Made in Our Own Sheet Metal Shop" has its line under the heading, as wide as every other section's line */
@media (min-width: 761px) {
  #shop .section-head { display: block; }
  #shop .section-head .lead { max-width: 40ch; margin-top: 16px; text-wrap: wrap; }
}

/* 17. About: Our Own Crew shows the ductwork from our own shop (the top of the page shows a technician at an outdoor unit) */
.crew-pic img { object-position: 50% 45%; }

/* 20. services.html: the card you came for (from the menu or a link) gets a 2 px blue line under its picture and the brightest title
       for about 2 seconds (the other titles dim a little meanwhile); no rounded ring. Less motion: no fade. */
.svc-card.ring, .svc-card.ring.land-focus:focus { outline-color: transparent; }
.svc-card figure { position: relative; }
.svc-card figure::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--accent-text); opacity: 0; transition: opacity .6s var(--ease); }
.section .svc-card h2 { transition: color .6s var(--ease); }
.svc-card.ring figure::after { opacity: 1; transition: none; }
.section .svc-card.ring h2 { color: #FFFFFF; transition: none; }
.svc-cards:has(.ring) .svc-card:not(.ring) h2 { color: var(--muted); }
@media (prefers-reduced-motion: reduce) { .svc-card figure::after, .section .svc-card h2 { transition: none; } }
