/* ===========================================================================
   Page-level components.
   Extends the approved homepage stylesheet (site.css) using the same design
   tokens. Loaded after site.css, so anything here can override the base.
   Mobile-first-ish: layouts are declared wide, then collapsed in media queries.
   =========================================================================== */

/* ---------- Reveal safety net ----------
   The homepage cascade only reveals .reveal-item elements that sit INSIDE a
   .hero-cascade wrapper. Inner-page heroes have reveal-items as grid siblings
   outside it, so without this rule they would stay at opacity 0 — visible to a
   screen reader and to search engines, but invisible to a human. */
.reveal-item.is-revealed { opacity: 1; transform: translateY(0); }

/* ---------- Section intro (eyebrow + heading + lede) ---------- */
.content-intro { max-width: 820px; margin: 0 auto 44px; text-align: center; }
.content-intro--left { margin-left: 0; text-align: left; }
.content-eyebrow {
  font-family: 'Inter', sans-serif; font-weight: 600; font-size: 13px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ember-500);
  margin: 0 0 12px;
}
.content-heading {
  font-family: 'Poppins', sans-serif; font-weight: 700;
  font-size: clamp(27px, 3.1vw, 38px); line-height: 1.12; letter-spacing: -.01em;
  color: #fff; margin: 0 0 16px;
}
.content-lede { font-size: 16px; line-height: 1.65; color: var(--mist-100); margin: 0; }
.content-intro--left .content-lede { max-width: 720px; }

/* ---------- Content blocks ---------- */
.content-block { margin: 0 0 56px; }
.content-block:last-child { margin-bottom: 0; }
.content-subheading {
  font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 23px;
  line-height: 1.25; color: #fff; margin: 0 0 18px;
}
.content-subheading--center { text-align: center; }
.content-note { font-size: 13.5px; color: var(--mist-100); opacity: .75; margin: 14px 0 0; }
.lede-inline { font-size: 17px; line-height: 1.65; color: var(--mist-100); margin: 0 0 8px; }

.prose p { font-size: 15.5px; line-height: 1.75; color: var(--mist-100); margin: 0 0 18px; }
.prose p:last-child { margin-bottom: 0; }
.prose a { color: var(--ember-300); }

/* ---------- Checklists ---------- */
.check-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.check-list li {
  display: flex; align-items: flex-start; gap: 11px;
  font-size: 15px; line-height: 1.6; color: var(--mist-100);
}
.check-list li svg { flex: 0 0 auto; margin-top: 3px; color: var(--ember-500); }

/* ---------- Feature cards ---------- */
.feature-grid { display: grid; gap: 20px; }
.feature-grid--2 { grid-template-columns: repeat(2, 1fr); }
.feature-grid--3 { grid-template-columns: repeat(3, 1fr); }
.feature-grid--4 { grid-template-columns: repeat(4, 1fr); }
.feature-card { padding: 26px 24px; transition: transform .25s ease, background-color .25s ease; }
.feature-card:hover { transform: translateY(-5px); background: rgba(255,255,255,.1); }
.feature-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 11px;
  background: rgba(239,100,46,.16); color: var(--ember-500); margin-bottom: 16px;
}
.feature-card-title {
  font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 16.5px;
  color: #fff; margin: 0 0 10px;
}
.feature-card-text { font-size: 14px; line-height: 1.65; color: var(--mist-100); opacity: .88; margin: 0; }
.feature-card-link {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 14px;
  font-size: 13.5px; font-weight: 500; color: var(--ember-300); text-decoration: none;
}
.feature-card-link:hover { color: #fff; }

/* ---------- Two column split ---------- */
/* Inner content-blocks lose their bottom margin when they are last in a
   column. The grid therefore needs the same outer rhythm as a content-block,
   otherwise the following heading touches the preceding paragraph/list. */
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: start; margin: 0 0 56px; }
.two-col:last-child { margin-bottom: 0; }
/* The original homepage also follows a grid with a separate detail heading.
   Space the transition without changing the grid or its horizontal margins. */
.project-grid + .project-detail { margin-top: 56px; }

