/* ============================================================
   SmartLockPro design system
   ------------------------------------------------------------
   Hand-written CSS, deliberately replacing the Tailwind browser
   CDN this site used to load. That script was 276KB of JS that
   compiled CSS in the browser on every page load — Tailwind's own
   docs say not to do that in production, and it made the "mobile
   PageSpeed > 90" launch target in PLAN.md unreachable. The whole
   site is ~10 templates, so hand-written CSS is both smaller and
   easier to reason about.

   Fonts are self-hosted (static/fonts/) rather than pulled from
   Google Fonts: no third-party request on every page load, no
   extra DNS/TLS round trip, and nothing leaks visitor IPs to a
   third party (which also keeps the privacy policy honest).
   ============================================================ */

/* ---------- fonts ---------- */
@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-latin.cd56e2ec63d7.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Plex";
  src: url("../fonts/plex-400-latin.b2c9031d9fd6.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Plex";
  src: url("../fonts/plex-600-latin.70800b98b5e7.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ---------- tokens ---------- */
:root {
  --ink: #0e1116;
  --ink-2: #171b22;
  --paper: #f7f4ef;
  --surface: #ffffff;
  --brass: #b8752b;
  --brass-hover: #9c6222;
  /* Brass as a FILL behind white text. #b8752b is only 3.74:1 against
     white, below WCAG AA's 4.5:1 for normal text — which put the site's
     single most important element, the primary CTA, under the bar. This
     is the same hue a shade deeper: 5.16:1. --brass stays as-is for text,
     rules and accents on dark, where it passes comfortably. */
  --brass-fill: #9c5f1f;
  --brass-fill-hover: #834d16;
  --brass-lt: #e8b872;
  --steel: #5f6772;
  --line: #e2dcd2;
  --on-dark: #ede8e0;
  --on-dark-dim: #9aa1ac;
  --good: #047857;
  --warn: #b45309;
  --danger: #b91c1c;

  --wrap: 1200px;
  --wrap-narrow: 760px;
  --radius: 2px;

  --font-display: "Archivo", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-body: "Plex", ui-sans-serif, system-ui, -apple-system, sans-serif;
}

/* ---------- base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  letter-spacing: -0.03em;
  text-wrap: balance;
  margin: 0;
  line-height: 1.12;
}

a {
  color: var(--brass);
}
a:hover {
  color: var(--brass-hover);
}

img {
  max-width: 100%;
  height: auto;
}

:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}

[x-cloak] {
  display: none !important;
}

/* ---------- layout ---------- */
.wrap {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 28px;
}
.wrap-narrow {
  max-width: var(--wrap-narrow);
  margin: 0 auto;
  padding: 0 28px;
}

.section {
  padding: 84px 0;
}
.section-sm {
  padding: 52px 0;
}
.section-dark {
  background: var(--ink);
  color: var(--on-dark);
}
.section-dark h1,
.section-dark h2,
.section-dark h3 {
  color: #fff;
}

.sec-head {
  max-width: 680px;
  margin-bottom: 48px;
}
.sec-head h2 {
  font-size: clamp(28px, 3.4vw, 42px);
  font-weight: 800;
  margin-top: 14px;
}
.sec-head p {
  color: var(--steel);
  font-size: 17px;
  margin: 16px 0 0;
}
.section-dark .sec-head p {
  color: var(--on-dark-dim);
}

.label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brass);
  margin: 0;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: var(--brass-fill);
  color: #fff;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  padding: 13px 24px;
  border: 1px solid var(--brass-fill);
  border-radius: var(--radius);
  text-decoration: none;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s;
}
.btn:hover {
  background: var(--brass-fill-hover);
  border-color: var(--brass-fill-hover);
  color: #fff;
}
.btn-block {
  width: 100%;
  justify-content: center;
}

.btn-outline {
  background: transparent;
  color: var(--ink);
  border-color: var(--line);
}
.btn-outline:hover {
  background: rgba(0, 0, 0, 0.04);
  color: var(--ink);
  border-color: var(--steel);
}
.section-dark .btn-outline,
.hero .btn-outline,
.cookie .btn-outline {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.28);
}
.section-dark .btn-outline:hover,
.hero .btn-outline:hover,
.cookie .btn-outline:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

