/* ============================================================
   smartlockinstaller.co.uk

   Rebuilt 2026-07-28 after the first attempt was, correctly, called out
   as a reskin of smartlockpro.co.uk: it kept that site's whole page
   architecture — sticky single-row nav, eyebrow/h1/sub/two-buttons hero,
   4-column spec strip, card grid, FAQ accordion, dark 3-column footer —
   and only changed the palette and typeface. Anyone visiting both would
   have recognised it immediately.

   What is deliberately different here, structurally, not just visually:
     - masthead header (brand row + nav row beneath a rule), NOT sticky,
       instead of a single sticky bar with brand-left/links-right/CTA
     - full-bleed photographic hero with the headline sitting ON it,
       instead of a text hero beside a product carousel
     - specs as an inline rule-separated run of text, not a 4-column grid
     - numbered full-width alternating image/text bands, instead of a
       heading + prose + card-grid rhythm
     - coverage as a dense district list, instead of cards
     - FAQ as an open two-column definition list with no JS, instead of
       an Alpine accordion
     - light minimal footer, instead of a dark 3-column one

   Palette is cool accent on light, chosen for maximum perceptual distance
   from smartlockpro's warm brass accent on a charcoal ground. Photography
   is duotoned into this palette (see seed_assets/build_images.py) which is
   also what stops shared source photos reading as the same pictures.
   ============================================================ */

@font-face {
  font-family: "Bricolage";
  src: url("/static/installer/fonts/bricolage-800.d2b972ecc13c.woff2") format("woff2");
  font-weight: 800;
  font-display: swap;
}
@font-face {
  font-family: "Instrument";
  src: url("/static/installer/fonts/instrument-400.18bdceb6a9fc.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Instrument";
  src: url("/static/installer/fonts/instrument-600.c92361ea5548.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}

:root {
  --ink: #131a2b;
  --ink-soft: #46506a;
  --paper: #ffffff;
  --mist: #eef0f6;
  --line: #d7dbe6;
  --accent: #3d34d6;
  --accent-dark: #2c25a8;
  --wrap: 1240px;
  --display: "Bricolage", Georgia, serif;
  --body: "Instrument", system-ui, -apple-system, sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
}
h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.025em;
  margin: 0;
  text-wrap: balance;
}
img {
  max-width: 100%;
  height: auto;
  display: block;
}
a {
  color: var(--accent);
}

.wrap {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 26px;
}
.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 12px;
  top: 12px;
  z-index: 99;
  background: var(--ink);
  color: #fff;
  padding: 10px 14px;
}
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- masthead (two rows, not a sticky bar) ---------- */
.util {
  background: var(--ink);
  color: #c9d0e2;
  font-size: 13.5px;
}
.util .wrap {
  display: flex;
  gap: 22px;
  align-items: center;
  min-height: 38px;
  flex-wrap: wrap;
}
.util a {
  color: #fff;
  text-decoration: none;
  font-weight: 600;
}
.util .spacer {
  margin-left: auto;
}

.masthead {
  border-bottom: 1px solid var(--line);
}
.masthead .wrap {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  padding-top: 26px;
  padding-bottom: 0;
}
.wordmark {
  display: block;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(21px, 2.5vw, 27px);
  letter-spacing: -0.035em;
  color: var(--ink);
  text-decoration: none;
  line-height: 1;
}
.wordmark span {
  color: var(--accent);
}
.masthead-strap {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 7px 0 0;
}
.mastnav {
  display: flex;
  gap: 26px;
  padding-bottom: 12px;
}
.mastnav a {
  color: var(--ink);
  text-decoration: none;
  font-size: 15px;
  font-weight: 600;
  padding-bottom: 10px;
  border-bottom: 2px solid transparent;
}
.mastnav a:hover {
  border-bottom-color: var(--accent);
}
.mast-toggle {
  display: none;
  background: none;
  border: 0;
  color: var(--ink);
  padding: 0 0 14px;
  cursor: pointer;
}
.mobnav {
  display: none;
  border-bottom: 1px solid var(--line);
  background: var(--mist);
}
.mobnav a {
  display: block;
  padding: 13px 0;
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
  border-bottom: 1px solid var(--line);
}
.mobnav a:last-child {
  border-bottom: 0;
}
[x-cloak] {
  display: none !important;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: var(--accent);
  color: #fff;
  font-family: var(--body);
  font-weight: 600;
  font-size: 16px;
  padding: 14px 24px;
  border: 2px solid var(--accent);
  border-radius: 2px;
  text-decoration: none;
  cursor: pointer;
}
.btn:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
}
.btn-ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--ink);
}
.btn-ghost:hover {
  background: var(--ink);
  color: #fff;
}
.btn-light {
  background: #fff;
  color: var(--ink);
  border-color: #fff;
}
.btn-block {
  width: 100%;
  justify-content: center;
}