/* ---------- Inner page hero ---------- */
.page-hero { padding: 44px 0 56px; position: relative; }
.page-hero--compact { padding-bottom: 32px; }
.page-hero-grid {
  display: grid; grid-template-columns: 1.15fr .85fr; gap: 56px; align-items: start;
}
.page-hero-grid--single { grid-template-columns: 1fr; }
.page-hero-copy h1 {
  font-family: 'Poppins', sans-serif; font-weight: 700;
  font-size: clamp(29px, 3.6vw, 44px); line-height: 1.14; letter-spacing: -.01em;
  color: #fff; margin: 0 0 20px;
}
.page-hero-copy .lede { font-size: 16.5px; line-height: 1.6; color: var(--mist-100); max-width: 620px; margin: 0 0 28px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
.page-hero-media { position: sticky; top: 120px; }

/* ---------- Breadcrumbs ---------- */
.breadcrumbs { margin: 0 0 26px; }
.breadcrumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; font-size: 12.5px; }
.breadcrumbs li { color: var(--mist-100); opacity: .7; }
.breadcrumbs li + li::before { content: '/'; margin-right: 6px; opacity: .5; }
.breadcrumbs a { color: var(--mist-100); text-decoration: none; }
.breadcrumbs a:hover { color: #fff; text-decoration: underline; }
.breadcrumbs [aria-current] { opacity: 1; color: #fff; }

/* ---------- Video ---------- */
.video-block { margin: 0; }
.video-frame {
  position: relative; display: block; width: 100%;
  aspect-ratio: var(--video-ratio, 16/9);
  border: 1px solid rgba(255,255,255,.16); border-radius: 14px;
  background:
    radial-gradient(150px 150px at 50% 50%, rgba(28,13,64,.1), transparent 70%),
    linear-gradient(135deg, #473861, #1c0d40);
  cursor: pointer; overflow: hidden; padding: 0;
  transition: transform .2s ease, box-shadow .2s ease;
}
.video-frame:not(:disabled):hover { transform: translateY(-2px); box-shadow: 0 18px 40px rgba(10,4,30,.4); }
.video-frame:disabled { cursor: default; }
.video-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.video-play {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 66px; height: 66px; border-radius: 50%; background: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 12px 30px rgba(0,0,0,.35);
}
.video-frame:hover .video-play { transform: translate(-50%, -50%) scale(1.06); }
.video-pending {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 20px; border-radius: 999px;
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.24);
  color: #fff; font-size: 13.5px; font-weight: 500; white-space: nowrap;
}
.video-caption { font-size: 13.5px; line-height: 1.6; color: var(--mist-100); opacity: .85; margin: 14px 2px 0; }
.video-embed { width: 100%; border-radius: 14px; overflow: hidden; border: 1px solid rgba(255,255,255,.16); background: #000; }
.video-embed iframe, .video-embed video { width: 100%; height: 100%; border: 0; display: block; }

/* ---------- Video transcript: inline and collapsed ----------

   Mark's production decision (storyboards doc section 10.5): the transcript lives
   inline under the video as a collapsed block — not its own page, which would
   fragment a page that already carries buying intent, and not a link out to a
   platform transcript, which takes people off-site and mangles names and numbers.

   Native <details> does the job with no JavaScript: collapsed by default, keyboard
   accessible, and the text still present in the HTML so search engines read it. The
   marker is drawn with a CSS chevron rather than the platform default, and the whole
   block is styled to sit quietly under a video rather than compete with it. */

.video-transcript { margin: 14px 2px 0; }

.video-transcript > summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 13.5px; font-weight: 600;
  color: var(--mist-100);
  padding: 4px 2px;
}
.video-transcript > summary::-webkit-details-marker { display: none; }
.video-transcript > summary::before {
  content: '';
  width: 7px; height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform .18s ease;
  flex: none;
}
.video-transcript[open] > summary::before { transform: rotate(45deg); }
.video-transcript > summary:hover { color: #fff; }
.video-transcript > summary:focus-visible {
  outline: 2px solid var(--focus-ring, #a89bd6);
  outline-offset: 3px;
  border-radius: 4px;
}

.video-transcript-body {
  margin-top: 10px;
  padding: 16px 18px;
  border-radius: 12px;
  border: 1px solid rgba(255,255,255,.16);
  background: rgba(255,255,255,.05);
  font-size: 13.5px; line-height: 1.65;
  color: var(--mist-100);
}
.video-transcript-body p { margin: 0 0 12px; }
.video-transcript-body p:last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .video-transcript > summary::before { transition: none; }
}

/* ---------- Stat rows ---------- */
.stat-row { display: flex; flex-wrap: wrap; gap: 16px; }
.stat-row .stat-card { min-width: 0; flex: 1 1 190px; }

/* ---------- CTA band ---------- */
.cta-band {
  display: flex; align-items: center; justify-content: space-between;
  gap: 32px; flex-wrap: wrap; padding: 40px 44px;
}
.cta-band-title {
  font-family: 'Poppins', sans-serif; font-weight: 700; font-size: clamp(21px, 2.2vw, 27px);
  line-height: 1.2; color: #fff; margin: 0 0 10px; max-width: 620px;
}
.cta-band-text { font-size: 15px; line-height: 1.6; color: var(--mist-100); margin: 0; max-width: 620px; }
.cta-band-actions { display: flex; gap: 10px; flex-wrap: wrap; flex: 0 0 auto; }

/* ---------- Service / location two-column layout ---------- */
.service-layout { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 56px; align-items: start; }
.service-main { min-width: 0; }
.service-main--wide { max-width: 100%; }
.service-sidebar { display: grid; gap: 20px; position: sticky; top: 120px; }

/* .glass-panel carries `margin: 0 auto` so that full-width page panels centre
 * themselves inside a max-width. On a GRID ITEM an auto margin overrides
 * justify-self:stretch, so every card in this sidebar shrank to its own content
 * and sat centred instead of filling the column: measured 233px, 261px and 286px
 * inside a 330px column, so "Related services", "More Tech Tip Tuesdays" and
 * "Worth a second opinion?" were three different widths. Neutralise the auto
 * margin here and they all fill the column.
 *
 * `> .glass-panel` covers every card in the rail, including any added later, so
 * a new sidebar card cannot reintroduce the mismatch. */
.service-sidebar > .glass-panel { margin: 0; max-width: none; }

.sidebar-card, .sidebar-cta { padding: 26px 24px; }
.sidebar-title {
  font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 15px;
  color: #fff; margin: 0 0 16px; letter-spacing: .01em;
}
.sidebar-text { font-size: 13.5px; line-height: 1.6; color: var(--mist-100); opacity: .85; margin: 0 0 16px; }
.sidebar-links { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.sidebar-links a {
  display: block; padding: 9px 12px; margin: 0 -12px; border-radius: 8px;
  font-size: 13.5px; color: var(--mist-100); text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}
.sidebar-links a:hover { background: rgba(255,255,255,.08); color: #fff; }
.sidebar-links a[aria-current="page"] { background: rgba(239,100,46,.16); color: #fff; font-weight: 600; }
.sidebar-links--plain li {
  display: flex; flex-direction: column; gap: 2px; padding: 9px 0;
  border-bottom: 1px solid rgba(255,255,255,.08); font-size: 13.5px;
}
.sidebar-links--plain li:last-child { border-bottom: 0; }
.sidebar-links--plain strong { color: #fff; font-weight: 600; }
.sidebar-links--plain span { color: var(--mist-100); opacity: .8; font-size: 13px; }
.sidebar-btn { width: 100%; justify-content: center; margin-bottom: 10px; }
.sidebar-btn:last-child { margin-bottom: 0; }

.branch-address { font-style: normal; font-size: 14px; line-height: 1.7; color: var(--mist-100); margin: 0 0 18px; }
.branch-contact { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.branch-contact li { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--mist-100); }
.branch-contact li svg { color: var(--ember-500); flex: 0 0 auto; }
.branch-contact a { color: var(--mist-100); text-decoration: none; }
.branch-contact a:hover { color: #fff; text-decoration: underline; }
.branch-badge {
  display: inline-block; margin: 16px 0 0; padding: 5px 12px; border-radius: 999px;
  background: rgba(239,100,46,.16); border: 1px solid rgba(239,100,46,.4);
  color: var(--ember-300); font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em;
}

/* ---------- Related services ---------- */
.content-block--related { margin-top: 64px; }
.related-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 18px; }
.related-card, .service-card {
  display: flex; flex-direction: column; gap: 10px;
  padding: 24px 22px; text-decoration: none;
  transition: transform .22s ease, background-color .22s ease;
}
.related-card:hover, .service-card:hover { transform: translateY(-5px); background: rgba(255,255,255,.1); }
.related-icon, .service-card-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 11px;
  background: rgba(239,100,46,.16); color: var(--ember-500);
}
.related-title, .service-card-title {
  font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 16px;
  color: #fff; margin: 0; line-height: 1.3;
}
.related-text, .service-card-text { font-size: 13.5px; line-height: 1.6; color: var(--mist-100); opacity: .85; margin: 0; }
.related-more, .service-card-more {
  display: inline-flex; align-items: center; gap: 7px; margin-top: auto; padding-top: 12px;
  font-size: 13px; font-weight: 500; color: var(--ember-300);
}
.related-card:hover .related-more, .service-card:hover .service-card-more { color: #fff; }

/* ---------- Services index ---------- */
.services-group { padding-bottom: 72px; }
.services-group-block { margin: 0 0 44px; }
.group-title {
  font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 18px;
  color: #fff; margin: 0 0 20px; padding-bottom: 12px;
  border-bottom: 1px solid rgba(255,255,255,.12);
}
.services-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 18px; }
.services-card-grid--3 { grid-template-columns: repeat(3, 1fr); }

/* ---------- Locations ---------- */
.location-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 20px; }
.location-card { display: flex; flex-direction: column; gap: 8px; padding: 26px 24px; text-decoration: none; transition: transform .22s ease, background-color .22s ease; }
.location-card:hover { transform: translateY(-5px); background: rgba(255,255,255,.1); }
.location-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.location-card-town { font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 18px; color: #fff; margin: 0; }
.location-card-badge {
  padding: 4px 10px; border-radius: 999px; font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em;
  background: var(--ember-500); color: var(--ember-ink); white-space: nowrap;
}
.location-card-address { font-size: 13.5px; line-height: 1.55; color: var(--mist-100); opacity: .85; margin: 0; }
.location-card-note { font-size: 12.5px; color: var(--mist-100); opacity: .65; margin: 0; }
.location-card-more { display: inline-flex; align-items: center; gap: 7px; margin-top: auto; padding-top: 14px; font-size: 13px; font-weight: 500; color: var(--ember-300); }

.town-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.town-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: 999px; font-size: 13px;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14);
  color: var(--mist-100);
}
.town-chip svg { color: var(--ember-500); flex: 0 0 auto; }

/* Location results card. The wrapper carries the card styling so the tile can
   be a real <button> (map selection) while the contacts and the branch-page
   link underneath stay real <a> elements. */
.location-entry {
  display: flex; flex-direction: column; gap: 6px;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 12px;
  padding: 14px 16px;
  transition: background-color .2s ease, border-color .2s ease;
}
.location-entry:hover { background: rgba(255,255,255,.09); }
.location-entry.is-active { background: rgba(239,100,46,.14); border-color: rgba(239,100,46,.5); }
.location-tile {
  display: flex; flex-direction: column; gap: 4px; width: 100%;
  background: none; border: 0; padding: 0; margin: 0;
  text-align: left; font-family: inherit; color: inherit; cursor: pointer;
}
.location-tile:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; border-radius: 6px; }

.location-tile-page {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 600; color: var(--ember-300); text-decoration: none;
}
.location-tile-page:hover { color: #fff; text-decoration: underline; }

.location-locate-btn {
  margin-left: auto; padding: 5px 12px; border-radius: 999px; cursor: pointer;
  background: rgba(239,100,46,.18); border: 1px solid rgba(239,100,46,.45);
  color: var(--ember-300); font-size: 11.5px; font-weight: 600; white-space: nowrap;
}
.location-locate-btn:hover { background: rgba(239,100,46,.3); color: #fff; }
.location-tile-badge--hq { background: rgba(255,255,255,.16); color: #fff; }
.location-tile-more { display: inline-block; margin-top: 6px; font-size: 11.5px; font-weight: 600; color: var(--ember-300); }

/* ---------- Testimonial / industry switcher ---------- */
.switcher { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 48px; }
.switcher-list {
  list-style: none; margin: 0; padding: 0 32px 0 0; display: flex; flex-direction: column; gap: 2px;
  border-right: 1px solid rgba(255,255,255,.16);
}
.switcher-item {
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  border-radius: 8px; padding: 11px 14px; font-family: inherit;
  color: var(--mist-100); font-size: 14px; font-weight: 500;
  transition: background-color .15s ease, color .15s ease;
}
.switcher-item:hover { background: rgba(255,255,255,.08); color: #fff; }
.switcher-item.is-active { background: rgba(255,255,255,.14); color: #fff; font-weight: 600; }
.switcher-item-label { margin: 0; font-size: inherit; font-weight: inherit; font-family: inherit; color: inherit; line-height: inherit; }
.switcher-stage { min-height: 240px; }
.switcher-panel { display: none; grid-template-columns: minmax(0, 1.55fr) minmax(0, .85fr); gap: 36px; width: 100%; }
.switcher-panel.is-active { display: grid; }
.switcher-main { display: flex; flex-direction: column; gap: 18px; }
.switcher-quote {
  font-family: 'Poppins', sans-serif; font-size: 18px; line-height: 1.5; color: #fff; margin: 0;
}
.switcher-focus { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.switcher-focus li { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; line-height: 1.55; color: var(--mist-100); opacity: .9; }
.switcher-focus li svg { flex: 0 0 auto; margin-top: 3px; color: var(--ember-500); }
.switcher-person {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px;
  padding-left: 24px; border-left: 1px solid rgba(255,255,255,.16); min-width: 150px;
}
.switcher-person .testimonial-photo {
  display: block; width: 100px; height: 100px; flex-shrink: 0; border-radius: 50%;
  background: linear-gradient(135deg, rgba(255,255,255,.28), rgba(255,255,255,.08));
  margin-bottom: 6px;
}
.switcher-person .testimonial-name { color: #fff; }
.switcher-person .testimonial-role,
.switcher-person .testimonial-org { color: var(--mist-100); }

/* ---------- "What this protects" panel ----------
   Carries the commercial framing at the top of every service and branch page,
   above the technical detail. Deliberately warmer than the sections around it:
   it is the part written for the person signing the cheque. */
.business-case {
  padding: 34px 36px;
  margin: 0 0 56px;
  border-left: 3px solid var(--ember-500);
  background: rgba(255,255,255,.07);
}
.business-case-eyebrow {
  font-family: 'Inter', sans-serif; font-weight: 600; font-size: 12px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--ember-500);
  margin: 0 0 10px;
}
.business-case-heading {
  font-family: 'Poppins', sans-serif; font-weight: 700;
  font-size: clamp(21px, 2.1vw, 26px); line-height: 1.2; letter-spacing: -.01em;
  color: #fff; margin: 0 0 14px;
}
.business-case-lede {
  font-size: 16px; line-height: 1.7; color: var(--mist-100);
  margin: 0 0 28px; max-width: 74ch;
}
.business-case-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.business-case-item { min-width: 0; }
.business-case-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 10px;
  background: rgba(239,100,46,.16); color: var(--ember-500); margin-bottom: 12px;
}
.business-case-title {
  font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 15px;
  color: #fff; margin: 0 0 8px;
}
.business-case-text { font-size: 13.5px; line-height: 1.65; color: var(--mist-100); opacity: .9; margin: 0; }

/* The grid adapts to how many items the panel has, so a four-item panel (the
   homepage) does not leave an orphaned fourth card on its own row. */
.business-case-grid[data-count="4"] { grid-template-columns: repeat(4, 1fr); }
.business-case-grid[data-count="2"] { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 1280px) {
  .business-case-grid[data-count="4"] { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 900px) {
  .business-case { padding: 26px 24px; }
  .business-case-grid,
  .business-case-grid[data-count="4"],
  .business-case-grid[data-count="2"] { grid-template-columns: 1fr; gap: 22px; }
}

/* Homepage placement: the section supplies the vertical rhythm, so the panel
   itself should not add any. */
.business-case-section { padding: 0 !important; padding-bottom: 96px !important; }
.business-case-section .business-case { margin-bottom: 0; }
.services-case-section { padding: 0 !important; padding-bottom: 72px !important; }
.services-case-section .business-case { margin-bottom: 0; }

/* The commercial stakes of the Sandy Court case, set apart from the technical
   description above it. */
.project-stakes {
  font-size: 15px; line-height: 1.7; color: var(--mist-100);
  border-left: 3px solid var(--ember-500); padding-left: 16px;
  margin: 0 0 28px; max-width: 62ch;
}

/* Closing pull-quote in the project detail column.
   In the original design this line was a checkmark list item, styled by
   .project-features li{color:var(--mist-100)}. Rebuilt as a standalone
   paragraph it had no rule of its own and inherited body's --ink-900, which is
   near-black against a dark section and therefore invisible (measured 1.18:1).
   Treated here as a deliberate pull-quote instead of reverting to a list item.
   Any new element lifted out of a styled container needs its own rule. */
.project-quote {
  position: relative;
  margin: 26px 0 0;
  padding: 20px 24px 20px 54px;
  background: rgba(255,255,255,.07);
  border-radius: 12px;
  font-family: 'Poppins', sans-serif;
  font-size: clamp(15px, 1.4vw, 16.5px);
  line-height: 1.62;
  font-style: italic;
  color: var(--mist-100);
}
.project-quote::before {
  content: "\201C";
  position: absolute; left: 20px; top: 8px;
  font-family: 'Poppins', serif;
  font-size: 46px; line-height: 1;
  color: var(--ember-500);
  opacity: .9;
}

/* ---------- Interim honesty panels ----------------------------------------

   Until real capture exists (see review/BLOCKERS.md), the lead form and the
   blog signup both report that nothing was sent and hand over the phone number
   and a direct email.

   The phone is deliberately PRIMARY. A mailto: does nothing for anyone on
   webmail-only or a machine with no mail client configured: they click, nothing
   happens, and we have lost them after they already typed their details. Phone
   first, email as the secondary route. */
.form-success-call {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  margin: 18px 0 6px; padding: 14px 24px; border-radius: 10px;
  background: linear-gradient(180deg, var(--ember-300, #ff9a5a), var(--ember-500, #ef642e));
  color: var(--ember-ink, #261205);
  font-weight: 700; font-size: 15.5px; text-decoration: none;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 6px 16px rgba(20,8,0,.28);
  transition: filter .15s ease, transform .15s ease;
}
.form-success-call:hover { filter: brightness(1.05); transform: translateY(-1px); }
.form-success-alt { margin-top: 4px; }

/* The generic link colour is deliberately :not() the call button. Without it,
   `.form-success a` (0,1,1) outranks `.form-success-call` (0,1,0) and paints the
   button label ember-300 — light orange on an orange gradient, which measured as
   effectively invisible. Any new link style in this panel must not swallow the
   primary button. */
.form-success a:not(.form-success-call),
.blog-signup-success a {
  color: var(--ember-300, #ff9a5a);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.form-success a:not(.form-success-call):hover,
.blog-signup-success a:hover { color: var(--ember-500, #ef642e); }
.form-success .form-success-mail { font-weight: 600; }
.form-success-aside {
  font-size: 12.5px; opacity: .75; margin-top: 10px;
}

/* ---------- Footer: Tech Tip Tuesdays ---------------------------------------

   Restored from the approved design, but as an explicit mailto rather than the
   signup box it originally had, because there is no capture backend yet. Starts
   from .footer-newsletter-btn (which is a square icon button) and overrides it
   into an auto-width pill with a label. */
.footer-newsletter-subscribe {
  width: auto; height: 44px; padding: 0 16px; gap: 8px;
  font-size: 13.5px; font-weight: 600; text-decoration: none;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.2);
  color: #fff;
  box-shadow: none;
}
.footer-newsletter-subscribe:hover {
  background: rgba(255,255,255,.14);
  border-color: var(--ember-500);
  filter: none; transform: none;
}
/* The newsletter column is the fifth, so the footer grid gains a track.
   Scoped to min-width:1001px deliberately. An unscoped rule here would load
   after site.css and defeat the footer's own responsive rules at max-width:1000
   (2 columns) and max-width:640 (1 column), because a media query adds no
   specificity — the later rule just wins. */
@media (min-width: 1001px) {
  .footer-top { grid-template-columns: 1.35fr .75fr .75fr 1fr 1.15fr; }
}

/* ---------- Regulated-sector pages ---------------------------------------- */

/* Deliberately cooler than .business-case: the business case argues the
   commercial stake, this panel sets out the compliance ground. Different accent
   so a reader does not read one as the other. */
.regulatory-panel {
  margin: 0 0 44px;
  padding: 32px 34px;
  border-left: 3px solid var(--support, #6f8dd8);
  background: rgba(255,255,255,.055);
}
.regulatory-eyebrow {
  font-family: 'Poppins', sans-serif; font-size: 11.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--support, #9fb4e6); margin: 0 0 10px;
}
.regulatory-heading {
  font-family: 'Poppins', sans-serif; font-weight: 600;
  font-size: clamp(21px, 2.1vw, 26px); line-height: 1.22;
  color: var(--mist-50, #fff); margin: 0 0 14px; max-width: 30ch;
}
.regulatory-lede {
  font-size: 15px; line-height: 1.72; color: var(--mist-100);
  opacity: .92; margin: 0 0 26px; max-width: 66ch;
}
.regulatory-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px 34px; }
.regulatory-grid[data-count="3"] { grid-template-columns: repeat(3, 1fr); }
.regulatory-item { border-top: 1px solid rgba(255,255,255,.13); padding-top: 14px; }
.regulatory-title {
  font-family: 'Poppins', sans-serif; font-size: 14.5px; font-weight: 600;
  color: var(--mist-50, #fff); margin: 0 0 7px; line-height: 1.35;
}
.regulatory-text { font-size: 13.5px; line-height: 1.65; color: var(--mist-100); opacity: .9; margin: 0; }

/* Baseline disclaimer, rendered by the component so it cannot be left out of a
   future vertical page. Quieter than the body text but still AA. */
.regulatory-note {
  margin: 22px 0 0; padding-top: 14px;
  border-top: 1px solid rgba(255,255,255,.13);
  font-size: 12.5px; line-height: 1.62;
  color: var(--mist-100); opacity: .78;
  max-width: 78ch;
}

@media (max-width: 900px) {
  .regulatory-panel { padding: 26px 24px; }
  .regulatory-grid,
  .regulatory-grid[data-count="3"] { grid-template-columns: 1fr; gap: 18px; }
}

/* Area-covered links on service-area and cluster pages. */
.area-links { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 34px; padding: 0; list-style: none; }
.area-links a {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px; border-radius: 999px;
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.14);
  color: var(--mist-50, #fff); font-size: 13.5px; text-decoration: none;
  transition: background .18s ease, border-color .18s ease;
}
.area-links a:hover { background: rgba(255,255,255,.14); border-color: var(--ember-500); }

.sidebar-more {
  display: inline-block; margin-top: 14px;
  font-size: 13.5px; color: var(--ember-400, #f08a5d);
  text-decoration: none; border-bottom: 1px solid rgba(240,138,93,.4);
}
.sidebar-more:hover { border-bottom-color: var(--ember-400, #f08a5d); }
.branch-badge { margin-top: 4px; }

/* Badge marking a place we cover but do not staff. Keeps the claim honest. */
.served-from {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12.5px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--mist-200, #cfcae0); opacity: .85;
  border: 1px solid rgba(255,255,255,.16); border-radius: 999px;
  padding: 6px 14px; margin: 0 0 22px;
}

/* ---------- Blog post ---------- */
.post-body .prose p { font-size: 16px; line-height: 1.8; }
.post-body .content-subheading { font-size: 24px; margin-top: 8px; }

.post-author {
  display: flex; align-items: flex-start; gap: 16px;
  padding: 22px 24px; margin: 8px 0 56px;
}
.post-author-photo {
  display: block; flex: 0 0 auto; width: 52px; height: 52px; border-radius: 50%;
  background: linear-gradient(135deg, rgba(255,255,255,.28), rgba(255,255,255,.08));
}
.post-author-name { font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 14.5px; color: #fff; margin: 0 0 6px; }
.post-author-note { font-size: 13px; line-height: 1.6; color: var(--mist-100); opacity: .8; margin: 0; }

/* "More from the blog" rail in the post sidebar */
.post-rail { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.post-rail a {
  display: block; padding: 10px 12px; margin: 0 -12px; border-radius: 8px;
  text-decoration: none; transition: background-color .15s ease;
}
.post-rail a:hover { background: rgba(255,255,255,.08); }
.post-rail-title { display: block; font-size: 13.5px; font-weight: 500; line-height: 1.45; color: var(--mist-100); }
.post-rail a:hover .post-rail-title { color: #fff; }
.post-rail-meta { display: block; margin-top: 3px; font-size: 11.5px; color: var(--mist-100); opacity: .6; }

@media (max-width: 640px) {
  .post-body .prose p { font-size: 15.5px; line-height: 1.75; }
  .post-author { flex-direction: column; gap: 12px; }
}

/* ---------- Contact page ---------- */
.contact-grid { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 56px; align-items: start; }
.contact-main { min-width: 0; }
.contact-methods { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 18px; margin: 8px 0 56px; }
.contact-method { display: block; padding: 28px 24px; text-decoration: none; transition: transform .22s ease, background-color .22s ease; }
.contact-method:hover { transform: translateY(-5px); background: rgba(255,255,255,.1); }
.contact-method-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: 12px;
  background: rgba(239,100,46,.16); color: var(--ember-500); margin-bottom: 16px;
}
.contact-method-title { font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 18px; color: #fff; margin: 0 0 8px; word-break: break-word; }
.contact-method-text { font-size: 13.5px; line-height: 1.6; color: var(--mist-100); opacity: .85; margin: 0; }

/* ---------- Industries ---------- */
.sector-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px; }
.sector-card { padding: 30px 28px; }
.sector-title { font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 19px; color: #fff; margin: 0 0 16px; }
.sector-quote {
  font-family: 'Poppins', sans-serif; font-size: 15.5px; line-height: 1.5; color: var(--mist-100);
  margin: 0 0 10px; padding-left: 16px; border-left: 3px solid var(--ember-500);
}
.sector-attrib { font-size: 12.5px; color: var(--mist-100); opacity: .65; margin: 0 0 18px; }
.sector-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.sector-list li { display: flex; align-items: flex-start; gap: 10px; font-size: 13.5px; line-height: 1.55; color: var(--mist-100); opacity: .9; }
.sector-list li svg { flex: 0 0 auto; margin-top: 3px; color: var(--ember-500); }

/* ---------- Blog index ---------- */
.post-list { margin-top: 56px; }
.post-row {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 24px 26px; margin-bottom: 14px; text-decoration: none;
  transition: transform .2s ease, background-color .2s ease;
}
.post-row:hover { transform: translateX(3px); background: rgba(255,255,255,.1); }
.post-row-body { min-width: 0; }
.post-row-tag { font-size: 11.5px; font-weight: 600; color: var(--ember-300); letter-spacing: .04em; text-transform: uppercase; }
.post-row-title { font-family: 'Poppins', sans-serif; font-weight: 600; font-size: 17px; line-height: 1.35; color: #fff; margin: 6px 0 8px; }
.post-row-excerpt { font-size: 13.5px; line-height: 1.6; color: var(--mist-100); opacity: .85; margin: 0 0 8px; }
.post-row-meta { font-size: 12px; color: var(--mist-100); opacity: .6; }
.post-row-arrow { flex: 0 0 auto; color: var(--ember-500); }

/* ---------- Legal ---------- */
.legal-updated { font-size: 13px; color: var(--mist-100); opacity: .7; margin: 0 0 36px; }
.legal-section .prose p { max-width: 780px; }

/* ---------- Mega menu: fit and colour ----------
 * Two defects reported in the desktop mega menus, fixed here because site.css
 * is generated and must not be hand-edited.
 *
 * COLOUR. The panels are WHITE cards (.mega-panel background:#ffffff). The nav's
 * own rule, .nav-links a { color: var(--mist-100) }, is (0,1,1) and outranks the
 * panel link rules at (0,1,0). So .mega-feature-link and .testimonial-link
 * inherited a pale lilac meant for the dark nav and rendered at 1.26:1 on white,
 * effectively invisible. The selectors below are (0,2,0) so they win, and the
 * :hover forms are (0,3,0) so they also beat .nav-links a:hover { color:#fff },
 * which was turning hovered panel links white on white.
 *
 * FIT. component_mega_panel() emits the list columns PLUS a Browse column, but
 * .mega-inner is a three-column grid. The fourth column therefore wrapped onto a
 * second row and pushed the panel past its max-height: 107px over on IT Services,
 * 25px on Communications, so the last rows sat behind a scrollbar. Four columns
 * keeps everything on one row.
 */
.mega-col--featured { border-left: 1px solid var(--field-border); padding-left: 24px; }
.mega-feature-link {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 14.5px; font-weight: 600;
  text-decoration: none; padding: 10px 0;
}
.mega-feature-link:hover { text-decoration: underline; }
.mega-panel-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 22px;
  margin-top: 28px; padding-top: 20px;
  border-top: 1px solid var(--field-border);
}

.mega-panel .mega-feature-link { color: var(--ember-700); }
.mega-panel .mega-feature-link:hover { color: var(--ink-900); }
.mega-panel .testimonial-link { color: var(--ember-ink); }
.mega-panel .testimonial-link:hover { color: var(--ember-ink); }

/* Same leak, second symptom. .nav-links a also sets white-space:nowrap, which is
   right for the nav bar but wrong inside the panels: every .blog-card-title
   inherited it, could not wrap, and so its min-content was the whole line. That
   is what forced the Tech Tip Tuesdays row 383px past the panel edge. Letting
   panel links wrap is what allows the columns to take their share. Equal
   specificity to .nav-links a, and pages.css loads second, so this wins. */
.mega-panel a { white-space: normal; }

/* Four columns: the list columns share the width, the Browse column takes only
   what its single link needs, and a tighter gap recovers the extra space. */
.mega-inner--featured {
  grid-template-columns: 1fr 1fr 1.2fr minmax(0, .72fr);
  gap: 32px;
}

/* minmax(0, ...) rather than a bare fr: a bare fr is minmax(auto, ...), so these
   columns refused to shrink below their content and the row spilled 383px past
   the panel edge. Letting them take their share makes the text reflow instead. */
.mega-inner--blog {
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 0.9fr);
}

/* ---------- Nav CTA pressure ----------
   The approved design carried five nav items. We added a sixth (Locations, so
   the branch index is reachable from the nav), which needs more horizontal
   room, and two things follow:

   1. The two secondary CTAs have to step aside a little earlier than before.
   2. site.css hides them with an unscoped `.nav-cta--support` rule, which also
      removed them from the mobile menu and the hero's mobile CTA row. Scope
      the hiding to the desktop group, and restore them everywhere else — they
      are the only route to the "report an incident" flow, so they have to stay
      reachable on a phone. */
@media (max-width: 1400px) {
  .nav-cta-group--desktop .nav-cta--support,
  .nav-cta-group--desktop .nav-cta--cyber { display: none; }
}
@media (max-width: 1320px) {
  .mobile-menu-ctas .nav-cta--support,
  .mobile-menu-ctas .nav-cta--cyber,
  .nav-cta-group--mobile .nav-cta--support,
  .nav-cta-group--mobile .nav-cta--cyber { display: inline-flex; }
}

/* ===========================================================================
   Responsive
   =========================================================================== */

@media (max-width: 1180px) {
  .feature-grid--4 { grid-template-columns: repeat(2, 1fr); }
  .services-card-grid--3 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 1024px) {
  .page-hero { padding: 32px 0 44px; }
  .page-hero-grid { grid-template-columns: 1fr; gap: 36px; }
  .page-hero-media { position: static; max-width: 620px; }
  .service-layout, .contact-grid { grid-template-columns: 1fr; gap: 40px; }
  .service-sidebar { position: static; }
  .switcher { grid-template-columns: 1fr; gap: 28px; }
  .switcher-list {
    flex-direction: row; flex-wrap: wrap; gap: 8px;
    padding: 0 0 20px; border-right: 0; border-bottom: 1px solid rgba(255,255,255,.16);
  }
  .switcher-item {
    width: auto; padding: 9px 16px; border-radius: 999px;
    background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.16);
  }
  .switcher-item.is-active { background: var(--ember-500); border-color: var(--ember-500); color: var(--ember-ink); }
  .switcher-stage { min-height: 0; }
  .sector-grid { grid-template-columns: 1fr; }
  .feature-grid--3 { grid-template-columns: repeat(2, 1fr); }
  .two-col { grid-template-columns: 1fr; gap: 32px; }
  .cta-band { padding: 32px 28px; }
  /* Sidebar collapses into a disclosure on small screens */
  .service-sidebar .sidebar-card:first-child .sidebar-links { display: none; }
  .service-sidebar.is-open .sidebar-card:first-child .sidebar-links { display: grid; }
  .service-sidebar .sidebar-title[role="button"] { cursor: pointer; display: flex; align-items: center; justify-content: space-between; }
  .service-sidebar .sidebar-title[role="button"]::after { content: '⌄'; font-size: 18px; line-height: 1; transition: transform .2s ease; }
  .service-sidebar.is-open .sidebar-title[role="button"]::after { transform: rotate(180deg); }
}

@media (max-width: 820px) {
  .services-card-grid, .related-grid, .location-card-grid, .contact-methods {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  }
}

@media (max-width: 640px) {
  .content-intro { margin-bottom: 32px; }
  .content-heading { font-size: 25px; }
  .content-lede, .page-hero-copy .lede { font-size: 15px; }
  .content-subheading { font-size: 19px; }
  .content-block, .two-col { margin-bottom: 40px; }
  .project-grid + .project-detail { margin-top: 40px; }

  .feature-grid--2, .feature-grid--3, .feature-grid--4 { grid-template-columns: 1fr; }
  .services-card-grid, .services-card-grid--3, .related-grid,
  .location-card-grid, .contact-methods, .sector-grid { grid-template-columns: 1fr; }

  .page-hero { padding: 20px 0 32px; }
  .page-hero-copy h1 { font-size: 26px; }
  .breadcrumbs { margin-bottom: 18px; }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .nav-cta { justify-content: center; }

  .stat-row { gap: 12px; }
  .stat-row .stat-card { flex: 1 1 100%; }

  .cta-band { flex-direction: column; align-items: stretch; padding: 26px 22px; gap: 20px; }
  .cta-band-actions { flex-direction: column; }
  .cta-band-actions .nav-cta { justify-content: center; }

  /* Video: 16:9, matching the player and the shoot.
     This was 4:3 with the note "taller ratio reads better on a phone", which is
     true as far as it goes — but pages.js builds the player's aspect-ratio from
     `data-ratio` in the markup, which is 16/9, so pressing play on a phone changed
     the shape of the frame under the visitor's thumb. Mark's decision: one ratio
     everywhere, no jolt, and one ratio for posters and captions.
     Verified: placeholder 262x147 -> player 262x147, shape change 0.000. */
  .video-frame { --video-ratio: 16/9; }
  .video-play { width: 56px; height: 56px; }
  .video-pending { font-size: 12px; padding: 10px 14px; }

  .switcher-panel, .switcher-panel.is-active { grid-template-columns: 1fr; gap: 22px; }
  .switcher-person {
    flex-direction: row; align-items: center; text-align: left;
    padding-left: 0; padding-top: 18px; border-left: 0; border-top: 1px solid rgba(255,255,255,.16);
    gap: 14px; min-width: 0;
  }
  .switcher-person .testimonial-photo { width: 56px; height: 56px; margin-bottom: 0; }
  .switcher-quote { font-size: 16px; }

  .post-row { flex-direction: column; align-items: flex-start; gap: 12px; padding: 20px; }
  .post-row-arrow { display: none; }

  .sidebar-card, .sidebar-cta, .sector-card, .contact-method { padding: 22px 20px; }
  .mega-col--featured { border-left: 0; padding-left: 0; }
}

/* Prefer real motion only when the user has asked for it */
@media (prefers-reduced-motion: reduce) {
  .feature-card, .related-card, .service-card, .location-card,
  .contact-method, .post-row, .video-frame { transition: none !important; }
  .feature-card:hover, .related-card:hover, .service-card:hover,
  .location-card:hover, .contact-method:hover, .post-row:hover { transform: none !important; }
}

/* ---------------------------------------------------------------------------
 * Pointer sunburst
 *
 * A warm orange ray burst that trails the cursor, drawn in the page background
 * on every page. It is body::before because the shell is shared, so no template
 * needed touching and nothing can be forgotten on a new page. body::after is
 * already the static glow layer in site.css, so ::before is the free one.
 *
 * PLACEMENT. z-index:-1 puts this above the canvas background (html has no
 * background of its own, so body's gradient becomes the canvas) and below all
 * in-flow content, which is what "in the background" means here. It therefore
 * never sits over text, so no contrast is lost and nothing needs a panel
 * behind it.
 *
 * The position comes from --pointer-x/--pointer-y, which pages.js eases toward
 * the cursor. The easing is the trailing effect: the layer lags behind the
 * pointer and catches up, rather than snapping to it.
 *
 * This element is only revealed when pages.js adds .sunburst-on, which it does
 * on the first real pointer move. A touch device or a reduced-motion visitor
 * never sees it at all.
 * ------------------------------------------------------------------------- */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;

  background:
    /* soft warm core, so the burst has a body and not only spokes */
    radial-gradient(560px 560px at var(--pointer-x, 50vw) var(--pointer-y, 35vh),
      rgba(239, 100, 46, .15) 0%,
      rgba(239, 100, 46, .07) 45%,
      rgba(239, 100, 46, 0) 76%),
    /* The spokes. 18 narrow rays, but each one is FEATHERED rather than a hard
       band: the stop list ramps 0 -> peak -> 0 across the period instead of
       switching on and off, so the edges are already soft before the blur below
       touches them. */
    repeating-conic-gradient(from 0deg at var(--pointer-x, 50vw) var(--pointer-y, 35vh),
      rgba(255, 154, 90, 0) 0deg,
      rgba(255, 154, 90, .07) 4deg,
      rgba(255, 154, 90, 0) 8deg,
      rgba(255, 154, 90, 0) 19deg);

  /* Softens the whole layer, which is what stops the rays reading as distinct
     spokes and blends the burst into the page. Kept moderate: this layer
     repaints as the pointer moves, and a heavy blur on a full-viewport element
     is not free. The JS parks its animation frame loop when the burst settles,
     so the cost only exists while the pointer is actually moving. */
  filter: blur(22px);

  /* Fade everything out with distance from the pointer, so the burst is a glow
     around the cursor and not a wash over the whole viewport. The ramp is
     deliberately gentle: a late, slow falloff blends into the background
     instead of ending on a visible edge. */
  -webkit-mask-image: radial-gradient(circle 700px at var(--pointer-x, 50vw) var(--pointer-y, 35vh),
    rgba(0, 0, 0, .85) 0%, rgba(0, 0, 0, .45) 45%, rgba(0, 0, 0, .12) 72%, transparent 92%);
  mask-image: radial-gradient(circle 700px at var(--pointer-x, 50vw) var(--pointer-y, 35vh),
    rgba(0, 0, 0, .85) 0%, rgba(0, 0, 0, .45) 45%, rgba(0, 0, 0, .12) 72%, transparent 92%);

  opacity: 0;
  transition: opacity .9s ease;
}

/* Revealed only once a fine pointer has actually moved. */
html.sunburst-on body::before { opacity: 1; }

/* No pointer chase for anyone who has asked for reduced motion. site.css
   already zeroes transition durations globally, but this layer should not be
   painted at all. */
@media (prefers-reduced-motion: reduce) {
  body::before { display: none; }
}

/* ---------------------------------------------------------------------------
 * Blog illustrations
 *
 * Each post carries one illustration (the 'image' key in data/posts.php),
 * rendered as a LAYERED background on the thumb spans that already existed.
 * No markup was added and no class changed.
 *
 * THE LAYERING IS NOT DECORATION. site.css sets these gradients with the
 * `background` SHORTHAND, so declaring background-image alone REPLACES the
 * gradient. The transparent SVG then sits directly on the dark page and its ink
 * linework vanishes, leaving only the orange accents floating on purple. Art and
 * gradient must be declared together so the illustration composites onto the
 * light surface it was drawn for. Verified by rendering both ways.
 *
 * The art URL arrives as --thumb-art from thumb_style() in inc/helpers.php. When
 * a post has no image the variable is unset, `none` applies, and the span keeps
 * exactly the gradient it had before.
 *
 * The nav panel's 90px (--md) and 56px (--sm) bands are deliberately NOT
 * illustrated. At 8.2:1 and 7.8:1, `cover` shows only ~21% of an 800x450
 * illustration, which is a fragment rather than an illustration, so they keep
 * their gradients.
 * ------------------------------------------------------------------------- */

.blog-tease-thumb,
.blog-card-thumb--lg {
  background-image: var(--thumb-art, none), linear-gradient(135deg, #cdbdf0, #6a54a8);
}

/* Declared after the base rule: equal specificity, so source order decides. */
.blog-tease-thumb--lg {
  background-image: var(--thumb-art, none), linear-gradient(135deg, #ffcda3, var(--ember-500));
}

/* Both layers cover; the art is centred so the composition survives the crop. */
.blog-tease-thumb,
.blog-tease-thumb--lg,
.blog-card-thumb--lg {
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
}

/* ---------- Per-post illustration: post hero ----------
 * Sits directly on the page ground rather than on a plate. The illustration
 * carries a white separation pass under its ink linework, so on the dark surface
 * it reads as white linework, which is the site's own line style. No plate is
 * needed and no plate colour is invented.
 */
.page-hero-figure { margin: 0; }
.page-hero-figure img {
  display: block; width: 100%; height: auto; max-width: 520px;
}

/* ---------- Per-post illustration: blog index row ----------
 * The plate is the same light gradient the other thumbs use, so the
 * illustration composites onto the surface its ink linework was drawn for.
 * The <img> is lazy-loaded and its box is reserved by the width/height
 * attributes, so nothing shifts as the eight rows load.
 */
.post-row-thumb {
  flex: 0 0 auto;
  width: 160px; height: 90px;
  border-radius: 10px;
  overflow: hidden;
  background: linear-gradient(135deg, #cdbdf0, #6a54a8);
}
.post-row-thumb img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}

/* ======================================================================
 * Fail-safe for the entrance animations
 *
 * site.css hides .reveal-item (opacity:0) and .scroll-reveal (opacity:0) by
 * DEFAULT, and only site.js adding .is-revealed makes them visible. That means
 * 50 elements per page depend on JavaScript to be readable -- including the
 * homepage headline, its standfirst and the lead card.
 *
 * Tested by loading the live site with scripting disabled: the homepage renders
 * as a blank purple page with a working header and cookie banner, and no content
 * at all. Not a hypothetical.
 *
 * components.php now opens with class="no-js" and an inline script swaps that for
 * "js" before the body paints. So `html:not(.js)` means "JavaScript never ran",
 * and in that case the content is simply shown. The entrance animation is
 * decoration; the words are not, and decoration must never be what stands between
 * a visitor and the page.
 *
 * Everything here fails safe in both directions:
 *   - JS off or blocked      -> no `js` class -> content visible, no animation
 *   - site.js fails to load  -> its onerror removes `js` -> content visible
 *   - JS working normally    -> `js` present -> animation runs exactly as before
 *
 * Deliberately !important: site.css is generated, its selectors are more specific
 * in places, and this must not lose a specificity fight to a file that gets
 * regenerated. If site.css ever gains its own no-JS fallback this block can go. */
html:not(.js) .reveal-item,
html:not(.js) .reveal-item--card,
html:not(.js) .scroll-reveal {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

/* ======================================================================
 * Navigation: let the bar span further out, keep the menu as one cluster
 *
 * Two rounds of owner feedback, in order:
 *
 * 1. "The floating navigation menu looks too squished -- let it span further out."
 *    The nav content was capped at 1440px inside a bar spanning the viewport, and
 *    `.nav-links` gap stepped down 22 -> 16 (<=1500) -> 13 (<=1320). So the six
 *    links sat 13px apart at 1280px while the pill carried ~93px of dead space at
 *    each end: cramped and empty at once.
 *
 * 2. "The menu items are now spread too far apart -- they need to stay together."
 *    My first attempt answered (1) by also making the group absorb the free space
 *    (`flex: 1 1 auto; justify-content: space-between`). That let the spacing scale
 *    with the viewport -- 47px at 1280, 116px at 1920 -- because space-between was
 *    setting the gaps and the clamp never bound. Reverted.
 *
 * What survives is the right half of (1): the bar and its content span further out.
 * The item spacing is bounded and the group sizes to its content, so the slack sits
 * between the brand and the menu and between the menu and the CTAs -- which is what
 * makes it read as one menu rather than items flung across the bar.
 *
 * All of this lives here rather than in site.css because site.css is GENERATED and
 * hand-edits to it are lost on regeneration. NAV ONLY: `.shell` keeps its 1440px
 * cap, so no page content moves. The graduated step-downs in site.css are
 * superseded rather than deleted -- this stylesheet loads after it, so an
 * equal-specificity rule here wins at every width. The hamburger takeover at 1100px
 * and the mega-panel anchoring are untouched. */

/* Nav content tracks the bar, and the pill sits closer to the edges (was 20px). */
.nav {
  margin-left: 12px;
  margin-right: 12px;
}
.nav-inner {
  max-width: none;
}

/* 2. Bounded spacing that can tighten but cannot balloon.
   The first attempt here used `gap: clamp(20px, 1.7vw, 44px)` together with
   `flex: 1 1 auto; justify-content: space-between` on the group. That was wrong:
   space-between distributed the free space, so the clamp never bound and the gaps
   scaled with the viewport -- 47px at 1280, 116px at 1920, with the group spanning
   1457px against ~589px of actual label width. Paul's correction: the menu must
   read as ONE CLUSTER, not items flung across the bar.

   So the group sizes to its content again (site.css already sets flex: 0 0 auto)
   and the slack returns to the two outer positions, between the brand and the
   group and between the group and the CTA group. That is what keeps it reading as
   one menu. The cap is deliberately low: 26px maximum, 16px floor. */
.nav-links {
  gap: clamp(16px, 1.6vw, 26px);
}

/* The links themselves must never wrap now that they have room to spread. */
.nav-links > li {
  white-space: nowrap;
}

/* ======================================================================
 * Lead form: honesty notice, ABOVE the fields
 *
 * Instructed by Mark (marketing) 2026-10-07. The form presented as fully
 * functional while capturing nothing, so a visitor typed their details in before
 * the panel told them it had not sent. The disclosure now arrives BEFORE the
 * effort instead of after it.
 *
 * The phone is inside this block, not just in the panel, because it is the only
 * route that reliably becomes a record while capture does not exist. Mark's
 * instruction was to make it the visually primary action here.
 *
 * Labelling only — nothing here implies capture exists, and it all comes out when
 * the ProactivePSA capture lands. */
.lead-notice {
  margin: 0 0 20px;
  padding: 14px 16px;
  border-radius: 10px;
  border: 1px solid rgba(255, 154, 90, .34);
  background: rgba(255, 154, 90, .10);
}
.lead-notice-text {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--mist-100, #e5e3f2);
}
/* Reuses the success panel's call button so the primary action looks identical
   wherever it appears. Margins reset: that button was spaced for the panel. */
.lead-notice-call {
  margin: 14px 0 0;
}

/* ---------------------------------------------------------------------------
 * OWNER LOGO (14 October 2026): the supplied lockup in the header, mobile menu
 * and footer. Hand-maintained here, not in the generated site.css.
 *
 * Height drives the size and width follows the real 2.374:1 ratio, so the
 * artwork is never stretched or cropped. The header logo is sized to stay
 * legible as a two-line wordmark without making the sticky bar much taller.
 * The text-era rules on .brand (font-size, nowrap) are harmless on an image.
 * ------------------------------------------------------------------------- */
.brand--logo,
.footer-brand--logo {
  display: inline-flex;
  align-items: center;
  line-height: 0;
  flex: 0 0 auto;
}
.brand-logo {
  display: block;
  width: auto;
  max-width: 100%;
  height: 52px;
}
.brand-logo--menu { height: 40px; }
.brand-logo--footer { height: 80px; }
.footer-brand--logo { margin-bottom: 18px; }
/* The visible focus ring belongs on the link around the logo, and it needs a
   little room so it does not sit on top of the artwork. */
.brand--logo:focus-visible,
.footer-brand--logo:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 4px;
  border-radius: 6px;
}
@media (max-width: 640px) {
  .brand-logo { height: 44px; }
  .brand-logo--menu { height: 40px; }
  .brand-logo--footer { height: 72px; }
}

/* Mobile quick links: dividers follow the two-column layout, not the tablet's
   3n rule. Seven tiles finish with one full-width link, so the penultimate tile
   is NOT automatically in the last row. Keep hover feedback but don't lift an
   entire tile (including its dividers) out of the shared grid on touch. */
@media (max-width: 640px) {
  .quicklinks-row > .quicklink-tile:nth-child(n) {
    border-right: 1px solid var(--field-border);
    border-bottom: 1px solid var(--field-border);
  }
  .quicklinks-row > .quicklink-tile:nth-child(2n),
  .quicklinks-row > .quicklink-tile:last-child {
    border-right: none;
  }
  .quicklinks-row > .quicklink-tile:last-child,
  .quicklinks-row > .quicklink-tile:nth-last-child(2):nth-child(odd) {
    border-bottom: none;
  }
  .quicklinks-row > .quicklink-tile:hover {
    transform: none;
  }
}