/* ---------- cards ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px;
}
a.card {
  display: block;
  text-decoration: none;
  color: inherit;
  transition:
    border-color 0.18s,
    transform 0.18s;
}
a.card:hover {
  border-color: var(--brass);
  transform: translateY(-2px);
  color: inherit;
}
.card h3 {
  font-size: 19px;
  font-weight: 700;
  margin-bottom: 8px;
}
.card p {
  color: var(--steel);
  font-size: 14.5px;
  margin: 0;
}
.go {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 16px;
  color: var(--brass);
  font-weight: 600;
  font-size: 13.5px;
}

/* ---------- nav ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(14, 17, 22, 0.94);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.nav-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 68px;
  gap: 28px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 19px;
  color: #fff;
  text-decoration: none;
  letter-spacing: -0.02em;
  white-space: nowrap;
}
.brand:hover {
  color: #fff;
}
.brand img {
  width: 26px;
  height: 26px;
  flex: none;
}
.nav-links {
  display: flex;
  align-items: center;
  gap: 22px;
  font-size: 14.5px;
  color: #c6cbd3;
}
.nav-links a {
  color: #c6cbd3;
  text-decoration: none;
}
.nav-links a:hover {
  color: var(--brass-lt);
}
.nav-cta {
  display: flex;
  align-items: center;
  gap: 14px;
}
.tel {
  display: flex;
  align-items: center;
  gap: 7px;
  color: #fff;
  text-decoration: none;
  font-weight: 600;
  font-size: 14.5px;
  white-space: nowrap;
}
.tel:hover {
  color: var(--brass-lt);
}
.wa {
  display: inline-flex;
  padding: 7px;
  color: #25d366;
  border-radius: var(--radius);
}
.wa:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #25d366;
}

.nav-toggle {
  display: none;
  background: none;
  border: 0;
  color: #fff;
  padding: 8px;
  margin-right: -8px;
  cursor: pointer;
}

/* dropdown */
.has-menu {
  position: relative;
}
.menu-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 0;
  color: #c6cbd3;
  font-family: var(--font-body);
  font-size: 14.5px;
  cursor: pointer;
  padding: 0;
}
.menu-btn:hover {
  color: var(--brass-lt);
}
.menu-btn svg {
  transition: transform 0.15s;
}
.menu-panel {
  position: absolute;
  left: 0;
  top: 100%;
  padding-top: 14px;
  width: 290px;
}
.menu-panel-in {
  background: var(--ink-2);
  border: 1px solid rgba(255, 255, 255, 0.12);
  padding: 8px;
}
.menu-panel a {
  display: block;
  padding: 10px 12px;
  color: #d7dbe1;
  text-decoration: none;
  font-size: 14.5px;
}
.menu-panel a:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--brass-lt);
}

/* display:none here is the DESKTOP state only. Alpine's x-show works by
   setting and clearing an INLINE display, so it can never override a
   stylesheet rule — with `display: none` and nothing re-enabling it, the
   panel could not be shown at any width. The burger toggled, the icon
   swapped to a cross, and nothing appeared. See the 1000px query below,
   which is where the burger itself becomes visible. */