/* ---------- full-bleed hero ---------- */
.hero {
  position: relative;
  background: var(--ink);
  min-height: 62vh;
  display: flex;
  align-items: flex-end;
}
.hero img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.62;
}
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Directional scrim: heaviest bottom-left where the type sits, clearing
     toward the top right so the photograph is still legible as a picture. */
  background: linear-gradient(
    to top right,
    rgba(19, 26, 43, 0.94) 0%,
    rgba(19, 26, 43, 0.72) 38%,
    rgba(19, 26, 43, 0.24) 78%
  );
}
.hero-in {
  position: relative;
  z-index: 1;
  width: 100%;
  padding-top: 96px;
  padding-bottom: 46px;
}
.hero h1 {
  color: #fff;
  /* 74px over a 15ch measure broke the headline across four lines and let
     it swallow the photograph. Longer measure, slightly smaller cap. */
  font-size: clamp(34px, 5.2vw, 62px);
  max-width: 19ch;
}
.hero .sub {
  color: #d6dcec;
  font-size: clamp(17px, 1.7vw, 20px);
  max-width: 50ch;
  margin: 22px 0 0;
}
.hero-actions {
  margin-top: 30px;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}

/* Specs as an inline rule-separated run, not a column grid. */
.specline {
  background: var(--ink);
  color: #b9c2d8;
  font-size: 14px;
}
.specline .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 0 30px;
  padding-top: 15px;
  padding-bottom: 15px;
}
.specline b {
  color: #fff;
  font-weight: 600;
}
.specline span + span::before {
  content: "";
  display: inline-block;
  width: 1px;
  height: 11px;
  background: rgba(255, 255, 255, 0.28);
  margin-right: 30px;
  vertical-align: -1px;
}

/* ---------- vertical rhythm ----------
   Wagtail wraps every StreamField block in <div class="w-block-x block-x">,
   so the block's own <section> is a grandchild of <main> and can never be
   targeted as a child. Spacing therefore has to live on these wrappers.
   Full-bleed blocks (hero, process bands, CTA strip) carry their own
   padding and must be exempt, or they gain a stripe of page background. */
main > [class*="block-"] {
  padding: 36px 0;
}
main > .block-hero,
main > .block-process,
main > .block-cta {
  padding: 0;
}
main > .block-heading {
  padding-bottom: 6px;
}
main > .block-hero + * {
  padding-top: 62px;
}
main > [class*="block-"]:last-child {
  padding-bottom: 84px;
}
main > .block-cta:last-child {
  padding-bottom: 0;
}

/* ---------- prose / headings ---------- */
.section {
  padding: 74px 0;
}
.section-mist {
  background: var(--mist);
}
.h-section {
  font-size: clamp(28px, 3.6vw, 44px);
  max-width: 20ch;
}
.prose {
  max-width: 66ch;
  font-size: 17.5px;
  line-height: 1.68;
}
.prose > * {
  margin: 0;
}
.prose > * + * {
  margin-top: 1.05em;
}
.prose ul {
  padding-left: 1.15em;
}
.prose li + li {
  margin-top: 0.4em;
}
.lede {
  font-size: clamp(19px, 2.1vw, 24px);
  line-height: 1.45;
  max-width: 34ch;
  color: var(--ink);
}

