@font-face{font-family:'Barlow';font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/Barlow-400.b0a8ad37.woff2) format('woff2');}
@font-face{font-family:'Barlow';font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/Barlow-500.cd759df8.woff2) format('woff2');}
@font-face{font-family:'Barlow';font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/Barlow-600.4b52ddd4.woff2) format('woff2');}
@font-face{font-family:'Barlow Condensed';font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/BarlowCondensed-500.460f141e.woff2) format('woff2');}
@font-face{font-family:'Barlow Condensed';font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/BarlowCondensed-600.215a93c6.woff2) format('woff2');}
@font-face{font-family:'Barlow Condensed';font-style:normal;font-weight:700;font-display:swap;src:url(/fonts/BarlowCondensed-700.3787a5a4.woff2) format('woff2');}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/IBMPlexMono-400.08949f72.woff2) format('woff2');}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/IBMPlexMono-500.01d28544.woff2) format('woff2');}

/* ============ RESET ============ */
  #app, #app *, #app *::before, #app *::after { box-sizing: border-box; margin: 0; padding: 0; }
  #app { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
  #app img, #app svg { display: block; max-width: 100%; }
  #app ul, #app ol { list-style: none; }
  /* Visually hidden but present for screen readers and for heading hierarchy. Bing asks for a
     logical H1-H6 order by name; the service card grid uses h3, so a section h2 must precede it. */
  #app .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}
  #app a { color: inherit; text-decoration: none; }
  #app button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
  #app input, #app select, #app textarea { font: inherit; color: inherit; }

  /* ============ TOKENS ============ */
  #app {
    --ground:   #F5F8FC;
    --surface:  #FFFFFF;
    --panel:    #0F3059;
    --ink:      #152233;
    --ink-soft: #4B5C6F;
    --line:     #D9E2EC;
    --amber:    #2764AE;   /* accent on light */
    --amber-hi: #8FBCEE;   /* accent on navy */
    --navy:     #0F3059;
    --amber-dn: #1F569B;
    --blue:     #1B4E8C;
    --slat-1:   #2E6FBE;
    --slat-2:   #1B4E8C;
    --radius:   4px;
    --radius-lg: 8px;
    --shadow-sm: 0 1px 2px rgba(15,48,89,.4);
    --shadow:    0 2px 6px rgba(15,48,89,.42), 0 16px 34px -18px rgba(15,48,89,.7);
    --shadow-lg: 0 4px 10px rgba(15,48,89,.45), 0 30px 60px -24px rgba(15,48,89,.8);
    --ring:      0 0 0 3px rgba(39,100,174,.35);
    --s-section: clamp(64px,8.5vw,116px);
    --font-display: 'Barlow Condensed', sans-serif;
    --font-body: 'Barlow', sans-serif;
    --font-mono: 'IBM Plex Mono', monospace;

    background: var(--ground);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 16.5px;
    line-height: 1.6;
    min-height: 100vh;
    position: relative;
    /* clip, not hidden: hidden makes #app a scroll container and kills every
       position:sticky inside it (the aside rail). clip clips without scrolling.
       Engines that ignore clip keep the hidden fallback. */
    overflow-x: hidden;
    overflow-x: clip;
  }

  #app h1, #app h2, #app h3 {
    font-family: var(--font-display);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.01em;
    line-height: 1.05;
  }
  #app h1 { font-size: clamp(44px, 8vw, 92px); }
  #app h2 { font-size: clamp(30px, 4.5vw, 52px); }
  #app h3 { font-size: clamp(20px, 2.6vw, 28px); font-weight: 600; }
  #app .eyebrow {
    font-family: var(--font-mono);
    font-size: 11.5px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--amber);
    display: inline-flex; align-items: center; gap: 9px;
  }
  #app .eyebrow::before { content:""; width:22px; height:1.5px; background:currentColor; opacity:.6; flex:none; }
  #app p { color: var(--ink-soft); }

  /* ============ LAYOUT HELPERS ============ */
  #app .wrap { max-width: 1180px; margin: 0 auto; padding-inline: 24px; }
  #app .section { padding-block: var(--s-section); position: relative; }
  #app .section-panel { background: var(--panel); }
  #app .section-panel h1, #app .section-panel h2, #app .section-panel h3 { color: #fff; }
  #app .section-panel p, #app .section-panel li { color: rgba(255,255,255,.82); }
  #app .section-panel strong { color: #fff; }
  #app .section-panel .eyebrow { color: var(--amber-hi); }
  #app .section-panel .facts { color: rgba(255,255,255,.9); }
  #app .section-panel .facts strong { color: var(--amber-hi); }
  #app .section-panel .sibling-link { color: var(--amber-hi); }
  #app .section-panel table.spec-table { color: rgba(255,255,255,.86); }
  #app .section-panel table.spec-table th { color: var(--amber-hi); }
  #app .section-panel table.spec-table td { border-color: rgba(255,255,255,.14); }
  #app .section-panel table.spec-table tbody tr:nth-child(even) { background: rgba(255,255,255,.05); }

  /* Hazard stripe divider */
  #app .hazard {
    height: 4px;
    width: 100%;
    background-image: repeating-linear-gradient(45deg, var(--navy) 0 10px, transparent 10px 20px);
    opacity: 0.55;
  }

  /* Visually hidden */
  #app .vh {
    position: absolute !important;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0; padding: 0; margin: -1px;
  }

  /* ============ HEADER / NAV ============ */
  #app header.site-header {
    position: sticky; top: 0; z-index: 200;
    background: rgba(245,248,252,0.82);
    -webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);
    border-bottom: 1px solid transparent;
    transition: background .3s ease, border-color .3s ease, box-shadow .3s ease;
  }
  #app header.site-header.scrolled { background: rgba(245,248,252,0.94); border-bottom-color: var(--line); box-shadow: 0 18px 34px -28px rgba(15,48,89,.9); }
  #app .nav-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px;
    padding-block: 14px;
  }
  #app .brand {
    display: flex; align-items: center; gap: 10px;
    font-family: var(--font-display);
    font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em;
    font-size: 19px; color: var(--ink);
  }
  #app .brand .mark { width: 30px; height: 30px; color: var(--amber); flex-shrink: 0; }
  #app .brand small { display: block; font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.1em; color: var(--ink-soft); text-transform: uppercase; font-weight: 400; }
  #app nav.primary-nav { display: flex; align-items: center; gap: 6px; }
  #app nav.primary-nav a {
    white-space: nowrap;
    font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em;
    color: var(--ink-soft); padding: 0 13px; height: 40px; border-radius: var(--radius);
    display: flex; align-items: center; position: relative;
    transition: color .2s ease, background .2s ease;
  }
  #app nav.primary-nav a::after { content:""; position:absolute; left:13px; right:13px; bottom:6px; height:2px; background:var(--amber); transform:scaleX(0); transform-origin:left; transition:transform .25s ease; }
  #app nav.primary-nav a:hover { color: var(--ink); background: rgba(39,100,174,.08); }
  #app nav.primary-nav a:hover::after { transform: scaleX(1); }
  #app nav.primary-nav a[aria-current="page"] { color: var(--ink); background: rgba(39,100,174,.12); }
  #app nav.primary-nav a[aria-current="page"]::after { transform: scaleX(1); }
  #app .header-cta {
    display: flex; align-items: center; gap: 14px;
  }
  #app .btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 9px;
    font-family: var(--font-mono); font-size: 13px; text-transform: uppercase; letter-spacing: 0.07em;
    padding: 0 22px; height: 48px; border-radius: var(--radius); cursor: pointer; white-space: nowrap;
    transition: transform .18s ease, background-color .18s ease, border-color .18s ease, box-shadow .18s ease, color .18s ease;
  }
  #app .btn:active { transform: translateY(1px) scale(.995); }
  #app .btn:focus-visible { outline: none; box-shadow: var(--ring); }
  #app .btn-amber { background: var(--amber); color: #FFFFFF; font-weight: 600; box-shadow: 0 1px 2px rgba(15,48,89,.4), 0 12px 26px -14px rgba(39,100,174,.7); }
  #app .btn-amber:hover { background: #2E6FBE; transform: translateY(-2px); box-shadow: 0 2px 5px rgba(15,48,89,.45), 0 18px 34px -14px rgba(39,100,174,.8); }
  #app .btn-ghost { background: transparent; border: 1px solid var(--amber); color: var(--amber); }
  #app .btn-ghost:hover { background: rgba(39,100,174,0.12); transform: translateY(-2px); border-color: #2E6FBE; color: #2E6FBE; }
  #app .hamburger {
    display: none; width: 44px; height: 44px; align-items: center; justify-content: center;
    border: 1px solid var(--line); border-radius: 3px; color: var(--ink);
  }
  #app .hamburger svg { width: 20px; height: 20px; }

  #app .mobile-nav {
    display: none;
    position: fixed; inset: 0; top: 0; z-index: 300;
    background: var(--ground);
    padding: 24px;
    flex-direction: column; gap: 20px;
    /* The panel is taller than a small phone: nine links at a 44px minimum plus the
       top row measured 596px against a 568px viewport, which put the phone number
       off the bottom with no way to reach it. Make the panel its own scroll
       container, and contain the overscroll so dragging it does not scroll the
       page behind. Matches the residential site, which measured clean. */
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  #app .mobile-nav.open { display: flex; }
  body.nav-open { overflow: hidden; }
  #app .mobile-nav .top-row { display: flex; justify-content: space-between; align-items: center; }
  #app .mobile-nav a { font-family: var(--font-display); font-size: 26px; text-transform: uppercase; letter-spacing: 0.02em; padding: 10px 0; border-bottom: 1px solid var(--line); min-height: 44px; display: flex; align-items: center; }

  /* A short viewport (small phone, landscape, or a reader using large text) cannot
     fit nine 26px uppercase links. Tighten rather than rely on scrolling. */
  @media (max-height: 640px) {
    #app .mobile-nav { padding: 16px 24px; gap: 10px; }
    #app .mobile-nav a { font-size: 20px; padding: 6px 0; }
  }

  /* ============ FOCUS ============ */
  #app a:focus-visible, #app button:focus-visible, #app input:focus-visible, #app select:focus-visible, #app textarea:focus-visible {
    outline: 2px solid var(--amber); outline-offset: 2px; border-radius: 2px;
  }

  /* ============ HERO ============ */
  #app .hero {
    position: relative;
    min-height: min(92vh, 820px);
    display: flex; align-items: flex-end;
    overflow: hidden;
    background: var(--ground);
  }
  #app .hero-bay {
    position: absolute; inset: 0;
    background-color: #EAF1F9;
    background-image:
      linear-gradient(rgba(39,100,174,.22) 1px, transparent 1px),
      linear-gradient(90deg, rgba(39,100,174,.22) 1px, transparent 1px);
    background-size: 42px 42px;
    background-position: center;
  }
  #app .hero-floor-glow {
    position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
    background: var(--amber);
    box-shadow: 0 0 40px 10px rgba(39,100,174,0.35);
  }
  #app .door-track { position: absolute; inset: 0; overflow: hidden; z-index: 5; }
  #app .door-curtain {
    position: absolute; inset: 0;
    background-image: repeating-linear-gradient(var(--slat-1) 0 22px, var(--slat-2) 22px 26px);
    transform-origin: top center;
    animation: roll-up 1.4s cubic-bezier(.7,.05,.2,1) 0.05s both;
  }
  #app .door-curtain::before {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,0.30) 48%, transparent 62%);
    mix-blend-mode: overlay;
  }
  #app .door-curtain::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 10px;
    background: var(--amber);
  }
  #app .door-rail { position: absolute; top: 0; bottom: 0; width: 14px; background: var(--surface); border-inline: 1px solid var(--line); z-index: 6; }
  #app .door-rail.left { left: 0; } #app .door-rail.right { right: 0; }

  @keyframes roll-up {
    0%   { transform: scaleY(1); }
    62%  { transform: scaleY(0.16); filter: brightness(1.15); }
    100% { transform: scaleY(0); filter: brightness(1); }
  }

  #app .hero-content {
    position: relative; z-index: 10;
    padding-block: clamp(48px, 8vw, 96px) clamp(32px, 6vw, 56px);
    width: 100%;
  }
  #app .hero-content .eyebrow { display: inline-block; margin-bottom: 14px; }
  #app .hero-content h1 { max-width: 16ch; opacity: 0; transform: translateY(18px); animation: rise 0.55s ease 0.35s forwards; }
  #app .hero-dek { max-width: 50ch; font-size: clamp(16px, 2vw, 19px); margin-top: 20px; color: var(--ink-soft); opacity: 0; transform: translateY(18px); animation: rise 0.55s ease 0.5s forwards; }
  #app .hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 30px; opacity: 0; transform: translateY(18px); animation: rise 0.55s ease 0.65s forwards; }
  #app .hero-replay {
    margin-top: 22px; display: inline-flex; align-items: center; gap: 8px;
    font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
    color: var(--ink-soft); opacity: 0.55; border: 1px dashed var(--line); padding: 6px 10px; border-radius: 3px;
  }
  #app .hero-replay:hover { opacity: 1; color: var(--amber); border-color: var(--amber); }
  #app .hero-replay svg { width: 13px; height: 13px; }

  /* Intro budget: the headline must be readable well inside the 2.5s LCP mark.
     Door ends 1.45s, h1 0.90s, dek 1.05s, buttons 1.20s. Lengthening these
     delays puts the homepage back over budget on a phone. */
  @keyframes rise { to { opacity: 1; transform: translateY(0); } }

  #app .spec-strip { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--line); }
  #app .spec-strip div {
    font-family: var(--font-mono); font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.04em;
    padding: 16px 18px; border-right: 1px solid var(--line); color: var(--ink-soft);
  }
  #app .spec-strip div:last-child { border-right: 0; }
  #app .spec-strip strong { color: var(--amber); display: block; font-size: 11px; letter-spacing: 0.06em; margin-bottom: 3px; }

  /* ============ REVEAL ============ */
  #app .reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.6s ease, transform 0.6s ease; }
  #app .reveal.in { opacity: 1; transform: translateY(0); }

  /* ============ CARD GRID: SERVICES OVERVIEW ============ */
  #app .grid-6 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 44px; }
  #app .service-card {
    background: var(--surface); border: 1px solid var(--line); border-radius: 4px;
    padding: 26px; display: flex; flex-direction: column; gap: 14px;
    transition: border-color 0.2s ease, transform 0.2s ease;
  }
  #app .service-card:hover { border-color: var(--amber); transform: translateY(-3px); }
  #app .service-card .icon { width: 40px; height: 40px; color: var(--amber); }
  #app .service-card h3 { font-size: 19px; }
  #app .service-card p { font-family: var(--font-mono); font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); }
  #app .service-card .goto { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--blue); margin-top: auto; }

  /* ============ COST BAND ============ */
  #app .truth-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 40px; }
  #app .truth-card { border-left: 2px solid var(--amber); padding-left: 18px; }
  #app .truth-card .num { font-family: var(--font-mono); color: var(--amber); font-size: 13px; }
  #app .truth-card p { color: var(--ink); font-size: 16px; margin-top: 8px; }

  /* ============ MAINTENANCE SPEC TABLE ============ */
  #app .spec-table-wrap { margin-top: 40px; border: 1px solid var(--line); border-radius: 4px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  /* 660, not 520. Below 560px the table stacks into labelled cards (see TABLES ON A
     PHONE further down) and this minimum is reset to 0. Between those two points the
     content column is about 559px, so a 520px minimum FITS and the table squeezed its
     columns to ~85px instead of scrolling: at 768px a five-column comparison had 13 of
     39 cells wrapping almost every word. A minimum above the available width makes the
     wrapper do its job and the rows stay readable. */
  #app .spec-table-wrap table.spec-table { min-width: 660px; }
  /* .scroll-x is used as a table wrapper on the rolling-steel guide and had NO rule at
     all, so it scrolled nothing. Same treatment. */
  #app .scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  #app .scroll-x table.spec-table { min-width: 660px; }
  #app table.spec-table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 13.5px; }
  #app table.spec-table caption { caption-side: top; text-align: left; padding: 12px 18px; font-size: 11.5px; letter-spacing: 0.02em; color: var(--ink-soft); border-bottom: 1px solid var(--line); }
  #app table.spec-table th, #app table.spec-table td { text-align: left; padding: 13px 18px; border-bottom: 1px solid var(--line); }
  #app table.spec-table th { background: var(--panel); color: var(--amber); text-transform: uppercase; letter-spacing: 0.06em; font-size: 11px; font-weight: 500; }
  #app table.spec-table tbody tr:last-child td { border-bottom: 0; }
  #app table.spec-table tbody tr:nth-child(even) { background: rgba(39,100,174,0.045); }
  #app table.spec-table td.note { color: var(--ink-soft); }
  #app table.spec-table .cite { color: var(--blue); }

  /* ============ TRUST STRIP ============ */
  #app .trust-strip { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px; }
  #app .trust-strip .facts { font-family: var(--font-mono); font-size: 14px; color: var(--ink); }
  #app .trust-strip .facts strong { color: var(--amber); }

  /* ============ CTA BAND ============ */
  #app .cta-band { background: linear-gradient(115deg, #1B4E8C, #2E6FBE 55%, var(--amber)); color: #fff; text-align: center; }
  #app .cta-band h2 { color: #fff; max-width: 20ch; margin-inline: auto; }
  #app .cta-band p { color: rgba(255,255,255,.82); }
  #app .cta-band .btn-amber { background: #fff; color: var(--navy); margin-top: 26px; box-shadow: 0 12px 30px -14px rgba(15,48,89,.6); }
  #app .cta-band .btn-amber:hover { background: #EAF2FC; color: var(--navy); }
  #app .cta-band .btn-ghost { border-color: rgba(255,255,255,.5); color: #fff; }
  #app .cta-band .btn-ghost:hover { background: rgba(255,255,255,.14); border-color: #fff; color: #fff; }

  /* ============ SERVICE BLOCKS (services page) ============ */
  #app .service-block { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 48px; align-items: center; padding-block: clamp(48px, 7vw, 84px); border-top: 1px solid var(--line); }
  #app .service-block:first-of-type { border-top: 0; }
  #app .service-block:nth-of-type(even) .block-art { order: 2; }
  #app .block-copy h2 { margin-bottom: 18px; }
  #app .block-copy p { margin-bottom: 14px; }
  #app .signs-list { margin-top: 20px; border-top: 1px dashed var(--line); padding-top: 16px; }
  #app .signs-list .eyebrow { display: block; margin-bottom: 10px; }
  #app .signs-list li { position: relative; padding-left: 20px; margin-bottom: 8px; color: var(--ink-soft); font-size: 15px; }
  #app .signs-list li::before { content: ""; position: absolute; left: 0; top: 9px; width: 8px; height: 2px; background: var(--amber); }
  #app .block-art { background: var(--surface); border: 1px solid var(--line); border-radius: 4px; padding: 30px; }
  #app .block-art svg { width: 100%; height: auto; }

  /* ============ AREAS HUB ============ */
  #app .areas-intro { max-width: 62ch; }
  /* The sentence under each tier heading on the areas page, saying what that tier actually
     gets. It sits between an h2 and a card grid, so it needs its own spacing rather than
     inheriting prose margins it is not inside. */
  #app .areas-note { max-width: 62ch; margin-top: 10px; color: var(--ink-soft); font-size: 15.5px; line-height: 1.6; }
  #app .areas-note a { color: var(--blue); border-bottom: 1px solid rgba(27,78,140,.35); }
  #app .areas-note a:hover { border-bottom-color: var(--blue); }
  #app .map-wrap { margin-top: 48px; background: var(--surface); border: 1px solid var(--line); border-radius: 4px; padding: 24px; }
  #app .map-wrap svg { width: 100%; height: auto; }
  #app .grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 40px; }
  #app .city-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 26px 24px; display: flex; flex-direction: column; gap: 12px;
    box-shadow: var(--shadow-sm); position: relative; overflow: hidden;
    transition: border-color .26s ease, transform .26s ease, box-shadow .26s ease; }
  #app .city-card::before { content:""; position:absolute; inset:0 0 auto; height:3px; background:var(--amber); transform:scaleX(0); transform-origin:left; transition:transform .32s ease; }
  #app .city-card:hover { border-color: rgba(39,100,174,.5); transform: translateY(-5px); box-shadow: var(--shadow-lg); }
  #app .city-card:hover::before { transform: scaleX(1); }
  #app .city-card h3 { font-size: 22px; }
  #app .city-card p { font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); }
  #app .city-card .goto { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--blue); margin-top: 4px; }

  /* ============ SERVICE AREA MAP ============ */
  #app .map-wrap { margin-top: 44px; background: linear-gradient(165deg,#FFFFFF,#EDF3FA); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: clamp(16px,2.2vw,28px); box-shadow: var(--shadow); }
  #app .map-svg { width: 100%; height: auto; display: block; }
  #app .map-water { fill: url(#gWaterC); }
  #app .map-shore { fill: none; stroke: #A9C6E4; stroke-width: 2; }
  #app .map-escarp { fill: none; stroke: #B9C6D4; stroke-width: 1.6; stroke-dasharray: 2 7; stroke-linecap: round; }
  #app .map-route { fill: none; stroke: var(--amber); stroke-width: 2.6; stroke-linecap: round; opacity: .6; }
  #app .map-route-glow { fill: none; stroke: var(--amber); stroke-width: 10; stroke-linecap: round; opacity: .1; }
  #app .map-ring { fill: none; stroke: var(--amber); stroke-width: 1.1; stroke-dasharray: 3 8; opacity: .22; }
  #app .map-legend { font-family: var(--font-mono); font-size: 11px; fill: var(--ink-soft); letter-spacing: .06em; text-transform: uppercase; }
  #app .map-city { cursor: pointer; }
  #app .map-city .mc-hit { fill: transparent; }
  #app .map-city .mc-dot { fill: #FFFFFF; stroke: var(--amber); stroke-width: 2.6; transition: r .25s ease, stroke-width .25s ease; }
  #app .map-city .mc-label { font-family: var(--font-mono); font-size: 12.5px; fill: var(--ink); letter-spacing: .05em; text-transform: uppercase; transition: fill .2s ease; }
  #app .map-city:hover .mc-dot, #app .map-city:focus-visible .mc-dot { r: 9; stroke-width: 3.4; }
  #app .map-city:hover .mc-label, #app .map-city:focus-visible .mc-label { fill: var(--amber); font-weight: 600; }
  #app .map-city:focus-visible { outline: none; }
  #app .map-city.is-base .mc-dot { fill: var(--amber); stroke: #FFFFFF; stroke-width: 3; }
  #app .map-city.is-base .mc-label { fill: var(--amber); font-weight: 700; }
  #app .mc-pulse { fill: none; stroke: var(--amber); stroke-width: 2; opacity: 0; animation: mcPulseC 3.2s ease-out infinite; }
  @keyframes mcPulseC { 0%{opacity:.5;r:9} 70%{opacity:0;r:30} 100%{opacity:0;r:30} }
  #app .map-readout { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line);
    font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); letter-spacing: .03em; min-height: 44px; }
  #app .map-readout b { color: var(--amber); font-weight: 600; letter-spacing: .07em; text-transform: uppercase; }
  #app .map-readout .mr-note { font-family: var(--font-body); letter-spacing: 0; font-size: 14px; }
  #app .map-readout .goto { margin-left: 8px; color: var(--blue); }

  #app .map-corridor { display: none; list-style: none; margin: 0; padding: 0; }
  #app .mcor-item { position: relative; }
  #app .mcor-item a { display: flex; align-items: flex-start; gap: 16px; padding: 14px 4px; }
  #app .mcor-item::before { content:""; position:absolute; left:9px; top:0; bottom:0; width:2px; background:var(--line); }
  #app .mcor-item:first-child::before { top: 26px; }
  #app .mcor-item:last-child::before { bottom: calc(100% - 26px); }
  #app .mcor-dot { width:20px; height:20px; border-radius:50%; background:var(--surface); border:2.5px solid var(--amber); flex:none; margin-top:3px; position:relative; z-index:1; }
  #app .mcor-item.is-base .mcor-dot { background:var(--amber); box-shadow:0 0 0 5px rgba(39,100,174,.16); }
  #app .mcor-body { display:flex; flex-direction:column; gap:3px; }
  #app .mcor-body b { font-family:var(--font-display); font-weight:600; text-transform:uppercase; font-size:18px; color:var(--ink); display:flex; align-items:center; gap:9px; }
  #app .mcor-body b em { font-family:var(--font-mono); font-style:normal; font-size:11px; letter-spacing:.12em; color:#FFFFFF; background:var(--amber); padding:3px 7px; border-radius:100px; }
  #app .mcor-body > span { font-family:var(--font-body); font-size:14px; color:var(--ink-soft); line-height:1.5; text-transform:none; }
  #app .mcor-item a:hover .mcor-body b { color: var(--amber); }

  /* ============ BREADCRUMB ============ */
  #app .breadcrumb { font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.04em; padding-top: 28px; }
  #app .breadcrumb a { color: var(--ink-soft); }
  #app .breadcrumb a:hover { color: var(--amber); }
  #app .breadcrumb .sep { margin-inline: 8px; color: var(--line); }
  #app .breadcrumb [aria-current] { color: var(--amber); }

  /* ============ CITY PAGE ============ */
  #app .city-hero h1 { margin-top: 16px; max-width: 20ch; }
  /* A city h1 is a full sentence ("Commercial garage door repair and installation in Brampton").
     At the site's 44px floor that runs six lines on a phone and pushes the answer paragraph off
     the first screen, which is the same fault fixed on the prices page. Phones only: desktop
     keeps the 92px display size exactly as it was. */
  @media (max-width: 560px) { #app .city-hero h1 { font-size: clamp(31px, 8.4vw, 44px); } }
  #app .city-hero p.lede { max-width: 60ch; margin-top: 20px; font-size: 17px; }
  #app .city-services { margin-top: 44px; }
  #app .city-services ul { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 24px; margin-top: 18px; }
  #app .city-services a { font-family: var(--font-mono); font-size: 14px; color: var(--blue); border-bottom: 1px solid transparent; display: inline-flex; align-items: center; gap: 8px; min-height: 32px; }
  #app .city-services a:hover { border-bottom-color: var(--blue); }
  #app .city-services a svg { width: 14px; height: 14px; flex-shrink: 0; }

  /* ============ CONTACT ============ */
  #app .contact-grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 56px; margin-top: 44px; }
  #app .hours-table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 14px; margin-top: 18px; }
  #app .hours-table th, #app .hours-table td { padding: 10px 0; border-bottom: 1px solid var(--line); }
  #app .hours-table th[scope="row"] { background: transparent; color: var(--ink-soft); font-family: var(--font-mono);
    font-size: 12px; text-transform: uppercase; letter-spacing: .04em; font-weight: 500; text-align: left; }
  #app .hours-table td:last-child { text-align: right; color: var(--ink); }
  #app .contact-detail { margin-top: 30px; display: flex; flex-direction: column; gap: 10px; font-family: var(--font-mono); font-size: 14.5px; }
  #app .contact-detail a { color: var(--blue); }
  #app .map-mini { margin-top: 28px; }

  /* ============ FOOTER ============ */
  #app footer.site-footer { background: var(--panel); border-top: 1px solid var(--line); }
  #app footer.site-footer .footer-grid p, #app footer.site-footer .footer-grid li { color: rgba(255,255,255,.76); }
  #app footer.site-footer .footer-grid a { color: rgba(255,255,255,.78); }
  #app footer.site-footer .footer-grid a:hover { color: #fff; }
  #app footer.site-footer .footer-brand span { color: #fff; }
  #app footer.site-footer .footer-bottom { color: rgba(255,255,255,.6); border-color: rgba(255,255,255,.14); }
  #app footer.site-footer .sibling-link { color: var(--amber-hi); }
  #app footer.site-footer .social-row a { border-color: rgba(255,255,255,.25); }
  #app footer.site-footer .social-row a:hover { border-color: var(--amber-hi); background: rgba(255,255,255,.07); }
  #app footer.site-footer .social-row svg { color: #fff; }
  #app .footer-grid { display: grid; grid-template-columns: 1.2fr 1fr 1fr 1fr; gap: 36px; padding-block: 56px; }
  #app .footer-grid h4 { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--amber-hi); margin-bottom: 16px; }
  #app .footer-grid p, #app .footer-grid li { font-size: 14px; color: var(--ink-soft); margin-bottom: 8px; }
  #app .footer-grid a { color: var(--ink-soft); }
  #app .footer-grid a:hover { color: var(--ink); }
  #app .footer-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
  #app .footer-brand .mark { width: 26px; height: 26px; color: var(--amber); }
  #app .footer-brand span { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 17px; }
  #app .social-row { display: flex; gap: 12px; margin-top: 14px; }
  #app .social-row a { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--line); border-radius: 3px; }
  #app .social-row a:hover { border-color: var(--amber); color: var(--amber); }
  #app .social-row svg { width: 16px; height: 16px; }
  #app .sibling-link { display: inline-block; margin-top: 6px; font-family: var(--font-mono); font-size: 13px; color: var(--blue); }
  #app .footer-bottom { border-top: 1px solid var(--line); padding-block: 18px; text-align: center; font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); }

  /* ============ REDUCED MOTION ============ */
  @media (prefers-reduced-motion: reduce) {
    #app .door-curtain { animation: none !important; transform: scaleY(0); }
    #app .hero-content h1, #app .hero-dek, #app .hero-actions { animation: none !important; opacity: 1; transform: none; }
  }
  /* Once the intro has played, pin the hero in its final state so the
     load-time keyframes don't restart every time the router re-shows home. */
  #app.settled .door-curtain { animation: none !important; transform: scaleY(0); }
  #app.settled .hero-content h1, #app.settled .hero-dek, #app.settled .hero-actions {
    animation: none !important; opacity: 1; transform: none;
  }

  /* ============ RESPONSIVE ============ */
  @media (max-width: 1024px) {
    #app .grid-6 { grid-template-columns: repeat(2, 1fr); }
    #app .spec-strip { grid-template-columns: repeat(2, 1fr); }
    #app .truth-grid { grid-template-columns: 1fr; gap: 30px; }
    #app .service-block { grid-template-columns: 1fr; }
    #app .service-block:nth-of-type(even) .block-art { order: 0; }
    #app .footer-grid { grid-template-columns: 1fr 1fr; }
    #app .contact-grid { grid-template-columns: 1fr; gap: 40px; }
  }
  /* The desktop nav and the hamburger are two halves of one switch, so they share a
     breakpoint. They did not before, and it cost two real faults: the nav was hidden below
     980px while the hamburger only appeared below 760px, which left every width from 761 to
     980px with no menu at all; and above 980px the seven-item nav plus the brand and the call
     button need about 1063px, so 1000 to 1080px overflowed the viewport. 1140px is the width
     where all three fit with room to spare, measured rather than guessed. */
  @media (max-width: 1140px) {
    #app nav.primary-nav { display: none; }
    #app .hamburger { display: flex; }
  }
  @media (max-width: 760px) {
    #app .header-cta .btn-ghost { display: none; }
    #app .grid-6 { grid-template-columns: 1fr; }
    #app .grid-3 { grid-template-columns: 1fr; }
    #app .fact-row { grid-template-columns: 1fr; }
    #app .city-services ul { grid-template-columns: 1fr; }
    #app .spec-strip { grid-template-columns: 1fr 1fr; }
  }
  @media (max-width: 480px) {
    #app .wrap { padding-inline: 16px; }
    #app .footer-grid { grid-template-columns: 1fr; padding-block: 40px; }
    #app .spec-strip { grid-template-columns: 1fr; }
    #app .city-cta { flex-direction: column; align-items: flex-start; }
  }

  @media (max-width: 760px) {
    #app .map-svg { display: none; }
    #app .map-corridor { display: block; }
    #app .map-wrap { padding: 8px 14px; }
    #app .map-readout { padding-top: 14px; }
    #app .map-readout > b, #app .map-readout .mr-note { display: none; }
  }
  @media (prefers-reduced-motion: reduce) {
    #app .mc-pulse { animation: none; opacity: 0; }
  }

  #app .truth-card p { color: rgba(255,255,255,.84); }
  #app .truth-card .num { color: var(--amber-hi); }
  #app .truth-card strong { color: #fff; }
  /* The header row is capped at 1180px and the parts no longer fit inside it. With seven nav
     items the bar needs 163 + 643 + 438 plus gaps = about 1276px, and flexbox paid for the
     overrun by crushing the logo to 19px wide at every width above 1220px, where the ghost
     button used to appear. The ghost button is the part to give up: it pointed at
     /services/planned-maintenance/, which is still reachable from the Services nav, the
     footer, the home page and the prices page. The logo is not negotiable, so .brand is
     pinned against any future addition shrinking it again. */
  #app .header-cta .btn-ghost { display: none; }
  #app .brand { flex-shrink: 0; }
  @media (max-width: 1080px) {
    #app .brand .brand-div small { display: none; }
    #app nav.primary-nav a { padding: 0 10px; }
  }
  #app table.spec-table th { color: var(--amber-hi); }
  #app .trust-strip .facts strong { color: var(--amber); }
  #app .section-panel .trust-strip .facts { color: rgba(255,255,255,.9); }
  #app .section-panel .trust-strip .facts strong { color: var(--amber-hi); }
  #app select, #app input, #app textarea { background: #fff !important; color: var(--ink) !important; border-color: var(--line) !important; }
  #app select option { color: var(--ink); }

  @media (max-width: 760px) { #app .wrap { padding-inline: 20px; } }

  /* ============ CLIENT MARQUEE (hero trust strip) ============ */
  #app .client-marquee { margin-top: 26px; border-top: 1px solid rgba(15,48,89,.12); padding-top: 16px; }
  #app .mq-label { display: block; font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink-soft); opacity: .85; margin-bottom: 12px; }
  #app .mq-viewport {
    position: relative; overflow: hidden;
    /* fade both edges into the hero rather than hard-cutting the strip */
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
  }
  #app .mq-track {
    display: flex; align-items: center; gap: 44px;
    list-style: none; margin: 0; padding: 0; width: max-content;
    animation: mq-scroll 42s linear infinite;
  }
  #app .mq-viewport:hover .mq-track { animation-play-state: paused; }
  #app .mq-item {
    font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
    letter-spacing: .06em; font-size: 23px; white-space: nowrap; line-height: 1;
  }
  #app .mq-item.is-real { color: var(--navy); opacity: .72; }
  @keyframes mq-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
  @media (prefers-reduced-motion: reduce) {
    #app .mq-track { animation: none; }
    #app .mq-viewport { -webkit-mask-image: none; mask-image: none; overflow-x: auto; }
  }
  @media (max-width: 760px) {
    #app .client-marquee { margin-top: 20px; padding-top: 14px; }
    #app .mq-track { gap: 30px; animation-duration: 34s; }
    #app .mq-item { font-size: 20px; }
    #app .mq-item.is-slot { font-size: 12.5px; padding: 6px 11px; }
    /* keep the strip clear of the viewport-anchored hood toggle */
    #app .mq-viewport { margin-right: 60px; -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 86%, transparent 100%); mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 86%, transparent 100%); }
  }

  /* ===== MOBILE HEADER FIT (was clipping the CTA and hamburger) ===== */
  #app .header-cta .btn svg { width: 17px; height: 17px; flex: none; }
  @media (max-width: 760px) {
    #app .header-cta .btn-amber .btn-label { display: none; }
    #app .header-cta .btn-amber { width: 48px; padding: 0; gap: 0; }
    #app .header-cta { gap: 8px; }
    #app .nav-row { gap: 10px; }
  }
  @media (max-width: 420px) {
    #app .brand .brand-div { font-size: 14px; padding-left: 9px; }
    #app .brand img.mark, #app .logo-chip img { height: 30px; }
    #app .header-cta .btn-amber { width: 44px; }
  }
  @media (max-width: 340px) {
    #app .brand .brand-div { display: none; }
  }

  /* ===== FIXED CHROME MUST NOT SIT ON CONTENT ===== */
  @media (max-width: 560px) {
    #app .hood-toggle span { display: none; }
    #app .hood-toggle { padding: 13px; }
  }
  @media (max-width: 760px) {
    #app .hero { min-height: auto; }                  /* 92vh left dead space above the copy */
    #app .concept-ribbon { position: static !important; margin: 10px auto 0; display: table; }
    #app .hero-content { padding-bottom: 72px; }
    #app .map-wrap { padding-bottom: 68px; }          /* clears the hood toggle */
    #app .map-readout { padding-bottom: 4px; }
  }

  /* ============ BRAND LOGO ============ */
  #app .brand img.mark { width: auto; height: 42px; flex-shrink: 0; mix-blend-mode: multiply; }
  #app .footer-logo { display: inline-flex; background: #fff; border-radius: 8px; padding: 7px 11px; }
  #app .footer-logo img { height: 34px; width: auto; display: block; }
  #app footer.site-footer .footer-brand span:last-child { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--amber-hi); font-size: 16px; }
  @media (max-width: 480px) {
    #app .brand img.mark { height: 34px; }
    #app .brand .brand-div { font-size: 15px; padding-left: 9px; }
  }

  /* ============ MOBILE OPTIMISATION ============ */
  @media (max-width: 980px) {
    /* thumb-sized targets on every tappable line */
    #app .breadcrumb a { display:inline-flex; align-items:center; min-height:40px; }
    #app .footer-grid li a { display:flex; align-items:center; min-height:44px; }
    #app .footer-grid p a { display:inline-flex; align-items:center; min-height:44px; }
    #app .city-services li a, #app .serviced-list li a { display:flex; align-items:center; min-height:44px; }
    #app .cross-links a { display:inline-flex; align-items:center; min-height:44px; }
    #app .footer-contact a, #app footer p a { display:inline-flex; align-items:center; min-height:44px; }
    #app .sibling-link { display:flex; align-items:center; min-height:48px; }
    #app .card-link, #app .goto { display:inline-flex; align-items:center; min-height:44px; }
    #app .contact-detail a { display:inline-flex; align-items:center; min-height:44px; }
    #app .hero-replay { min-height:44px; padding-inline:14px; }
    #app .brand small { font-size:11.5px; letter-spacing:.07em; }
    #app .social-row a { width:44px; height:44px; }
    #app .brand { min-height:44px; }
  }
  @media (max-width: 760px) {
    #app .cta-band .btn, #app .hero-actions .btn { width:100%; }
    #app .hero-actions { gap:10px; }
    #app .section-head { margin-bottom:24px; }
  }
  @media (max-width: 400px) {
    #app .btn-lg { height:52px; padding:0 18px; font-size:13px; }
    #app .spec-strip { grid-template-columns:1fr 1fr; }
  }

  /* ============ PRODUCTION BUILD ADDITIONS ============ */
  /* brand mark: the wordmark is in the image, so no text lockup beside it */
  #app .brand img.mark { width: auto; height: 52px; mix-blend-mode: normal; }
  #app .footer-logo { background: #fff; border-radius: 8px; padding: 8px 12px; }
  #app .footer-logo img { height: 44px; width: auto; }
  @media (max-width: 480px) { #app .brand img.mark { height: 40px; } }
  #app .page-updated { white-space: nowrap; }

  /* inline source citations: a real link beside the claim */
  #app a.cite-link { color: var(--amber); text-decoration: underline; text-decoration-color: rgba(39,100,174,.4); text-underline-offset: 3px; }
  #app a.cite-link:hover { text-decoration-color: var(--amber); }
  #app .section-panel a.cite-link { color: var(--amber-hi); text-decoration-color: rgba(143,188,238,.5); }

  /* long-form service / city pages */
  /* These caps read low on purpose. `1ch` is the width of the digit zero, and Barlow's
     zero is narrower than its average letter, so a 70ch cap actually renders about 88
     characters per line against the 80 WCAG 1.4.8 allows. Measured, not guessed. */
  #app .prose { max-width: 52ch; }
  /* Once .truth-grid collapses to one column these cards are full width, and their
     paragraphs carried no measure at all. Measured 684px and 85-92 characters. */
  /* Measured exactly, by walking every character with a Range and grouping by line
     top rather than dividing total length by line count, which flatters the result.
     At 60ch the column is 597px and carries 89 characters; WCAG 1.4.8 caps at 80 and
     60-75 is the comfortable band. 52ch lands about 76. These two containers had no
     cap at all and ran 98-101 characters at 768px. */
  #app .truth-card p { max-width: 52ch; }
  #app blockquote p, #app figure blockquote { max-width: 52ch; }
  #app .block-copy p { max-width: 52ch; }
  #app .contact-card p { max-width: 52ch; }
  #app .section > p, #app .wrap > p { max-width: 52ch; }
  #app .dealer-strip p { max-width: 52ch; }
  #app .prose h2 { margin-top: 42px; }
  #app .prose h2:first-child { margin-top: 0; }
  #app .prose p { margin-top: 14px; font-size: 16.5px; line-height: 1.65; color: var(--ink); }
  #app .prose ul { margin-top: 12px; display: grid; gap: 8px; }
  #app .prose ul li { padding-left: 22px; position: relative; font-size: 15.5px; line-height: 1.5; }
  #app .prose ul li::before { content: ''; position: absolute; left: 0; top: 9px; width: 10px; height: 3px; background: var(--amber); }
  #app .two-col { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 48px; align-items: start; }
  #app .two-col .aside { position: sticky; top: 96px; display: grid; gap: 16px; }
  #app .aside-card { background: var(--surface); border: 1px solid var(--line); border-top: 3px solid var(--amber); padding: 22px 24px; }
  #app .aside-card h3 { font-size: 20px; margin-bottom: 8px; }
  #app .aside-card p { font-size: 14.5px; color: var(--ink-soft); line-height: 1.55; }
  #app .aside-card .btn { width: 100%; margin-top: 14px; }
  #app .aside-card ul { display: grid; gap: 6px; margin-top: 10px; }
  #app .aside-card ul a { font-size: 14.5px; color: var(--amber); font-weight: 600; }
  #app .steps { counter-reset: step; display: grid; gap: 14px; margin-top: 16px; }
  #app .steps li { counter-increment: step; display: grid; grid-template-columns: 44px 1fr; gap: 14px; align-items: start; background: var(--surface); border: 1px solid var(--line); padding: 16px 18px; }
  #app .steps li::before { content: counter(step, decimal-leading-zero); font-family: var(--font-mono); font-size: 13px; color: var(--amber); padding-top: 3px; }
  #app .steps li b { display: block; font-family: var(--font-display); font-size: 18px; text-transform: uppercase; letter-spacing: .03em; }
  #app .steps li span { font-size: 14.5px; color: var(--ink-soft); line-height: 1.5; }
  #app .art-frame { background: var(--surface); border: 1px solid var(--line); padding: 22px; }
  #app .where-strip { margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--line); font-size: 15px; color: var(--ink-soft); line-height: 1.9; max-width: 62ch; }
  #app .where-strip a { color: var(--amber); font-weight: 600; }
  #app .contact-card { background: var(--surface); border: 1px solid var(--line); border-top: 3px solid var(--amber); padding: 28px 30px; display: grid; gap: 12px; }
  #app .contact-card h3 { margin-bottom: 4px; }
  #app .contact-card p { font-size: 15px; color: var(--ink-soft); }
  #app .contact-card .btn { justify-content: center; }
  /* A grid track's automatic minimum is its content's MIN-CONTENT width, so a single
     unbreakable token sets the width of everything else in the card. The email address
     is 33 characters with no break opportunity and measured a 258px minimum inside a
     card that has about 228px to give at 320px. That pushed the heading, both
     paragraphs and both buttons to 353px in a 320px viewport, where the page wrapper's
     overflow:clip cut them off: on a small phone the call button and the email address
     were both partly off the screen, on the contact page. Let the address break, and
     stop any future long token doing the same. */
  #app .contact-card > * { min-width: 0; }
  #app .contact-card a, #app .contact-card .btn { overflow-wrap: anywhere; }
  @media (max-width: 900px) { #app .two-col { grid-template-columns: minmax(0, 1fr); } #app .two-col .aside { position: static; } }

  /* ============ POST-CHECK FIXES ============ */
  /* the H1 now carries the keyword phrase, so it runs longer than the old punchline */
  #app .hero-content h1 { font-size: clamp(40px, 5.4vw, 72px); max-width: 18ch; }
  /* steps: the ::before marker owns column 1 for both rows; title and copy stack in column 2 */
  #app .steps li::before { grid-row: 1 / span 2; }
  #app .steps li b, #app .steps li span { grid-column: 2; }
  /* thumb-sized link lists on small screens (inline prose links are exempt, per WCAG 2.5.8) */
  @media (max-width: 980px) {
    #app .where-strip a, #app .aside-card ul a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 2px; }
    #app .breadcrumb a { padding: 0 6px; margin-left: -6px; }
  }
  #app .hero-content h1 { font-size: clamp(38px, 4.8vw, 64px); max-width: 20ch; }
  #app .map-mini text { font-family: var(--font-mono); }

  /* ============ AUTHORIZED DEALER STRIP ============ */
  #app .dealer-strip { margin-top: 28px; padding: 22px 26px; background: var(--surface); border: 1px solid var(--line); display: grid; grid-template-columns: auto 1fr; gap: 10px 28px; align-items: center; }
  #app .dealer-strip ul { display: flex; flex-wrap: wrap; gap: 8px 10px; }
  #app .dealer-strip li { font-family: var(--font-display); font-weight: 700; font-size: 15px; letter-spacing: .05em; text-transform: uppercase; color: var(--navy); padding: 7px 12px; border: 1px solid var(--line); background: var(--ground); }
  #app .dealer-strip li small { font-family: var(--font-mono); font-weight: 400; font-size: 11px; letter-spacing: .1em; color: var(--ink-soft); margin-left: 6px; }
  #app .dealer-strip p { grid-column: 1 / -1; font-size: 14px; color: var(--ink-soft); }
  @media (max-width: 760px) { #app .dealer-strip { grid-template-columns: 1fr; } }
  /* narrow phones: the hours table and the long email button must shrink, not clip */
  #app .contact-grid > * { min-width: 0; }
  @media (max-width: 420px) {
    #app .hours-table { font-size: 12.5px; table-layout: fixed; }
    #app .hours-table td:last-child { white-space: normal; }
    #app .contact-detail { font-size: 13.5px; }
    #app .contact-detail span, #app .contact-detail a { overflow-wrap: anywhere; }
    #app .contact-card { padding: 22px 18px; }
    #app .contact-card .btn { white-space: normal; height: auto; min-height: 48px; padding: 12px 14px; line-height: 1.25; text-align: center; font-size: 12.5px; }
  }

  /* ============ TRUST STRIP IN THE FIRST VIEWPORT ============ */
  /* hero content is a column so the strip can be re-ordered per breakpoint */
  #app .hero-content { display: flex; flex-direction: column; align-items: flex-start; }
  #app .hero-content > * { flex: none; }
  #app .client-marquee { width: 100%; max-width: 720px; }
  /* short desktop/laptop screens: tighten the hero so the strip lands above the fold */
  @media (min-width: 981px) and (max-height: 900px) {
    #app .hero-content { padding-block: 40px 34px; }
    #app .hero-content h1 { font-size: clamp(36px, 4.2vw, 52px); }
    #app .hero-dek { margin-top: 14px; font-size: clamp(15.5px, 1.6vw, 17px); }
    #app .hero-actions { margin-top: 20px; }
    #app .client-marquee { margin-top: 18px; padding-top: 12px; }
    #app .hero-replay { margin-top: 14px; }
    #app .hero { min-height: 0; }
  }
  /* phones: the strip moves ABOVE the buttons (the header call button keeps the CTA visible) */
  @media (max-width: 980px) {
    #app .client-marquee { order: 4; margin-top: 18px; padding-top: 12px; }
    #app .hero-actions { order: 5; margin-top: 20px; }
    #app .hero-replay { order: 6; }
    #app .hero-content { padding-block: 34px 44px; }
    #app .hero-dek { margin-top: 12px; }
  }
  /* very small phones: one more notch so the strip at least crests the fold */
  @media (max-width: 400px) {
    #app .hero-content { padding-block: 26px 36px; }
    #app .hero-content h1 { font-size: clamp(30px, 9.4vw, 36px); }
    #app .hero-dek { font-size: 15px; }
    #app .hero-actions { margin-top: 16px; gap: 8px; }
    #app .client-marquee { margin-top: 14px; padding-top: 10px; }
  }
  /* flex children must never outgrow the hero column */
  #app .hero-content > * { max-width: 100%; min-width: 0; }
  /* ...but that rule has the same specificity as the measure cap on .hero-dek and
     comes later, so it was quietly overriding it: the dek measured 100% of the hero
     and ran 91 characters at 768px against the 80 WCAG 1.4.8 allows. min() keeps
     both intentions - hold the measure, never outgrow the column. */
  #app .hero-content .hero-dek { max-width: min(50ch, 100%); }
  @media (max-width: 760px) {
    #app .hero-actions { align-self: stretch; }
    #app .hero-actions .btn { white-space: normal; height: auto; min-height: 52px; line-height: 1.25; padding: 12px 16px; text-align: center; }
  }
  /* the hero call button drops "the service line" on narrow phones so the number breathes */
  @media (max-width: 480px) {
    #app .btn-longlabel { display: none; }
    #app .hero-actions .btn { font-size: 13.5px; letter-spacing: .05em; }
  }

  /* ============ GIVING LINE ============ */
  #app .give-line { margin-top: 18px; padding-top: 16px; border-top: 1px solid rgba(255,255,255,.16); }
  #app .give-line p { font-size: 15px; line-height: 1.6; color: rgba(255,255,255,.85); max-width: 62ch; }
  #app .give-line strong { color: var(--amber-hi); font-weight: 600; }

  /* the H1 wraps at the container like every other page title, not at a narrow ch box */
  #app .hero-content h1 { max-width: 100%; }
  /* footer credit link gets a thumb-sized hit area on phones */
  @media (max-width: 980px) {
    #app .footer-bottom a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; }
  }

  /* ===== FOOTER COMPRESSION ON PHONES (2026-09-02) =====
     Below 480px the footer stacked ~22 tap-height links in one column and
     scrolled forever. Two-column link lists halve the height; tap targets
     stay at 44px. */
  @media (max-width: 480px) {
    #app .footer-grid { gap: 26px; padding-block: 34px 26px; }
    #app .footer-grid ul { display: grid; grid-template-columns: 1fr 1fr; column-gap: 14px; }
    #app .footer-grid h4 { margin-bottom: 8px; }
    #app .footer-grid p, #app .footer-grid li { margin-bottom: 4px; }
    #app .footer-bottom { padding-block: 14px; font-size: 12px; line-height: 1.8; }
  }

  /* ---------------------------------------------------------------------------
     SOURCE CITATIONS.  Added 7 September 2026.

     This site had 21 source LINKS and zero visible citations: real anchors pointing at
     primary sources, sitting inside running sentences, with nothing to say the document
     had been read or when. The residential site puts a dated source line under the claim;
     this site shipped four days before that discipline existed and never got the component.

     Why it is not cosmetic: Bing ranks cited content above uncited and ties the same bar to
     Copilot grounding eligibility, and the observed AI-citation pattern is that a visible
     date, a visible publisher and on-page citations only work together. Citations with no
     date read as abandoned research.

     Same shape as the residential component, in this site's own palette.
     --------------------------------------------------------------------------- */
  /* This site spaces prose with margin-TOP on p (14px), not margin-bottom, so a negative top
     margin here does not tighten anything, it overlaps the paragraph above by exactly its own
     value. Caught by the overlap audit at every width. 8px is deliberately less than the 14px
     between paragraphs, which is what visually binds a source to the claim it belongs to. The
     next paragraph brings its own 14px, so this needs no bottom margin. */
  #app .cite{display:block;margin:8px 0 0;padding-left:16px;
    border-left:2px solid var(--line);
    font-family:var(--font-mono);font-size:12.5px;line-height:1.6;color:var(--ink-soft);}
  #app .cite a{color:var(--ink-soft);text-decoration:underline;
    text-decoration-color:rgba(39,100,174,.45);text-underline-offset:2px;}
  #app .cite a:hover,#app .cite a:focus-visible{color:var(--amber);text-decoration-color:var(--amber);}
  /* on the dark navy panels the muted ink disappears, so lift it there */
  #app .section-panel .cite,#app .panel-dark .cite{color:rgba(255,255,255,.72);
    border-left-color:rgba(255,255,255,.22);}
  #app .section-panel .cite a,#app .panel-dark .cite a{color:rgba(255,255,255,.8);}
  #app .section-panel .cite a:hover,#app .panel-dark .cite a:hover{color:var(--amber-hi);}
  @media (max-width:620px){
    #app .cite{font-size:12px;padding-left:13px;}
  }

  /* ---------------------------------------------------------------------------
     GUIDES.  Added 7 September 2026.

     The call strip exists because of a measured fault on the residential site: guide
     pages put their call card in an aside that stacks below the article on phones, so
     the first way to reach anybody sat six to eight screens down. One line and one
     48px button directly under the standfirst fixes that on every guide from day one.
     --------------------------------------------------------------------------- */
  #app .guide-help{display:flex;align-items:center;gap:14px 18px;flex-wrap:wrap;
    margin:20px 0 0;padding:14px 18px;border-left:3px solid var(--amber);
    border-radius:0 6px 6px 0;background:#fff;border-top:1px solid var(--line);
    border-right:1px solid var(--line);border-bottom:1px solid var(--line);}
  #app .guide-help p{margin:0;flex:1 1 16rem;min-width:0;font-size:15px;line-height:1.55;color:var(--ink-soft);}
  #app .guide-help .btn{flex:0 0 auto;}
  @media (max-width:560px){ #app .guide-help .btn{width:100%;text-align:center;} }

  /* hub cards: same idiom as the service cards, question as the heading */
  #app .guide-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:18px;}
  #app .guide-card{display:flex;flex-direction:column;gap:10px;background:#fff;
    border:1px solid var(--line);border-top:3px solid var(--amber);border-radius:8px;
    padding:24px 24px 20px;color:inherit;text-decoration:none;
    transition:transform .22s ease,box-shadow .22s ease;}
  #app .guide-card:hover{transform:translateY(-3px);box-shadow:0 10px 26px rgba(15,32,54,.10);}
  /* 19px against the 16.5px lead was a ratio of 1.12, under the ~1.25 where a
     heading stops reading as a heading (measured at 390px, 2026-09-20). */
  #app .guide-card h2{font-size:21.5px;line-height:1.3;margin:0;}
  #app .guide-card p{margin:0;font-size:14.5px;line-height:1.55;color:var(--ink-soft);}
  #app .guide-card .gc-tag{font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;
    text-transform:uppercase;color:var(--amber);}
  #app .guide-card .goto{margin-top:auto;padding-top:6px;font-family:var(--font-mono);
    font-size:12px;color:var(--amber);}

  /* ============ SYMPTOM TRIAGE (commercial-door-problems) ============ */
  /* Verdict colors live on the light ground: brick = stop, gold = today,
     slate = book, royal = staff-checkable. Amber (blue) stays the CTA color only. */
  #app {
    --sx-now:#A63A24;   --sx-now-bg:rgba(166,58,36,.10);
    --sx-today:#8A5A10; --sx-today-bg:rgba(138,90,16,.11);
    --sx-book:#4B5C6F;  --sx-book-bg:rgba(75,92,111,.11);
    --sx-check:#1B4E8C; --sx-check-bg:rgba(27,78,140,.10);
  }
  .sx-table{margin-top:0;}
  .sx-table thead th{line-height:1.35;}
  /* row headers are symptom links, not column headers: undo the navy-cap th treatment */
  #app .sx-table tbody th{width:34%;font-weight:600;padding-top:2px;padding-bottom:2px;
    background:var(--surface);color:var(--ink);text-transform:none;letter-spacing:0;
    font-family:var(--font-body);font-size:14.5px;}
  .sx-table td:first-of-type{width:38%;}
  .sx-table tbody td,.sx-table tbody th{vertical-align:middle;}
  #app .sx-table tbody th a{display:flex;align-items:center;min-height:46px;padding-block:9px;
    color:var(--ink);font-family:var(--font-body);font-size:14.5px;text-transform:none;letter-spacing:0;
    text-decoration:underline;text-decoration-thickness:1px;
    text-decoration-color:rgba(39,100,174,.6);text-underline-offset:3px;
    transition:color .18s,text-decoration-color .18s;}
  #app .sx-table tbody th a:hover,#app .sx-table tbody th a:focus-visible{
    color:var(--amber-dn);text-decoration-color:var(--amber-dn);}
  #app .sx-table .sx-grp th{font-family:var(--font-mono);font-size:11px;font-weight:500;
    letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);
    background:var(--ground);padding-top:14px;padding-bottom:10px;}
  .sx-tag{font-family:var(--font-mono);font-size:11px;font-weight:500;letter-spacing:.11em;
    text-transform:uppercase;border-radius:3px;padding:5px 9px;display:inline-block;
    line-height:1.35;white-space:normal;}
  .sx-now{background:var(--sx-now-bg);color:var(--sx-now);}
  .sx-today{background:var(--sx-today-bg);color:var(--sx-today);}
  .sx-book{background:var(--sx-book-bg);color:var(--sx-book);}
  .sx-check{background:var(--sx-check-bg);color:var(--sx-check);}
  .sx-verdict{display:flex;flex-wrap:wrap;align-items:center;gap:10px 12px;font-size:16.5px;}
  /* the quiet route back to the table; real 44px target on a phone */
  #app .sx-back{display:inline-block;margin-left:4px;font-family:var(--font-mono);font-size:12px;
    letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);text-decoration:none;
    padding:11px 0;min-height:44px;line-height:22px;white-space:nowrap;transition:color .18s;}
  #app .sx-back:hover,#app .sx-back:focus-visible{color:var(--amber-dn);}
  #app :is(p,li,td,dd,figcaption) a.sx-back:not(.btn){color:var(--ink-soft);}
  #app :is(p,li,td,dd,figcaption) a.sx-back:not(.btn):hover,
  #app :is(p,li,td,dd,figcaption) a.sx-back:not(.btn):focus-visible{color:var(--amber-dn);}
  #app .sx-endnote{margin:2px 0 0;}
  /* anchored headings land clear of the sticky header, and each symptom gets a
     hairline boundary on phones so two answers never run together while scrolling */
  #app .prose h2[id]{scroll-margin-top:96px;}
  @media (max-width:760px){
    #page-commercial-door-problems .prose h2:not(:first-child){
      border-top:1px solid var(--line);margin-top:4px;padding-top:26px;}
  }

  /* ============ TABLES ON A PHONE (ai-visibility-pass §4b practice 4) ============ */
  /* The canon asks for real tables that "stack to labelled cards on mobile without ceasing
     to be tables". Below 560px each row becomes a card: the row header is its title, and
     every other cell prints its own column label from data-label. The <thead> is hidden
     visually but stays in the markup, so what a crawler parses does not change at all. */
  @media (max-width: 560px) {
    #app .spec-table-wrap { border: 0; overflow: visible; -webkit-overflow-scrolling: auto; }
    /* stacked-card width floor */
    #app .spec-table-wrap table.spec-table, #app .scroll-x table.spec-table, #app table.spec-table { min-width: 0; width: 100%; }
    #app .scroll-x { overflow-x: visible; }
    /* a short or numeric row header cannot stand alone as a card title, so it prints
       its column label like every other cell does */
    #app table.spec-table tbody th[scope="row"][data-label]::before {
      content: attr(data-label); display: block; font-family: var(--font-mono);
      font-size: 9.5px; letter-spacing: .13em; text-transform: uppercase;
      opacity: .72; font-weight: 400; margin-bottom: 3px;
    }
    /* display:none, not a visually-hidden box: the column labels are printed on every
       cell by data-label, so nothing is lost, and the hidden row no longer leaves
       full-width child boxes for a layout auditor to trip over. The <thead> is still in
       the HTML, so what a crawler parses is unchanged. */
    #app table.spec-table thead { display: none; }
    #app table.spec-table tbody tr {
      display: block; border: 1px solid var(--line); border-radius: 4px;
      margin-bottom: 12px; background: var(--surface); overflow: hidden;
    }
    #app table.spec-table tbody tr:last-child { margin-bottom: 0; }
    #app table.spec-table tbody th,
    #app table.spec-table tbody td { display: block; width: auto; border-bottom: 0; }
    #app table.spec-table tbody th[scope="row"] { padding: 11px 14px; }
    #app table.spec-table tbody td { padding: 11px 14px; border-top: 1px solid var(--line); }
    #app table.spec-table tbody td[data-label]::before {
      content: attr(data-label); display: block; font-family: var(--font-mono);
      font-size: 9.5px; letter-spacing: .13em; text-transform: uppercase;
      color: var(--ink-soft); margin-bottom: 4px;
    }
    /* a group band is a section heading, not a card */
    #app table.spec-table tbody tr.sx-grp {
      border: 0; background: transparent; margin: 20px 0 8px; border-radius: 0;
    }
    #app table.spec-table tbody tr.sx-grp th { padding: 0 2px 6px; background: transparent; }
    /* the hours table is two columns of plain fact; keep it as rows, not cards */
    #app .hours-table tbody tr { display: table-row; border: 0; background: transparent; margin: 0; }
    #app .hours-table tbody th, #app .hours-table tbody td { display: table-cell; }
    #app .hours-table tbody td[data-label]::before { content: none; }
  }

  #app .hours-table caption { caption-side: top; text-align: left; font-family: var(--font-mono);
    font-size: 11.5px; line-height: 1.5; color: var(--ink-soft); padding-bottom: 10px; }

  /* ============ LEDE AND BYLINE ============ */
  /* The opening paragraph is the block an answer engine lifts verbatim, so it is set at body
     size and prose measure rather than as small print, with the publisher and date directly
     under it. Both were repeated inline styles on every page that has them. */
  #app .lede { max-width: 64ch; margin-top: 14px; font-size: 16.5px; }
  #app .byline { font-family: var(--font-mono); font-size: 12.5px; line-height: 1.55; max-width: 66ch;
    color: var(--ink-soft); margin-top: 14px; }

  /* ============ PRICES PAGE ============ */
  /* The figure is the point of a rate table, so it never breaks mid-number and it reads as
     the heaviest thing in its cell. Columns are fixed rather than auto-balanced: left to
     itself the browser gave the description column the room and wrapped "$147.50 an hour
     plus HST" onto three lines. */
  #app table.rate-table { table-layout: fixed; }
  #app table.rate-table th[scope="col"]:nth-child(1) { width: 27%; }
  #app table.rate-table th[scope="col"]:nth-child(2) { width: 23%; }
  #app table.rate-table .fig { display: block; white-space: nowrap; font-weight: 600;
    font-size: 15px; color: var(--ink); }
  /* Below 560px the row is a stacked card and the <thead> is gone, so the fixed widths have
     nothing to apply to: hand the layout back to the browser and set the figure inline. */
  @media (max-width: 560px) {
    #app table.rate-table { table-layout: auto; }
    #app table.rate-table .fig { display: inline; font-size: 16.5px; }
  }
  /* This H1 is the query a buyer types, not a sentence. At the site's floor of 44px it still
     ran seven lines and pushed the prices under the fold on a phone, so this page scales it
     down with the viewport instead. */
  #page-pricing h1 { font-size: clamp(34px, 8.5vw, 72px); }
  #page-pricing .prose h2[id] { scroll-margin-top: 96px; }

  /* GOOGLE RATING BAR, added 2026-09-20. The home page had shown the review COUNT since launch
     but never the score or the stars; Trevor asked for the stars to be brought over. The reviews
     are the PARENT company's (Garage Doorman) single Google profile, which is why the label names
     it rather than implying a separate commercial profile. See RATING in site.js.

     COLOUR, and why it is a literal and not a token. This theme was re-skinned from the dark
     industrial palette to brand blue and the VARIABLE NAMES kept their old amber spelling while
     holding blue values: --amber is #2764AE. The first version of this block used var(--amber)
     for the stars and var(--ink) for the score, which rendered blue stars and near-black digits
     on the navy trust panel, both effectively invisible (measured 2026-09-20). Google's rating
     stars are gold everywhere a person has ever seen one, so gold is what they are here, stated
     outright rather than routed through a token whose name lies about its value. */
  .rating-bar{display:flex;flex-wrap:wrap;align-items:center;gap:10px 26px;margin-bottom:14px;}
  .rating-score{display:flex;align-items:baseline;gap:10px;}
  .rating-score b{font-family:var(--font-display);font-size:34px;line-height:1;color:var(--ink);}
  .rating-score .rs-out{font-family:var(--font-mono);font-size:12px;color:var(--ink-soft);}
  .rating-stars{display:flex;gap:3px;color:#F2B01E;align-self:center;}
  .rating-stars svg{width:17px;height:17px;}
  .rating-src{font-family:var(--font-mono);font-size:12px;color:var(--ink-soft);letter-spacing:.03em;}
  .rating-src b{color:var(--ink);font-weight:600;}
  /* On the navy trust panel every default above is the wrong side of the contrast line. */
  #app .section-panel .rating-score b{color:#fff;}
  #app .section-panel .rating-score .rs-out{color:rgba(255,255,255,.72);}
  #app .section-panel .rating-src{color:rgba(255,255,255,.78);}
  #app .section-panel .rating-src b{color:#fff;}
  @media (max-width:560px){ .rating-bar{gap:8px 16px;} .rating-score b{font-size:30px;} }

  /* READING MEASURE AND HEADING WRAP, added 2026-09-20 after a visual pass.
     At 768px the prose ran 87 to 95 characters per line across 18 pages. WCAG
     1.4.8 caps readable text at 80 and 60 to 75 is the comfortable band; a
     facility manager reading a spec guide on a tablet is exactly the reader who
     loses their place on a 95-character line.
     Capped per component rather than with a blanket p{max-width}, because a
     blanket rule also squeezes text inside narrow grid cells and aside cards
     where the cell is already the measure. text-wrap:balance costs nothing, is
     ignored where unsupported, and cleared 64 stranded last words in headings. */
  .prose > p, .prose > ul, .prose > ol, .prose > blockquote{max-width:72ch;}
  .aside-card p{max-width:60ch;}
  h1,h2,h3,h4{text-wrap:balance;}

  /* CREW CREDENTIALS, added 2026-09-20. Renders nothing until a credential is
     confirmed in site.js CREDENTIALS, so this CSS is dormant on a site that has
     confirmed none. Sits in the navy trust strip under the Google rating, which
     is where a property manager already looks for exactly these facts. */
  /* SCOPED WITH #app, and that is load-bearing rather than cosmetic. Both themes
     scope their resets as "#app ul, #app ol { ... }" and "#app .prose ul li { ... }",
     which is specificity (1,2,1). An unscoped ".creds li" is (0,2,0) and loses, so
     padding-left computed to 0px, the text started at the li's left edge, and the
     absolutely positioned tick landed on top of the first capital of every line.
     Visible in a screenshot on 2026-09-20 and invisible to every other check on
     this site, which is exactly the class of fault the visual pass exists for. */
  #app .creds{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px 22px;
         font-family:var(--font-mono);font-size:12px;letter-spacing:.03em;color:var(--ink-soft);}
  #app .creds li{position:relative;padding-left:18px;margin:0;}
  #app .creds li::before{content:"";position:absolute;left:0;top:.45em;width:7px;height:7px;
                    border-left:2px solid #F2B01E;border-bottom:2px solid #F2B01E;transform:rotate(-45deg);}
  #app .section-panel .creds{color:rgba(255,255,255,.82);}

  /* MOBILE HEADING SCALE, added 2026-09-20 after a mobile pass.
     The base rules are h1 clamp(44px,8vw,92px) and h2 clamp(30px,4.5vw,52px). On a
     phone the h1 scales down properly (33px at 390px, via the .city-hero override)
     but the h2 hits its 30px FLOOR and stops. The two then sit 3px apart, so the
     page has no visible top level: measured on 15 pages at 390px. The same 30px
     floor is why 87 headings were wrapping across four to six lines with a stranded
     word at that width.
     Lowering the h2 floor lets it scale with the h1 again. At 390px this gives
     h1 33px against h2 24px, a ratio of 1.37, comfortably past the 1.25 where a
     heading stops reading as a heading. */
  @media (max-width: 560px) {
    #app h2 { font-size: clamp(22px, 6.2vw, 30px); }
  }