.nav-mobile {
  display: none;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  background: var(--ink);
  padding: 16px 0 22px;
}
.nav-mobile a {
  display: block;
  padding: 11px 0;
  color: #d7dbe1;
  text-decoration: none;
  font-size: 15px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.nav-mobile a:hover {
  color: var(--brass-lt);
}
/* `.nav-mobile a` (0,1,1) outranks `.btn` (0,1,0) and forces display:block,
   which kills the button's own flex centring and padding. Restore both. */
.nav-mobile .btn {
  display: flex;
  justify-content: center;
  margin-top: 16px;
  padding: 13px 20px;
  border-bottom: 0;
}

@media (max-width: 1000px) {
  .nav-links,
  .nav-cta .tel,
  .nav-cta .btn {
    display: none;
  }
  .nav-toggle {
    display: block;
  }
  /* Lets x-show take over: it hides the panel with an inline display:none
     when closed, and clears it to reveal this. [x-cloak] covers the gap
     before Alpine initialises. */
  .nav-mobile {
    display: block;
  }
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: #fff;
  color: var(--brass);
  padding: 12px 20px;
  z-index: 100;
  font-weight: 600;
}
.skip:focus {
  left: 12px;
  top: 12px;
}

/* ---------- hero ---------- */
.hero {
  position: relative;
  background: var(--ink);
  color: #fff;
  overflow: hidden;
}
.hero-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 60% 45%;
}
.hero-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    rgba(14, 17, 22, 0.96) 0%,
    rgba(14, 17, 22, 0.9) 42%,
    rgba(14, 17, 22, 0.45) 72%,
    rgba(14, 17, 22, 0.25) 100%
  );
}
.hero-in {
  position: relative;
  /* padding-top only — a `padding: 92px 0 0` shorthand here overrides .wrap's
     own `padding: 0 28px`, zeroing the horizontal gutters. Invisible on
     desktop, where .wrap's max-width creates the margin anyway, but on any
     viewport narrower than --wrap it put the hero copy flush against the
     screen edge while every other section stayed inset. */
  padding-top: 92px;
}
.hero-copy {
  max-width: 620px;
}
.hero h1 {
  font-size: clamp(36px, 4.6vw, 57px);
  font-weight: 800;
  line-height: 1.02;
  margin-top: 16px;
  color: #fff;
}
.hero .sub {
  color: #c6cbd3;
  font-size: 18px;
  margin: 22px 0 0;
  max-width: 520px;
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-top: 34px;
}
.price-tag {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  color: #fff;
  padding-left: 16px;
  border-left: 2px solid var(--brass);
}
.price-tag span {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 12.5px;
  color: var(--on-dark-dim);
}

.spec {
  position: relative;
  margin: 72px 0 0;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  column-gap: 48px;
}
.spec > div {
  position: relative;
  padding: 22px 0 24px;
}
/* Divider lives centred in the column gap, not on the cell edge. As a
   border-right it sat hard against the next column's text — with no
   horizontal padding the label started at exactly the divider's x, so the
   rule appeared to be touching the words. Inset top and bottom too, so it
   reads as a separator rather than a table gridline running into the
   border above. */
.spec > div + div::before {
  content: "";
  position: absolute;
  left: -24px;
  top: 20px;
  bottom: 22px;
  width: 1px;
  background: rgba(255, 255, 255, 0.13);
}
.spec dt {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brass-lt);
  margin-bottom: 5px;
}
.spec dd {
  margin: 0;
  font-size: 14.5px;
  color: #e7e9ec;
  font-weight: 500;
}
@media (max-width: 820px) {
  .spec {
    grid-template-columns: 1fr 1fr;
    column-gap: 28px;
  }
  .spec > div {
    padding: 16px 0 18px;
  }
  /* Two columns: only the second cell of each row gets a vertical rule,
     otherwise a divider appears at the start of the second row. */
  .spec > div:nth-child(odd)::before {
    display: none;
  }
  .spec > div + div::before {
    left: -14px;
  }
  /* And a horizontal rule between the two rows. */
  .spec > div:nth-child(n + 3)::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 1px;
    background: rgba(255, 255, 255, 0.1);
  }
  .hero-in {
    padding-top: 60px;
  }
}