/* ---------- numbered alternating bands ---------- */
.band {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  border-top: 1px solid var(--line);
}
.band-media {
  position: relative;
  min-height: 380px;
  background: var(--mist);
}
.band-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.band-body {
  padding: 58px clamp(26px, 5vw, 84px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 660px;
}
/* Reverse every other band so the eye zig-zags down the page. */
.band:nth-child(even) .band-media {
  order: 2;
}
.band-num {
  font-family: var(--display);
  font-weight: 800;
  font-size: 15px;
  letter-spacing: 0.06em;
  color: var(--accent);
}
.band h3 {
  font-size: clamp(24px, 2.8vw, 34px);
  margin: 10px 0 14px;
}
.band p {
  margin: 0;
  color: var(--ink-soft);
  max-width: 46ch;
}
.band p + p {
  margin-top: 0.9em;
}

/* ---------- coverage list ---------- */
.districts {
  columns: 3;
  column-gap: 40px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.districts li {
  break-inside: avoid;
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: 15.5px;
}
.districts .code {
  font-weight: 600;
  min-width: 76px;
}
.districts .where {
  color: var(--ink-soft);
}

/* ---------- FAQ: open list, no accordion, no JS ---------- */
.qa {
  columns: 2;
  column-gap: 56px;
  margin: 0;
}
.qa > div {
  break-inside: avoid;
  margin-bottom: 30px;
}
.qa dt {
  font-weight: 600;
  font-size: 17px;
  margin-bottom: 7px;
}
.qa dd {
  margin: 0;
  color: var(--ink-soft);
  font-size: 16px;
}

/* ---------- page head (interior pages) ---------- */
.page-head {
  border-bottom: 1px solid var(--line);
  padding: 54px 0 44px;
}
.page-head .crumb {
  font-size: 13.5px;
  color: var(--ink-soft);
  margin: 0 0 14px;
}
.page-head h1 {
  font-size: clamp(34px, 5vw, 58px);
  max-width: 17ch;
}
.page-head .intro {
  margin-top: 18px;
  max-width: 58ch;
  color: var(--ink-soft);
  font-size: 18px;
}

/* ---------- forms ---------- */
.field {
  display: block;
  margin-bottom: 18px;
}
.field > label,
.field-label {
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  margin-bottom: 6px;
}
.input {
  width: 100%;
  font-family: inherit;
  font-size: 16px;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 13px 14px;
}
.input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.form-actions {
  display: flex;
  gap: 12px;
  margin-top: 8px;
}
.steps-bar {
  display: flex;
  gap: 10px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 24px;
}
.steps-bar .on {
  color: var(--accent);
}
.choice-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 18px;
}
.choice {
  display: block;
  text-align: center;
  padding: 16px 10px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: #fff;
  cursor: pointer;
  font-weight: 600;
  font-size: 14px;
}
.choice:has(:checked) {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.choice input {
  display: block;
  margin: 0 auto 8px;
  accent-color: var(--accent);
}
.form-success {
  color: #1c3fb0;
  font-weight: 600;
  background: #e8ebfb;
  border: 1px solid #c3cbf3;
  border-radius: 2px;
  padding: 14px 16px;
  margin: 0;
}

/* ---------- CTA strip ---------- */
.cta {
  background: var(--ink);
  color: #fff;
  padding: 64px 0;
}
.cta h2 {
  color: #fff;
  font-size: clamp(28px, 3.6vw, 42px);
  max-width: 20ch;
}
.cta p {
  color: #c3cbdf;
  max-width: 50ch;
  margin: 16px 0 28px;
}

/* ---------- footer: light, minimal, single row ---------- */
.site-footer {
  border-top: 1px solid var(--line);
  padding: 40px 0 46px;
  font-size: 14.5px;
  color: var(--ink-soft);
}
.site-footer a {
  color: var(--ink-soft);
  text-decoration: none;
}
.site-footer a:hover {
  color: var(--accent);
}
.frow {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 28px;
  align-items: baseline;
}
.frow .spacer {
  margin-left: auto;
}
.fnote {
  margin: 26px 0 0;
  font-size: 12.5px;
  max-width: 92ch;
  color: #6b7488;
}
.fbot {
  margin-top: 16px;
  display: flex;
  gap: 8px 22px;
  flex-wrap: wrap;
  font-size: 12.5px;
}

/* ---------- cookie banner ---------- */
.cookie {
  position: fixed;
  bottom: 18px;
  left: 18px;
  right: 18px;
  max-width: 430px;
  background: var(--ink);
  color: #dfe4f2;
  padding: 20px 22px;
  z-index: 90;
  font-size: 14px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.32);
}
.cookie p {
  margin: 0 0 14px;
}
.cookie a {
  color: #fff;
}
.cookie .row {
  display: flex;
  gap: 10px;
}
/* base.html's cookie banner markup uses .btn-outline. The rebuild renamed
   that variant to .btn-ghost, which left both consent buttons rendering as
   the same solid indigo — so "Essential only" and "Accept all" were visually
   indistinguishable, on the one control where the choice has to be obvious. */
.cookie .btn-outline {
  background: transparent;
  color: #fff;
  border-color: rgba(255, 255, 255, 0.45);
}
.cookie .btn-outline:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: #fff;
}
.hidden {
  display: none;
}