/* ---------- service grid ---------- */
.svc {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: 20px;
}
.svc-col {
  display: grid;
  gap: 20px;
  grid-template-rows: repeat(3, 1fr);
}
.svc-feature {
  position: relative;
  padding: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.svc-feature img {
  width: 100%;
  height: 290px;
  object-fit: cover;
  display: block;
}
.svc-feature .fbody {
  padding: 28px 30px 30px;
}
.svc-feature h3 {
  font-size: 25px;
  margin-bottom: 10px;
}
.svc-feature p {
  font-size: 15.5px;
}
.tag {
  position: absolute;
  top: 18px;
  left: 18px;
  background: var(--brass-fill);
  color: #fff;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 6px 11px;
  z-index: 2;
}
.grid-4 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}
.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.grid-1 {
  display: grid;
  grid-template-columns: minmax(0, 640px);
  gap: 20px;
}
.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
@media (max-width: 980px) {
  .grid-4 {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 900px) {
  .svc {
    grid-template-columns: 1fr;
  }
  .svc-col {
    grid-template-rows: none;
  }
  .grid-3 {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 620px) {
  .grid-4,
  .grid-2 {
    grid-template-columns: 1fr;
  }
}

/* ---------- steps ---------- */
.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.step {
  padding: 30px 26px 8px 0;
  border-right: 1px solid rgba(255, 255, 255, 0.14);
  position: relative;
}
.step:last-child {
  border-right: 0;
}
.step::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 34px;
  height: 3px;
  background: var(--brass);
}
.step .n {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 13px;
  color: var(--brass-lt);
  letter-spacing: 0.1em;
}
.step h3 {
  font-size: 18px;
  font-weight: 700;
  margin: 12px 0 8px;
  color: #fff;
}
.step p {
  color: var(--on-dark-dim);
  font-size: 14px;
  margin: 0;
}
@media (max-width: 860px) {
  .steps {
    grid-template-columns: 1fr 1fr;
  }
  .step {
    border-right: 0;
    padding-right: 20px;
  }
}
@media (max-width: 520px) {
  .steps {
    grid-template-columns: 1fr;
  }
}

/* ---------- prose ---------- */
.prose {
  color: var(--ink);
  font-size: 17px;
  line-height: 1.72;
}
/* Reset with the SAME specificity as the sibling rule below, so the sibling
   rule wins for everything after the first child. `.prose p { margin: 0 }`
   was (0,1,1) and beat `.prose > * + *` at (0,1,0) whatever the order, which
   silently removed the gap between every pair of paragraphs site-wide —
   headings still had theirs, so it read as "long blocks of text" rather than
   an obvious bug. */
.prose > * {
  margin: 0;
}
.prose > * + * {
  margin-top: 1.1em;
}
.prose h2 {
  font-size: clamp(24px, 2.8vw, 32px);
  font-weight: 800;
  margin-top: 1.9em;
}
.prose h3 {
  font-size: 20px;
  font-weight: 700;
  margin-top: 1.6em;
}
.prose ul,
.prose ol {
  margin: 0;
  padding-left: 24px;
}
.prose li + li {
  margin-top: 0.5em;
}
.prose a {
  color: var(--brass);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.prose strong {
  font-weight: 600;
}
.prose img {
  display: block;
  border: 1px solid var(--line);
}
.prose blockquote {
  margin: 0;
  padding: 4px 0 4px 24px;
  border-left: 3px solid var(--brass);
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.02em;
}

.page-head {
  background: var(--ink);
  color: #fff;
  padding: 56px 0 60px;
}
.page-head h1 {
  font-size: clamp(32px, 4.4vw, 52px);
  font-weight: 800;
  color: #fff;
  margin-top: 14px;
}
.page-head .intro {
  color: #c6cbd3;
  font-size: 18px;
  margin: 18px 0 0;
  max-width: 620px;
}
.page-head .intro p {
  margin: 0 0 0.7em;
}
.page-head .intro p:last-child {
  margin-bottom: 0;
}
.page-head .intro a {
  color: var(--brass-lt);
}
.crumb {
  font-size: 13px;
  color: var(--on-dark-dim);
}
.crumb a {
  color: var(--on-dark-dim);
  text-decoration: none;
}
.crumb a:hover {
  color: var(--brass-lt);
}
.head-actions {
  margin-top: 30px;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
}

/* ---------- trust strip ---------- */
.trust {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.trust > div {
  padding: 26px 24px 26px 0;
  border-right: 1px solid rgba(255, 255, 255, 0.12);
}
.trust > div:last-child {
  border-right: 0;
}
.trust dt {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brass-lt);
  margin-bottom: 6px;
}
.trust dd {
  margin: 0;
  color: #fff;
  font-weight: 600;
  font-size: 15px;
}
.trust dd span {
  display: block;
  font-weight: 400;
  font-size: 13.5px;
  color: var(--on-dark-dim);
  margin-top: 3px;
}
.trust a {
  color: var(--brass-lt);
}
@media (max-width: 880px) {
  .trust {
    grid-template-columns: 1fr 1fr;
  }
  .trust > div {
    border-right: 0;
    padding: 20px 16px 20px 0;
  }
}
@media (max-width: 520px) {
  .trust {
    grid-template-columns: 1fr;
  }
}

/* ---------- pricing ---------- */
.price-card {
  display: flex;
  flex-direction: column;
}
.price-card .amount {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 800;
  color: var(--ink);
  margin: 6px 0 2px;
  letter-spacing: -0.03em;
}
.price-card .unit {
  font-size: 13px;
  color: var(--steel);
}
.price-card .desc {
  margin-top: 12px;
}
.fineprint {
  margin-top: 26px;
  font-size: 14px;
  color: var(--steel);
}

/* ---------- FAQ ---------- */
.faq-item {
  border-bottom: 1px solid var(--line);
}
.faq-q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  text-align: left;
  background: none;
  border: 0;
  padding: 20px 0;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  cursor: pointer;
}
.faq-q:hover {
  color: var(--brass);
}
.faq-q svg {
  flex: none;
  transition: transform 0.15s;
  color: var(--brass);
}
.faq-a {
  padding: 0 0 22px;
  color: var(--steel);
  font-size: 16px;
  line-height: 1.7;
  max-width: 72ch;
}
.faq-a p {
  margin: 0 0 0.8em;
}
.faq-a p:last-child {
  margin-bottom: 0;
}

/* ---------- forms ---------- */
.field {
  display: block;
  margin-bottom: 18px;
}
.field > label,
.field-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink);
  margin-bottom: 6px;
}
.input {
  width: 100%;
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
}
.input:focus {
  outline: none;
  border-color: var(--brass);
  box-shadow: 0 0 0 3px rgba(184, 117, 43, 0.18);
}
select.input {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235f6772' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 18px;
  padding-right: 40px;
}
.errorlist {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  color: var(--danger);
  font-size: 13.5px;
}
.form-actions {
  display: flex;
  gap: 12px;
  margin-top: 8px;
}
.steps-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--steel);
  margin-bottom: 22px;
}
.steps-bar .on {
  color: var(--brass);
}
.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: var(--radius);
  background: var(--surface);
  cursor: pointer;
  font-weight: 600;
  font-size: 14px;
}
.choice:has(:checked) {
  border-color: var(--brass);
  box-shadow: inset 0 0 0 1px var(--brass);
}
.choice input {
  display: block;
  margin: 0 auto 8px;
  accent-color: var(--brass);
}

/* ---------- misc ---------- */
.band {
  background: var(--brass-fill);
  color: #fff;
}
.band .wrap {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 34px;
  padding-top: 50px;
  padding-bottom: 50px;
  flex-wrap: wrap;
}
.band h2 {
  font-size: clamp(24px, 3vw, 34px);
  font-weight: 800;
  max-width: 560px;
  color: #fff;
}
.band p {
  margin: 10px 0 0;
  color: rgba(255, 255, 255, 0.88);
  font-size: 16px;
}
.band .btn {
  background: #fff;
  color: var(--brass);
  border-color: #fff;
}
.band .btn:hover {
  background: #f2e6d6;
  border-color: #f2e6d6;
  color: var(--brass);
}

.post-list {
  display: grid;
  gap: 2px;
  background: var(--line);
  border: 1px solid var(--line);
}
.post-item {
  background: var(--surface);
  padding: 26px 28px;
  text-decoration: none;
  color: inherit;
  display: block;
  transition: background 0.15s;
}
.post-item:hover {
  background: #fffdf9;
  color: inherit;
}
.post-item h2 {
  font-size: 22px;
  font-weight: 700;
  margin-bottom: 6px;
}
.post-meta {
  font-size: 12.5px;
  color: var(--steel);
  letter-spacing: 0.04em;
}
.post-item p {
  color: var(--steel);
  margin: 10px 0 0;
  font-size: 15px;
}

.notice {
  padding: 14px 18px;
  border-left: 3px solid var(--brass);
  background: rgba(184, 117, 43, 0.07);
  font-size: 15px;
}
.ok-msg {
  color: var(--good);
  font-weight: 600;
}