@media (max-width: 980px) {
  .masthead {
    position: relative;
    z-index: 10;
  }
  /* DIRECT CHILD, not a descendant selector. .mobnav lives inside .masthead,
     so `.masthead .wrap` also matched `.mobnav .wrap` and pushed the header's
     card treatment — and its align-items: flex-start — onto the menu panel.
     That is why the menu links shrank to their own text width and their
     underlines came out as ragged stubs instead of full-width rules. */
  /* Full-width bar, not an inset card. Insetting it exposed the card's own
     left and right borders as two vertical strokes either side of the logo
     and burger, which read as stray bracket marks. The surface and shadow
     live on .masthead so the bar spans the viewport, while the padding
     keeps its contents on the page's 26px gutter. */
  .masthead {
    background: #ffffff;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.06);
  }
  .masthead > .wrap {
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: nowrap;
    margin: 0;
    padding: 14px 26px;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }
  .masthead > .wrap > div:first-child {
    min-width: 0;
    flex: 1 1 auto;
  }
  .masthead-strap {
    display: none;
  }
  /* No !important needed: this matches .mastnav at the same specificity and
     sits later in the file, so it already wins. */
  .mastnav {
    display: none;
  }
  .mast-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-left: auto;
    padding: 0;
    line-height: 1;
    align-self: flex-start;
  }
  .mast-toggle svg {
    display: block;
  }
  /* Overlays rather than pushing the page down, and is styled explicitly
     here instead of inheriting the header's box by accident. Same margin,
     border and radius as the header card above it, so the two read as one
     component. */
  .mobnav {
    display: block;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    width: 100%;
    border: 0;
    border-bottom: 1px solid var(--line);
    background: #ffffff;
    box-shadow: 0 18px 34px rgba(0, 0, 0, 0.12);
  }
  .mobnav .wrap {
    display: flex;
    flex-direction: column;
    /* stretch, so each row fills the panel and its underline is a full-width
       rule. Without it the rows shrink-wrapped their text. */
    align-items: stretch;
    margin: 0;
    padding: 4px 26px 14px;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  .mobnav a {
    display: block;
    padding: 15px 2px;
  }
  .band {
    grid-template-columns: 1fr;
  }
  .band:nth-child(even) .band-media {
    order: 0;
  }
  .band-media {
    min-height: 260px;
  }
  .band-body {
    padding: 40px 26px;
    max-width: none;
  }
  .districts {
    columns: 2;
  }
  .qa {
    columns: 1;
  }
}
/* The inline dividers only work while the spec strip is a single row. Once
   it wraps, every item starting a new line carries a leading bar with
   nothing before it, reading as a broken bullet list. Below this width the
   strip becomes an explicit stack instead. */
@media (max-width: 760px) {
  .specline .wrap {
    flex-direction: column;
    gap: 7px;
  }
  .specline span + span::before {
    display: none;
  }
}

@media (max-width: 620px) {
  /* The strap wraps to two lines beside the burger at this width and
     unbalances the masthead; the same claims are on the page anyway. */
  .masthead-strap {
    display: none;
  }
  .districts {
    columns: 1;
  }
  .choice-grid {
    grid-template-columns: 1fr;
  }
  .hero {
    min-height: 56vh;
  }
  .util .wrap {
    font-size: 12.5px;
    gap: 14px;
  }
}

.formwrap {
  max-width: 620px;
}

/* ---------- contact page ---------- */
.contact-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  gap: 56px;
  align-items: start;
}
.contact-aside h2 {
  font-size: 20px;
  margin-bottom: 18px;
}
.contact-list {
  margin: 0;
}
.contact-list > div + div {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
.contact-list dt {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 5px;
}
.contact-list dd {
  margin: 0;
  font-size: 15.5px;
}
@media (max-width: 900px) {
  .contact-cols {
    grid-template-columns: 1fr;
    gap: 40px;
  }
}

/* ---------- post-submission success panel ----------
   Shared template with smartlockpro (home/templates/booking/_success.html),
   this brand's values. Replaces the single line of text that used to be the
   whole confirmation and left the visitor with nowhere to go. */
.success-panel {
  border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  background: var(--mist);
  padding: 34px 36px 36px;
}
.success-panel:focus {
  outline: none;
}
.success-eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 10px;
}
.success-panel h2 {
  font-family: var(--display);
  font-size: clamp(24px, 2.8vw, 33px);
  line-height: 1.1;
  margin: 0 0 12px;
}
.success-lead {
  margin: 0 0 24px;
  font-size: 17px;
}
.success-steps {
  list-style: none;
  margin: 0 0 24px;
  padding: 0;
}
.success-steps li {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: 15.5px;
  color: var(--ink-soft);
}
.success-steps span {
  flex: none;
  width: 21px;
  height: 21px;
  background: var(--accent);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.success-note {
  font-size: 14.5px;
  color: var(--ink-soft);
  margin: 0 0 26px;
}
.success-actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