.cookie {
  position: fixed;
  bottom: 18px;
  left: 18px;
  right: 18px;
  max-width: 440px;
  background: var(--ink);
  color: var(--on-dark);
  border: 1px solid rgba(255, 255, 255, 0.14);
  padding: 20px 22px;
  z-index: 90;
  font-size: 14px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
}
.cookie p {
  margin: 0 0 14px;
}
.cookie a {
  color: var(--brass-lt);
}
.cookie .row {
  display: flex;
  gap: 10px;
}
.cookie .btn {
  padding: 10px 18px;
  font-size: 14px;
}
.form-success {
  color: #1f6f4a;
  font-weight: 600;
  background: #eaf6ef;
  border: 1px solid #bfe0cd;
  border-radius: var(--radius);
  padding: 14px 16px;
  margin: 0;
}
.hidden {
  display: none;
}

/* ---------- footer ---------- */
.site-footer {
  background: var(--ink);
  color: var(--on-dark-dim);
  padding: 62px 0 28px;
  font-size: 14px;
  margin-top: auto;
}
.fgrid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 38px;
}
.site-footer h4 {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #fff;
  margin: 0 0 14px;
}
.site-footer ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 9px;
}
.site-footer a {
  color: var(--on-dark-dim);
  text-decoration: none;
}
.site-footer a:hover {
  color: var(--brass-lt);
}
.fbot {
  margin-top: 44px;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 12.5px;
}
@media (max-width: 820px) {
  .fgrid {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 520px) {
  .fgrid {
    grid-template-columns: 1fr;
  }
}

/* ---------- utilities (sparingly) ---------- */
.center {
  text-align: center;
}
.muted {
  color: var(--steel);
}
.stack > * + * {
  margin-top: 18px;
}
.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;
}

/* ---------- layout helpers (used by templates instead of inline styles) ---------- */
.measure {
  max-width: 820px;
}
.measure-text {
  max-width: 72ch;
}
.mt-sm {
  margin-top: 20px;
}
.mt-md {
  margin-top: 34px;
}
.mt-lg {
  margin-top: 70px;
}
.mt-xl {
  margin-top: 80px;
}
.mb-md {
  margin-bottom: 28px;
}
.h-section {
  font-size: clamp(26px, 3.2vw, 38px);
  font-weight: 800;
  max-width: 680px;
}
.h-block {
  font-size: clamp(26px, 3.2vw, 36px);
  font-weight: 800;
  margin: 12px 0 26px;
}
.h-sub {
  font-size: 24px;
  font-weight: 800;
  margin-bottom: 10px;
}
.btn-grow {
  flex: 1;
  justify-content: center;
}
.btn-wa {
  background: #25d366;
  border-color: #25d366;
  margin-top: 10px;
}
.btn-stack {
  margin-top: 10px;
}
.row {
  display: flex;
  gap: 10px;
}
.img-full {
  display: block;
  width: 100%;
  border: 1px solid var(--line);
}
.img-portrait {
  display: block;
  max-width: 420px;
  border: 1px solid var(--line);
}
.map {
  position: relative;
  z-index: 0;
  height: 340px;
  width: 100%;
  border: 1px solid var(--line);
}
.wrap-form {
  max-width: 720px;
  margin: 0 auto;
  padding: 0 28px;
}
.post-body {
  padding-bottom: 70px;
}
.brand-footer {
  margin-bottom: 14px;
}
.footer-blurb {
  margin: 0;
  max-width: 290px;
}
.meta-line {
  margin-top: 18px;
}
.lede-gap {
  margin: 0 0 26px;
}
.date-line {
  margin: 0 0 34px;
}
.warn-msg {
  color: var(--warn);
  font-weight: 600;
}

/* ---------- StreamField rhythm ----------
   Wagtail wraps every block in .block-<name>, so spacing lives here rather
   than as per-template classes. An earlier pass converted inline styles to
   classes and silently dropped several margin-top values, which is why
   images and grids ended up flush against whatever preceded them. */
.streamfield {
  padding: 56px 0 78px;
}
.streamfield-flush {
  padding-top: 0;
}
.block-hero {
  margin-top: 0;
}
.block-heading {
  margin-top: 58px;
}
.block-paragraph {
  margin-top: 20px;
}
.block-image,
.block-portrait_image {
  margin-top: 34px;
}
.block-service_grid {
  margin-top: 30px;
}
.block-quote {
  margin-top: 36px;
}
.block-faq {
  margin-top: 64px;
}
.block-coverage_map {
  margin-top: 36px;
}
.block-reviews_coming_soon {
  margin-top: 0;
}
.streamfield > *:first-child {
  margin-top: 0;
}

/* ---------- video ---------- */
.block-video {
  margin-top: 36px;
}
.video-figure {
  margin: 0;
  max-width: 820px;
}
.video-frame {
  position: relative;
  padding-top: 56.25%;
  background: var(--ink);
  border: 1px solid var(--line);
}
.video-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.video-figure figcaption {
  margin-top: 12px;
  font-size: 14.5px;
  color: var(--steel);
}
.video-figure figcaption strong {
  display: block;
  color: var(--ink);
  font-weight: 600;
  margin-bottom: 2px;
}

/* ---------- hero: split layout with a product carousel ---------- */
.hero-split {
  position: relative;
}
/* Depth for the large dark field behind the copy. Anchored well left of the
   visual on purpose: the slide images fade to exactly var(--ink) at their
   edges, so any gradient reaching under them would show as a seam. */
.hero-split::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    46% 62% at 16% 52%,
    rgba(184, 117, 43, 0.13) 0%,
    rgba(184, 117, 43, 0.04) 46%,
    rgba(184, 117, 43, 0) 70%
  );
  pointer-events: none;
}
.hero-split .hero-in {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  grid-template-areas: "copy visual" "spec spec";
  align-items: center;
  column-gap: 44px;
  padding-top: 58px;
}
.hero-split .hero-copy {
  grid-area: copy;
}
.hero-split .spec {
  grid-area: spec;
  margin-top: 50px;
}
.hero-visual {
  grid-area: visual;
  position: relative;
  justify-self: end;
  width: 100%;
  max-width: 470px;
}
.hslides {
  display: grid;
}
.hslide {
  grid-area: 1 / 1;
  position: relative;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.6s ease,
    visibility 0.6s;
}
.hslide.on {
  opacity: 1;
  visibility: visible;
}
.hslide img {
  display: block;
  width: 100%;
  height: auto;
}
/* Overlaid, not stacked underneath: captions vary in length, so in normal
   flow each slide changed the block's height and visibly shunted the
   carousel up and down. The slide art already fades to var(--ink) at its
   bottom edge, so the text sits on the image's own dark ground. */
.hslide figcaption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 46px 22px 16px;
  font-size: 13.5px;
  line-height: 1.5;
  color: #b4bbc4;
  background: linear-gradient(
    to bottom,
    rgba(14, 17, 22, 0) 0%,
    rgba(14, 17, 22, 0.86) 55%,
    rgba(14, 17, 22, 0.96) 100%
  );
}
.hdots {
  display: flex;
  gap: 8px;
  margin-top: 16px;
  /* Matches the caption's own horizontal padding so the dots and the caption
     text share one left edge. Flush against the image edge instead, they sat
     22px left of the caption above them — a visible step between two
     adjacent elements. Left, not centred: the whole layout is left-aligned,
     and a centred control under a left-aligned caption reads as detached. */
  padding-left: 22px;
}
.hdots button {
  width: 26px;
  height: 3px;
  padding: 0;
  border: 0;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.22);
  cursor: pointer;
  transition: background 0.3s ease;
}
.hdots button.on {
  background: var(--brass-lt);
}
.hdots button:focus-visible {
  outline: 2px solid var(--brass-lt);
  outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
  .hslide {
    transition: none;
  }
}

/* ---------- rotating coverage area ---------- */
.rotator {
  display: inline-grid;
  vertical-align: bottom;
  overflow: hidden;
  height: 1.3em;
}
.rotator > span {
  grid-area: 1 / 1;
  line-height: 1.3;
  white-space: nowrap;
  color: var(--brass-lt);
  opacity: 0;
  transform: translateY(0.7em);
  animation: rotate-area 15s infinite;
}
.rotator > span:nth-child(2) {
  animation-delay: 2.5s;
}
.rotator > span:nth-child(3) {
  animation-delay: 5s;
}
.rotator > span:nth-child(4) {
  animation-delay: 7.5s;
}
.rotator > span:nth-child(5) {
  animation-delay: 10s;
}
.rotator > span:nth-child(6) {
  animation-delay: 12.5s;
}
@keyframes rotate-area {
  0% {
    opacity: 0;
    transform: translateY(0.7em);
  }
  3%,
  15% {
    opacity: 1;
    transform: translateY(0);
  }
  18%,
  100% {
    opacity: 0;
    transform: translateY(-0.7em);
  }
}
/* Reduced motion: no cycling — show the primary area, statically. */
@media (prefers-reduced-motion: reduce) {
  .rotator {
    height: auto;
  }
  .rotator > span {
    animation: none;
    opacity: 0;
    transform: none;
  }
  .rotator > span:first-child {
    opacity: 1;
  }
}

/* Balanced line lengths only above the stacked breakpoint. On narrow
   screens balancing makes the browser break inside "software-first",
   leaving "software-" hanging; greedy wrapping there gives three clean
   lines instead. */
@media (min-width: 901px) {
  .hero h1 {
    text-wrap: balance;
  }
}

@media (max-width: 900px) {
  .hero-split .hero-in {
    grid-template-columns: 1fr;
    grid-template-areas: "copy" "visual" "spec";
    row-gap: 0;
    padding-top: 34px;
  }
  .hero-split .hero-copy {
    max-width: none;
  }
  /* Left-aligned, not centred. Everything else in this design sits on the
     same left edge, so a centred visual under left-aligned copy reads as a
     mistake rather than a choice. */
  .hero-visual {
    justify-self: start;
    max-width: 340px;
    margin-top: 26px;
  }
  .hero .sub {
    margin-top: 16px;
    max-width: none;
  }
  .hero-actions {
    margin-top: 24px;
  }
  .hero-split .spec {
    margin-top: 26px;
  }
}

@media (max-width: 560px) {
  .hero-split .hero-in {
    padding-top: 28px;
  }
  /* Side by side they don't fit, and left-aligned they stack to two
     different widths, which reads as an accident. Full width is the
     deliberate-looking version and gives a bigger tap target. */
  /* With the gutters restored the copy column is 56px narrower, which
     pushed "smart lock installer" onto its own fourth line. 35px fits it
     back onto three. */
  .hero h1 {
    font-size: 35px;
  }
  .hero-actions {
    display: grid;
    gap: 10px;
  }
  .hero-actions .btn {
    justify-content: center;
    width: 100%;
  }
  /* One compact line instead of a two-line block stranded on its own row
     under the buttons, where the brass rule read as a stray mark. */
  .price-tag {
    display: flex;
    align-items: baseline;
    gap: 7px;
    padding-left: 12px;
  }
  .price-tag span {
    display: inline;
  }
  .hero-visual {
    max-width: 100%;
    margin-top: 22px;
  }
  .hslide figcaption {
    padding: 34px 14px 13px;
    font-size: 12.5px;
  }
  .hdots {
    margin-top: 13px;
    padding-left: 14px;
  }
  .spec > div {
    padding: 13px 0;
  }
}

.fnote {
  margin: 34px 0 0;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.09);
  font-size: 12.5px;
  line-height: 1.6;
  color: #7d858f;
  max-width: 760px;
}

.legal-address {
  margin: 4px 0 18px;
  padding-left: 16px;
  border-left: 2px solid var(--brass);
  font-style: normal;
  line-height: 1.65;
}

.price-card .extra-lock {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--line);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--steel);
}
.price-card .extra-lock strong {
  color: var(--ink);
}

/* ---------- post-submission success panel ----------
   Replaces the single line of green text that used to be the entire
   confirmation, which left the visitor on a page with no way onward. */
.success-panel {
  border: 1px solid var(--line);
  border-left: 3px solid var(--brass);
  background: var(--surface);
  padding: 32px 34px 34px;
}
.success-panel:focus {
  outline: none;
}
.success-eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brass-fill);
  margin: 0 0 10px;
}
.success-panel h2 {
  font-family: var(--font-display);
  font-size: clamp(23px, 2.6vw, 30px);
  line-height: 1.15;
  margin: 0 0 12px;
}
.success-lead {
  margin: 0 0 22px;
  font-size: 17px;
  color: var(--ink);
}
.success-steps {
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
  border-top: 1px solid var(--line);
}
.success-steps li {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  font-size: 15.5px;
  color: var(--steel);
}
.success-steps span {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--brass-fill);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.success-note {
  font-size: 14.5px;
  color: var(--steel);
  margin: 0 0 24px;
}
.success-actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
