/* HOJ Electrical Ltd — shared site stylesheet
   Design system sourced from style/style-tokens.json (chosen preview variant "a"):
   near-black/charcoal base, brushed-chrome/silver metallic accent, monochrome palette,
   Barlow Condensed display + Barlow body, uppercase tracked micro-labels, hairline borders,
   sharp/minimal border-radius. Do not introduce color hues — palette is deliberately grayscale. */

:root {
  --black:#0A0A0A; --black-mid:#111111; --black-light:#1A1A1A; --black-card:#161616;
  --black-footer:#070707;
  --chrome:#C8C8C8; --chrome-bright:#E8E8E8; --chrome-dim:#999999; --chrome-dark:#777777;
  --border:rgba(200,200,200,0.1); --border-bright:rgba(200,200,200,0.22); --body-text:#BBBBBB;
  /* Deliberate, single-use exception to the grayscale palette: marks the 24/7 emergency
     call-out banner as the one service that applies across everything else. */
  --amber:#D9A44A; --amber-border:rgba(217,164,74,0.4);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
/* overflow-x: hidden lives on html only, not body — setting it on both
   breaks the standard viewport-scroll propagation from body to the root
   scrolling element and silently kills vertical page scroll entirely. */
html { scroll-behavior: smooth; overflow-x: hidden; }
body {
  font-family: 'Barlow', sans-serif;
  color: var(--chrome);
  background: var(--black);
  -webkit-font-smoothing: antialiased;
  line-height: 1.6;
  font-size: 19px;
}
img { max-width: 100%; }
a { text-decoration: none; color: inherit; }
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
.display { font-family: 'Barlow Condensed', sans-serif; font-weight: 900; text-transform: uppercase; }
.chrome-text {
  background: linear-gradient(to top,#6e6e6e 0%,#9a9a9a 25%,#c8c8c8 50%,#e8e8e8 75%,#fff 100%);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}

a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--chrome-bright);
  outline-offset: 2px;
}

/* Header / nav */
header {
  background: rgba(10,10,10,0.97);
  padding: 0 24px;
  display: flex; align-items: center; justify-content: space-between;
  height: 76px;
  border-bottom: 1px solid var(--border-bright);
  position: sticky; top: 0; z-index: 1000;
  backdrop-filter: blur(10px);
}
.logo-badge { display: inline-flex; align-items: center; flex-shrink: 0; }
.logo-badge img { height: 60px; width: auto; display: block; }
nav { flex: 1; display: flex; justify-content: center; min-width: 0; }
nav ul { display: flex; gap: 34px; list-style: none; align-items: center; }
nav a {
  color: var(--chrome-dim); font-size: 15px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 1px; transition: color 0.2s;
}
nav a:hover, nav a.active { color: var(--chrome-bright); }
.has-dropdown { position: relative; }
.nav-right { display: flex; align-items: center; gap: 20px; flex-shrink: 0; }
.nav-socials { display: flex; align-items: center; gap: 14px; transform: translateY(1px); }
.nav-socials a { color: var(--chrome-dim); display: inline-flex; transition: color 0.2s; }
.nav-socials a:hover { color: var(--chrome-bright); }
.nav-socials svg { width: 20px; height: 20px; display: block; }
.dropdown {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%) translateY(-6px);
  background: var(--black-mid); border: 1px solid var(--border-bright); border-top: 2px solid var(--chrome-dim);
  min-width: 230px; padding: 6px 0;
  opacity: 0; pointer-events: none; transition: opacity 0.2s, transform 0.2s;
  z-index: 200;
}
.has-dropdown:hover .dropdown, .has-dropdown.open .dropdown { opacity: 1; pointer-events: all; transform: translateX(-50%) translateY(0); }
.dropdown a { display: block; padding: 10px 18px; font-size: 12.3px; border-top: 1px solid var(--border); white-space: nowrap; }
.dropdown a:first-child { border-top: none; }
.nav-cta {
  border: 1px solid rgba(200,200,200,0.12) !important;
  color: var(--chrome-dim) !important;
  padding: 9px 18px !important;
  border-radius: 2px;
  font-size: 15px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 1px; transition: color 0.2s, border-color 0.2s;
}
.nav-cta:hover { color: var(--chrome-bright) !important; border-color: var(--border-bright) !important; }
.menu-toggle { display: none; background: none; border: none; color: var(--chrome); font-size: 22px; cursor: pointer; }

/* Header quick-contact buttons (Call Now / Email): desktop only, sit to
   the left of Request a Quote. Hidden on mobile (see 1050px breakpoint
   below) — the mobile equivalent lives in the homepage hero instead,
   see .hero-quick-actions. */
.nav-actions { display: flex; align-items: center; gap: 10px; }
.nav-call, .nav-email {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid rgba(200,200,200,0.12);
  color: var(--chrome-dim);
  padding: 9px 16px;
  border-radius: 2px;
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.5px; text-transform: uppercase; white-space: nowrap;
  transition: color 0.2s, border-color 0.2s;
}
.nav-call:hover, .nav-email:hover { color: var(--chrome-bright); border-color: var(--border-bright); }
.nav-call svg, .nav-email svg { width: 14px; height: 14px; flex-shrink: 0; }

/* Mobile nav drawer */
nav ul.nav-open {
  display: flex !important;
  position: absolute; top: 76px; left: 0; right: 0;
  background: var(--black-mid); flex-direction: column; gap: 0;
  border-bottom: 1px solid var(--border-bright);
}
nav ul.nav-open li { width: 100%; border-top: 1px solid var(--border); }
nav ul.nav-open a { display: block; padding: 16px 24px; text-align: center; }

/* Contact has its own header button on desktop (.nav-cta); on mobile that
   button is hidden instead and this item (last in the nav list) surfaces
   Contact inside the dropdown menu instead — see 1050px breakpoint below. */
.nav-item-mobile-contact { display: none; }

/* Hero (page-level, optionally with a photo background) */
.page-hero { background: var(--black-mid); padding: 72px 24px; border-bottom: 1px solid var(--border); position: relative; }
.page-hero.has-photo {
  background-size: cover; background-position: center;
  height: 90vh; display: flex; align-items: center; justify-content: center;
}
.page-hero.has-photo::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, rgba(10,10,10,0.85) 0%, rgba(10,10,10,0.62) 50%, rgba(10,10,10,0.25) 100%);
  pointer-events: none;
}
.hero-split { position: absolute; inset: 0; overflow: hidden; z-index: 0; }
.hero-split-half {
  position: absolute; top: 0; height: 100%; width: 58%;
  background-size: cover; background-position: center;
}
.hero-split-left {
  left: 0;
  clip-path: polygon(0 0, 100% 0, 78% 100%, 0 100%);
}
.hero-split-right {
  right: 0;
  clip-path: polygon(22% 0, 100% 0, 100% 100%, 0 100%);
}

@media (max-width: 768px) {
  /* .page-hero.has-photo is display:flex (row) on desktop so it can center
     .page-hero-inner while .hero-split sits behind it as position:absolute,
     out of flow. Here .hero-split goes back into flow (position:relative)
     to stack — but left as a flex item it becomes a second row sibling
     next to .page-hero-inner with no explicit width, and .hero-split-half
     has no intrinsic size (background-image only, no content), so it was
     collapsing to 0 width and rendering nothing. Block layout lets the
     photo stack and the text stack normally instead of sharing a row. */
  .page-hero.has-photo { height: auto; padding: 0; display: block; }
  .hero-split-half { position: relative; width: 100%; height: 240px; clip-path: none; }
  .hero-split { position: relative; display: flex; flex-direction: column; inset: auto; width: 100%; }
  /* .hero-split (the stacked photos) is the only in-flow content, so it
     alone determines .page-hero.has-photo's height — .page-hero-inner is
     pulled out of flow to overlay on top of it, matching the desktop
     treatment where text sits over the photo instead of below it.
     Scoped as .page-hero.has-photo .page-hero-inner (not just
     .page-hero-inner) so this beats the base .page-hero-inner rule further
     down the file on specificity rather than relying on source order. */
  .page-hero.has-photo .page-hero-inner {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 24px;
  }
}
.page-hero-inner { max-width: 760px; margin: 0 auto; text-align: center; position: relative; z-index: 2; }
.eyebrow { display: flex; align-items: center; justify-content: center; gap: 12px; margin-bottom: 20px; }
.eyebrow-line { width: 36px; height: 1px; background: var(--chrome-dark); }
.eyebrow span { color: var(--chrome-dim); font-size: 17px; font-weight: 600; letter-spacing: 3px; text-transform: uppercase; }
.page-hero h1 { font-size: 72px; line-height: 0.98; letter-spacing: -1px; margin-bottom: 20px; }
.page-hero p { color: var(--body-text); font-size: 19px; line-height: 1.75; max-width: 600px; margin: 0 auto 32px; }
.page-hero.has-photo h1 { filter: drop-shadow(0 2px 6px rgba(0,0,0,0.9)); }
.page-hero.has-photo p { text-shadow: 0 2px 12px rgba(0,0,0,0.7); }
.hero-btns { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
/* Mobile-only Call Now / Email row, shown above the hero's Request a
   Quote button; the desktop equivalent lives in the header instead
   (see .nav-call / .nav-email), hidden here at desktop widths. */
.hero-quick-actions { display: none; gap: 12px; justify-content: center; flex-wrap: wrap; margin-bottom: 20px; }
.hero-quick-actions a {
  display: inline-flex; align-items: center; gap: 8px;
  background: transparent; border: 1px solid rgba(200,200,200,0.12); color: var(--chrome-dim);
  padding: 12px 22px; border-radius: 2px; font-weight: 600; font-size: 13px;
  letter-spacing: 0.5px; text-transform: uppercase;
}
.hero-quick-actions svg { width: 15px; height: 15px; flex-shrink: 0; }
.btn-primary {
  background: linear-gradient(135deg,#2a2a2a,#1a1a1a); border: 1px solid var(--border-bright);
  color: var(--chrome-bright); padding: 14px 30px; border-radius: 2px; font-weight: 700;
  font-size: 13.75px; letter-spacing: 0.5px; text-transform: uppercase; display: inline-block;
}
.btn-ghost {
  background: transparent; border: 1px solid rgba(200,200,200,0.12); color: var(--chrome-dim);
  padding: 14px 30px; border-radius: 2px; font-weight: 600; font-size: 13.75px;
  letter-spacing: 0.5px; text-transform: uppercase; display: inline-block;
}
/* Hero's secondary CTA sits directly on a photo (unlike other .btn-ghost
   uses on plain dark backgrounds), so it needs a translucent fill and
   full-opacity border/text to stay legible against any hero image. */
.page-hero.has-photo .btn-ghost {
  background: rgba(0,0,0,0.5); border-color: transparent; color: #fff;
}

/* Stats row */
.stats-row {
  background: var(--black-mid);
  display: grid; grid-template-columns: repeat(4,1fr);
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.stat { padding: 30px 20px; text-align: center; border-right: 1px solid var(--border); }
.stat:last-child { border-right: none; }
.stat-num { font-size: 44px; line-height: 1; display: block; letter-spacing: -1px; margin-bottom: 6px; }
.stat-lbl { font-size: 17px; font-weight: 600; color: var(--chrome-dim); text-transform: uppercase; letter-spacing: 1px; }

/* Sections */
section { padding: 72px 24px; border-bottom: 1px solid var(--border); }
.section-label { color: var(--chrome-dim); font-size: 17px; font-weight: 600; letter-spacing: 3px; text-transform: uppercase; margin-bottom: 12px; display: block; }
.section-h2 { font-size: 36px; line-height: 1; margin-bottom: 16px; letter-spacing: -0.5px; }
.section-intro { color: var(--body-text); font-size: 19px; max-width: 560px; line-height: 1.75; margin-bottom: 44px; text-align: left; }

/* Services grid */
#services .wrap { max-width: none; margin: 0; }
.services-heading-center { text-align: center; margin-bottom: 40px; }

/* Auto-scrolling service photo strip — scroll-driven (not transform-driven) so
   native trackpad/wheel horizontal scroll and the JS autoplay in main.js share
   the same scrollLeft instead of fighting each other. See main.js for the
   rAF loop, hover-pause, and seamless modulo-wrap logic. */
.services-photo-strip-wrap { overflow: hidden; margin-bottom: 40px; }
.services-photo-strip {
  display: flex; overflow-x: auto; scroll-behavior: auto;
  -webkit-overflow-scrolling: touch; padding: 4px 24px 16px;
  scrollbar-width: none; -ms-overflow-style: none;
}
.services-photo-strip::-webkit-scrollbar { display: none; }
.strip-set { display: flex; gap: 14px; flex-shrink: 0; }
.strip-photo {
  position: relative; flex: 0 0 auto; width: 240px; height: 160px;
  border-radius: 4px; overflow: hidden; display: block;
  border: 1px solid var(--border); background: var(--black-card);
}
.strip-photo img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.35s; }
.strip-photo:hover, .strip-photo:focus-visible { border-color: var(--chrome-dim); }
.strip-photo:hover img, .strip-photo:focus-visible img { transform: scale(1.06); }
/* Same darkening pattern as .page-hero.has-photo::before (service hero photos) —
   reused here at rest opacity 0 so it's a hover-only reveal, not a permanent tint. */
.strip-photo::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to top, rgba(10,10,10,0.85) 0%, rgba(10,10,10,0.62) 50%, rgba(10,10,10,0.25) 100%);
  opacity: 0; transition: opacity 0.3s ease;
}
.strip-photo:hover::after, .strip-photo:focus-visible::after { opacity: 1; }
/* Font/weight/uppercase/color matched exactly to .s-card h3 (the service tile
   labels), verified against that rule's computed styles rather than eyeballed. */
.strip-caption {
  position: absolute; left: 14px; right: 14px; bottom: 10px; z-index: 2; pointer-events: none;
  font-family: 'Barlow Condensed', sans-serif; font-weight: 800; font-size: 16px;
  text-transform: uppercase; color: var(--chrome-bright);
  opacity: 0; transform: translateY(12px); transition: opacity 0.3s ease, transform 0.3s ease;
}
.strip-photo:hover .strip-caption, .strip-photo:focus-visible .strip-caption { opacity: 1; transform: translateY(0); }
.services-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 3px; background: rgba(255,255,255,0.06); }
.s-card {
  background: var(--black-card); border-top: 2px solid transparent;
  transition: border-color 0.25s, background 0.25s;
}
.s-card:hover, .s-card:focus-within { border-top-color: var(--chrome-dim); background: var(--black-light); }
.s-card a.s-card-link {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  padding: 26px 22px; height: 100%; text-align: center;
}
.s-card .ti { font-size: 26px; color: var(--chrome-dim); flex-shrink: 0; }
.s-card h3 { font-family: 'Barlow Condensed', sans-serif; font-weight: 800; font-size: 18px; text-transform: uppercase; color: var(--chrome-bright); }

/* Emergency call-out banner — spans the full grid width as its own row */
.s-emergency-banner {
  grid-column: 1 / -1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  text-align: center; background: var(--black-card);
  border-top: 2px solid var(--amber); border-bottom: 1px solid var(--amber-border);
  padding: 30px 22px; transition: background 0.25s;
}
.s-emergency-banner:hover, .s-emergency-banner:focus-within { background: var(--black-light); }
.s-emergency-banner .ti { font-size: 32px; color: var(--amber); }
.s-emergency-banner h3 { font-family: 'Barlow Condensed', sans-serif; font-weight: 800; font-size: 20px; text-transform: uppercase; letter-spacing: 1px; color: var(--chrome-bright); }

/* About / two-column layout */
.about-intro { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 64px; align-items: start; }
.about-intro p { color: var(--body-text); font-size: 19px; line-height: 1.85; margin-bottom: 20px; text-align: left; }
.about-intro p:last-child { margin-bottom: 0; }
.partner-card {
  background: var(--black-light); border: 1px solid var(--border-bright);
  border-top: 2px solid var(--chrome); padding: 24px;
}
.partner-card .label { color: var(--chrome-dim); font-size: 17px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 10px; display: block; }
.partner-card p { color: var(--chrome); font-size: 19px; line-height: 1.7; margin: 0; }

/* Accreditation badges */
.accreds-row { display: flex; gap: 14px; flex-wrap: wrap; }
.badge {
  border: 1px solid var(--border-bright); border-radius: 2px; padding: 20px 28px;
  text-align: center; min-width: 150px; background: rgba(255,255,255,0.02);
}
.badge-name { font-family: 'Barlow Condensed', sans-serif; font-size: 20px; font-weight: 900; display: block; }
.badge-desc { font-size: 17px; color: var(--chrome-dim); letter-spacing: 0.5px; text-transform: uppercase; }

/* CTA strip */
.cta-strip {
  background: var(--black-light); padding: 60px 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 32px; flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
}
.cta-strip h2 { font-size: 34px; line-height: 1.05; margin-bottom: 8px; }
.cta-strip p { color: var(--body-text); font-size: 19px; max-width: 460px; line-height: 1.7; }
.cta-btns { display: flex; gap: 14px; flex-wrap: wrap; }

/* Contact form (shared markup, used inside the quote modal) */
.contact-form { max-width: 480px; margin: 0 auto; display: grid; gap: 14px; text-align: left; }
.contact-form[hidden] { display: none; }
.contact-form input, .contact-form textarea {
  background: var(--black); border: 1px solid var(--border-bright); color: var(--chrome);
  padding: 12px 16px; font-family: 'Barlow', sans-serif; font-size: 17.5px; border-radius: 0;
  width: 100%;
}
.contact-form ::placeholder { color: var(--chrome-dim); opacity: 0.85; }
.form-note { color: var(--chrome-dim); font-size: 13.75px; margin-top: 4px; text-align: center; }
.contact-form-status { display: none; max-width: 480px; margin: 0 auto; text-align: center; font-size: 16px; line-height: 1.6; padding: 16px 18px; }
.contact-form-status.is-success { display: block; color: var(--chrome-bright); border: 1px solid var(--border-bright); }
.contact-form-status.is-error { display: block; color: var(--amber); border: 1px solid var(--amber-border); }

/* Quote request modal (injected by main.js, opens on any "#contact" link click) */
.quote-modal-overlay {
  display: none; position: fixed; inset: 0; z-index: 999;
  background: rgba(0,0,0,0.78); align-items: center; justify-content: center; padding: 24px;
}
.quote-modal-overlay.is-open { display: flex; }
.quote-modal {
  background: var(--black-mid); border: 1px solid var(--border-bright); border-top: 2px solid var(--chrome-dim);
  max-width: 480px; width: 100%; max-height: 90vh; overflow-y: auto; padding: 40px 32px 32px; position: relative;
}
.quote-modal-close {
  position: absolute; top: 14px; right: 14px; background: none; border: none; cursor: pointer;
  color: var(--chrome-dim); font-size: 26px; line-height: 1; padding: 4px;
}
.quote-modal-close:hover { color: var(--chrome-bright); }
.quote-modal-title { font-size: 26px; margin-bottom: 20px; text-align: center; }
.quote-modal-contact {
  display: flex; flex-direction: column; gap: 10px; margin-top: 24px; padding-top: 20px;
  border-top: 1px solid var(--border);
}
.quote-modal-contact a, .quote-modal-contact span {
  display: flex; align-items: center; gap: 10px; color: var(--body-text); font-size: 20px;
}
.quote-modal-contact a:hover { color: var(--chrome-bright); }
.quote-modal-contact svg { width: 20px; height: 20px; flex-shrink: 0; stroke: var(--chrome-dim); display: block; }
/* align-items:center on the row above centers icon vs. text against the
   FONT's fixed ascent+descent, not the text's actual painted ink — so rows
   whose characters include a descender (the "@" and the "j" in
   "hojelectrical") paint lower than that fixed center, making the icon look
   high. Confirmed by rasterizing icon and text ink to a canvas (not
   getBoundingClientRect, which reads the font's line-box and misses this).
   Offsets below match each row's own measured ink gap — the phone row's
   gap is <1px and imperceptible, so it's left alone. */
.quote-modal-contact span svg { transform: translateY(1.5px); }
.quote-modal-contact a[href^="mailto:"] svg,
.quote-modal-contact a[href*="instagram.com"] svg,
.quote-modal-contact a[href*="facebook.com"] svg {
  transform: translateY(3px);
}

/* Footer */
footer { background: var(--black-footer); padding: 48px 24px 24px; }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 48px; padding-bottom: 36px; border-bottom: 1px solid var(--border); margin-bottom: 24px; }
.footer-grid.footer-grid--3col { grid-template-columns: 1.6fr 1fr 1fr; }
.footer-logo { margin-bottom: 14px; }
.footer-logo img { height: 22px; }
.footer-desc { color: var(--body-text); font-size: 17px; line-height: 1.75; max-width: 300px; }
.footer-col-title { color: var(--chrome-dim); font-size: 26px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; margin-bottom: 16px; display: block; }
.footer-links { display: flex; flex-direction: column; gap: 10px; }
.footer-links a { color: var(--body-text); font-size: 18.7px; opacity: 0.85; }
.footer-links a:hover { opacity: 1; color: var(--chrome-bright); }
.footer-contact { display: flex; flex-direction: column; gap: 10px; }
.footer-contact a, .footer-contact span { display: flex; align-items: center; gap: 9px; color: var(--body-text); font-size: 21.25px; opacity: 0.85; }
.footer-contact a:hover { opacity: 1; color: var(--chrome-bright); }
.footer-contact svg { width: 18.75px; height: 18.75px; flex-shrink: 0; stroke: var(--chrome-dim); }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; }
.footer-bottom p { color: var(--chrome-dim); font-size: 17px; }
.footer-credit { display: inline-flex; align-items: center; gap: 9px; color: var(--chrome-dark); font-size: 21px; letter-spacing: 0.2px; transition: color 0.2s ease; }
.footer-credit img { height: 1em; width: auto; display: block; }
.footer-credit:hover, .footer-credit:focus-visible, .footer-credit:active { color: var(--chrome-dim); }
.footer-accred { color: var(--chrome-dim); font-size: 26px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; }

/* Placeholder / coming-soon states (used for empty hero images and empty content areas) */
.placeholder-box {
  border: 1px dashed var(--border-bright); border-radius: 2px;
  padding: 28px; text-align: center; color: var(--chrome-dim);
  background: rgba(255,255,255,0.02);
}
.placeholder-box .placeholder-tag {
  display: inline-block; font-size: 17px; font-weight: 700; letter-spacing: 2px;
  text-transform: uppercase; color: var(--chrome-dark); border: 1px solid var(--border-bright);
  padding: 4px 10px; border-radius: 2px; margin-bottom: 12px;
}
.placeholder-box p { color: var(--chrome-dim); font-size: 19px; line-height: 1.7; }

/* Emergency call-out phone highlight (emergency-callout.html only) */
.emergency-box { background: var(--black-light); border: 1px solid var(--border-bright); border-top: 2px solid var(--chrome); padding: 24px; }
.emergency-box .em-label { color: var(--chrome-dim); font-size: 17px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; display: block; margin-bottom: 8px; }
.emergency-box p { color: var(--body-text); font-size: 19px; line-height: 1.65; margin-bottom: 12px; }
.emergency-box .phone-link { color: var(--chrome-bright); font-weight: 700; font-size: 24px; font-family: 'Barlow Condensed', sans-serif; }
.emergency-box .phone-link:hover { color: var(--chrome); }

/* Service detail page layout */
.service-body { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 56px; align-items: start; }
.service-body p { color: var(--body-text); font-size: 19px; line-height: 1.85; margin-bottom: 20px; }
.service-body ul { color: var(--body-text); font-size: 19px; line-height: 1.9; margin: 0 0 20px 20px; }
.scope-card {
  background: var(--black-light); border: 1px solid var(--border-bright);
  border-top: 2px solid var(--chrome); padding: 24px;
}
.scope-card .label { color: var(--chrome-dim); font-size: 17px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 14px; display: block; }
.scope-card ul { list-style: none; margin: 0; padding: 0; }
.scope-card li { color: var(--chrome); font-size: 19px; padding: 10px 0; border-top: 1px solid var(--border); }
.scope-card li:first-child { border-top: none; }

/* Service scope tag row on services overview page */
.scope-tag { display: inline-block; font-size: 17px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase; color: var(--chrome-dark); margin-top: 10px; }

/* Service detail page — photo/title/tags overview layout */
.service-hero-split { display: grid; grid-template-columns: 1fr 1.1fr; gap: 56px; align-items: center; }
.service-photo-frame {
  position: relative; border: 1px solid var(--border-bright); border-radius: 6px;
  overflow: hidden; aspect-ratio: 4/3; background: var(--black-card);
}
.service-photo-frame img { display: block; width: 100%; height: 100%; object-fit: cover; }
.service-photo-tag {
  position: absolute; left: 16px; bottom: 16px;
  background: rgba(10,10,10,0.78); backdrop-filter: blur(6px);
  border: 1px solid var(--border-bright); border-radius: 2px;
  padding: 7px 14px; color: var(--chrome-bright);
  font-size: 15px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
}
.service-index { color: var(--chrome-dark); font-size: 17px; font-weight: 700; letter-spacing: 2px; }
.service-hero-content h1 { margin-bottom: 6px; }
.service-hero-content h2 {
  font-family: 'Barlow', sans-serif; font-size: 22px; font-weight: 700;
  color: var(--chrome-dim); text-transform: none; letter-spacing: 0; margin-bottom: 18px;
}
.service-hero-content p { color: var(--body-text); font-size: 19px; line-height: 1.85; margin-bottom: 18px; }
.service-tags { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0 28px; }
.service-tag {
  display: inline-block; border: 1px solid var(--border-bright); border-radius: 2px;
  padding: 7px 14px; font-size: 15px; font-weight: 700; letter-spacing: 0.5px;
  text-transform: uppercase; color: var(--chrome-dim);
}
.service-cta { display: inline-flex; align-items: center; gap: 10px; }
.service-cta-arrow { width: 14px; height: 14px; flex-shrink: 0; }

/* Service detail page — additional photo gallery (reuses .portfolio-grid) */
.service-gallery { padding-top: 0; }

/* Portfolio grid */
.portfolio-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 20px; }
.portfolio-item { background: var(--black-card); border: 1px solid var(--border); overflow: hidden; }
.portfolio-item img { display: block; width: 100%; height: 260px; object-fit: cover; transition: transform 0.35s; }
.portfolio-item:hover img { transform: scale(1.05); }
.portfolio-caption { padding: 16px 18px; }
.portfolio-caption .cap-title { font-family: 'Barlow Condensed', sans-serif; font-weight: 700; font-size: 15px; text-transform: uppercase; color: var(--chrome-bright); display: block; margin-bottom: 4px; }
.portfolio-caption .cap-service { font-size: 17px; color: var(--chrome-dim); text-transform: uppercase; letter-spacing: 1px; }
.portfolio-shortfall-note { color: var(--chrome-dim); font-size: 11px; margin-top: 32px; text-align: center; }

/* Breadcrumb / small back link used on service pages */
.back-link { display: inline-block; margin-bottom: 20px; font-size: 17px; letter-spacing: 1px; text-transform: uppercase; color: var(--chrome-dim); }
.back-link:hover { color: var(--chrome-bright); }

/* Team page — director profile */
.director-grid { display: grid; grid-template-columns: 300px 1fr; gap: 48px; align-items: start; }
.director-info .role-title { color: var(--chrome-dim); font-size: 17px; font-weight: 600; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 24px; padding-bottom: 20px; border-bottom: 1px solid var(--border); display: block; }
.director-info p { color: var(--body-text); font-size: 19px; line-height: 1.85; margin-bottom: 18px; }
.qual-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 28px; }
.qual-badge { border: 1px solid var(--border-bright); padding: 6px 14px; font-size: 17px; font-weight: 700; color: var(--chrome-dim); text-transform: uppercase; letter-spacing: 0.5px; border-radius: 2px; }

/* Team page — team grid */
.team-grid { display: grid; grid-template-columns: repeat(5,1fr); gap: 3px; background: rgba(255,255,255,0.06); margin-top: 24px; }
.team-card { background: var(--black-card); border-top: 2px solid transparent; transition: border-color 0.2s; }
.team-card:hover { border-top-color: var(--chrome-dim); }
.team-card-img { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; background: var(--black-light); border-bottom: 1px solid var(--border); font-size: 30px; overflow: hidden; }
.team-card-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.team-card-info { padding: 16px; }
.team-card-info .t-name { font-family: 'Barlow Condensed', sans-serif; font-weight: 800; font-size: 15px; text-transform: uppercase; color: var(--chrome-bright); display: block; margin-bottom: 2px; }
.team-card-info .t-bio { font-size: 16.9px; line-height: 1.55; color: var(--body-text); opacity: 0.8; margin-top: 10px; }
.team-card-info .t-role { font-size: 17px; color: var(--chrome-dim); text-transform: uppercase; letter-spacing: 0.5px; }

/* Accreditations page */
.accred-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 3px; background: rgba(255,255,255,0.06); margin-top: 8px; }
.accred-grid.accred-grid-2 { grid-template-columns: repeat(2,1fr); }
.accred-card { background: var(--black-card); border-top: 2px solid var(--chrome-dim); padding: 32px 28px; }
.accred-card h3 { font-family: 'Barlow Condensed', sans-serif; font-weight: 800; font-size: 20px; text-transform: uppercase; margin-bottom: 12px; color: var(--chrome-bright); }
.accred-card p { color: var(--body-text); font-size: 19px; line-height: 1.75; margin-bottom: 14px; }
.what-it-means { background: rgba(255,255,255,0.03); border-left: 2px solid var(--chrome-dim); padding: 14px 16px; }

/* Legal pages (privacy/terms/cookie) — shared long-form text styling */
.legal-updated { color: var(--chrome-dark); font-size: 15px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.5px; margin-bottom: 40px; display: block; }
.legal-content h2 { font-family: 'Barlow Condensed', sans-serif; font-weight: 800; font-size: 24px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--chrome-bright); margin: 40px 0 14px; }
.legal-content h2:first-of-type { margin-top: 0; }
.legal-content p { color: var(--body-text); font-size: 18px; line-height: 1.85; margin-bottom: 16px; }
.legal-content ul { list-style: none; margin: 0 0 16px; padding: 0; }
.legal-content ul li { color: var(--body-text); font-size: 18px; line-height: 1.75; padding: 10px 0; border-top: 1px solid var(--border); }
.legal-content ul li:first-child { border-top: none; }
.legal-content a { color: var(--chrome-bright); text-decoration: underline; text-underline-offset: 3px; }
.legal-content a:hover { color: var(--chrome); }
.what-it-means .label { color: var(--chrome-dim); font-size: 17px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 6px; display: block; }
.what-it-means p { color: var(--chrome); font-size: 19px; line-height: 1.6; margin: 0; }

/* Accreditation logo banner — auto-scrolling, pauses on hover, static under reduced-motion */
.accred-logo-strip { background: var(--black-mid); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); padding: 32px 0; overflow: hidden; }
.accred-logo-strip .section-label { text-align: center; margin-bottom: 20px; }
.accred-logo-track-wrap { overflow: hidden; }
.accred-logo-track { display: flex; width: max-content; animation: accred-scroll 10s linear infinite; }
.accred-logo-set { display: flex; align-items: center; gap: 64px; padding: 0 32px; flex-shrink: 0; }
.accred-logo-item img { height: 40px; width: auto; }
.accred-logo-item img.logo-ipaf { height: 86px; }
.accred-logo-item img.logo-firstaid { height: 132px; }
.logo-outlined {
  filter:
    drop-shadow(1px 0 0 #fff)
    drop-shadow(-1px 0 0 #fff)
    drop-shadow(0 1px 0 #fff)
    drop-shadow(0 -1px 0 #fff);
}
@keyframes accred-scroll { from { transform: translateX(0); } to { transform: translateX(-25%); } }

/* Index-page-only override: static (non-scrolling) logo row instead of the
   auto-scrolling marquee used elsewhere (about.html, accreditations.html).
   Reuses the same wrapped/centered layout already used for reduced-motion. */
.accred-logo-strip-static .accred-logo-track { animation: none; width: 100%; flex-wrap: wrap; justify-content: center; }
.accred-logo-strip-static .accred-logo-set:nth-child(n+2) { display: none; }
.accred-logo-strip-static .accred-logo-set { flex: 1 1 100%; justify-content: center; flex-wrap: wrap; }

@media (max-width: 1050px) {
  nav ul { display: none; }
  .menu-toggle { display: block; font-size: 43px; }
  .dropdown { display: none; }
  .logo-badge img { height: 30px; }
  .nav-cta { display: none; }
  nav ul.nav-open .nav-item-mobile-contact { display: block; }
  .nav-call, .nav-email { display: none; }
  .hero-quick-actions { display: flex; }
}
@media (max-width: 900px) {
  .services-grid { grid-template-columns: repeat(2,1fr); }
  .stats-row { grid-template-columns: repeat(2,1fr); }
  .stat { border-bottom: 1px solid var(--border); }
  .about-intro { grid-template-columns: 1fr; gap: 32px; }
  .service-body { grid-template-columns: 1fr; gap: 32px; }
  .service-hero-split { grid-template-columns: 1fr; gap: 28px; }
  /* .footer-grid.footer-grid--3col (0,2,0 specificity) beats a bare .footer-grid
     override (0,1,0) regardless of source order, so the 3-column footer used on
     every service subpage stayed at grid-template-columns: 1.6fr 1fr 1fr here,
     overflowing well past 100vw — both selectors are listed so the 4-column and
     3-column footer variants both collapse to one column on mobile. */
  .footer-grid, .footer-grid.footer-grid--3col { grid-template-columns: 1fr; gap: 28px; }
  .portfolio-grid { grid-template-columns: repeat(2,1fr); }
  .director-grid { grid-template-columns: 1fr; gap: 28px; }
  .director-grid .placeholder-box { max-width: 280px; }
  .team-grid { grid-template-columns: repeat(3,1fr); }
  /* .accred-grid.accred-grid-2 (0,2,0 specificity) beats a bare .accred-grid
     override (0,1,0) regardless of source order, so the NICEIC/CompEx and
     IPAF/First Aid pairs were staying 2-column here while the plain
     3-card group correctly went single-column — both selectors are listed
     so every accreditation card gets the same single-column rule. */
  .accred-grid, .accred-grid.accred-grid-2 { grid-template-columns: 1fr; }
  /* Every <section> on the site gets 24px horizontal padding from the base
     `section` rule, and .wrap inside it adds its own 24px — the two stack
     to 48px, doubling the .page-hero-inner/.accred-logo-strip's plain 24px
     inset. Scoped to .accred-section (this page only, mobile only) rather
     than the shared `section`/.wrap rules, which ~17 other pages rely on. */
  .accred-section { padding-left: 0; padding-right: 0; }
  .accred-logo-strip { padding-left: 24px; padding-right: 24px; }
}
@media (max-width: 480px) {
  .page-hero h1 { font-size: 34px; }
  .services-grid { grid-template-columns: 1fr; }
  .section-h2 { font-size: 28px; }
  .hero-btns, .cta-btns { flex-direction: column; align-items: stretch; }
  .portfolio-grid { grid-template-columns: 1fr; }
  .team-grid { grid-template-columns: repeat(2,1fr); }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; }
  .accred-logo-track { animation: none; width: 100%; flex-wrap: wrap; justify-content: center; }
  .accred-logo-set:nth-child(n+2) { display: none; }
  .accred-logo-set { gap: 40px; padding: 0 16px; justify-content: center; flex-wrap: wrap; }
}

/* =====================================================================
   Homepage load-in effects (index.html only) — paired with the "Hero
   fade + rise" and "Stat tiles hard-impact reveal" blocks in main.js.

   Safety model, same as every other animation on this site: the default
   (no JS class present) state below is full opacity / no transform —
   fully visible. The "hidden/offset" starting state only ever applies
   once main.js has added the *-anim-pending class, and only after it has
   confirmed prefers-reduced-motion is off. If the script fails to load
   or throws, nothing in this file can leave the hero or stat row stuck
   dim or invisible.
   ===================================================================== */

/* --- Effect 1: hero heading/subtext/buttons fade + rise on page load --- */
.hero-anim-pending .page-hero-inner h1,
.hero-anim-pending .page-hero-inner p,
.hero-anim-pending .page-hero-inner .hero-quick-actions,
.hero-anim-pending .page-hero-inner .hero-btns {
  opacity: 0;
  transform: translateY(15px);
  transition: opacity 0.75s cubic-bezier(0.22, 0.61, 0.36, 1),
              transform 0.75s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.hero-anim-pending .page-hero-inner h1        { transition-delay: 0s; }
.hero-anim-pending .page-hero-inner p         { transition-delay: 0.135s; }
.hero-anim-pending .page-hero-inner .hero-quick-actions { transition-delay: 0.2s; }
.hero-anim-pending .page-hero-inner .hero-btns { transition-delay: 0.27s; }

.hero-anim-pending.hero-anim-in .page-hero-inner h1,
.hero-anim-pending.hero-anim-in .page-hero-inner p,
.hero-anim-pending.hero-anim-in .page-hero-inner .hero-quick-actions,
.hero-anim-pending.hero-anim-in .page-hero-inner .hero-btns {
  opacity: 1;
  transform: translateY(0);
}

/* --- Effect 2: stat tiles hard-impact reveal, on first scroll into view --- */
.stat-drop-pending .stat {
  opacity: 0;
  transform: translateY(-40px);
  transition: opacity 0.35s ease-out,
              transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); /* spring/overshoot, not linear or ease-in-out */
}
.stat-drop-pending .stat:nth-child(1) { transition-delay: 0s; }
.stat-drop-pending .stat:nth-child(2) { transition-delay: 0.13s; }
.stat-drop-pending .stat:nth-child(3) { transition-delay: 0.26s; }
.stat-drop-pending .stat:nth-child(4) { transition-delay: 0.39s; }

.stat-drop-pending.stat-drop-in .stat {
  opacity: 1;
  transform: translateY(0);
}

/* Belt-and-braces: even if JS still added the pending class, force full
   visibility with no motion under reduced-motion (the sitewide `* {
   transition: none !important; }` rule above already kills the
   transition; this also guarantees the end opacity/transform values). */
@media (prefers-reduced-motion: reduce) {
  .hero-anim-pending .page-hero-inner h1,
  .hero-anim-pending .page-hero-inner p,
  .hero-anim-pending .page-hero-inner .hero-quick-actions,
  .hero-anim-pending .page-hero-inner .hero-btns,
  .stat-drop-pending .stat,
  .reveal-pending {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}
/* ===== end homepage load-in effects ===== */

/* =====================================================================
   Projects page (projects.html) — jump index, per-project sections, and
   the coverflow carousel ported from previews/project-coverflow-demo.html.
   ===================================================================== */

/* Jump index: a wrapping strip of project-name chips linking to each
   section's anchor further down the page. Titles are derived from each
   photo's alt text (see scripts/build_projects_data.py) since the source
   data has no short/unique project-name field — chips truncate long titles
   with an ellipsis and keep the full text in the `title` attribute. */
.project-jump { display: flex; flex-wrap: wrap; gap: 10px; }
.project-jump-chip {
  display: inline-block; max-width: 240px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; border: 1px solid rgba(200,200,200,0.12); border-radius: 2px;
  padding: 8px 16px; font-size: 14px; font-weight: 600; letter-spacing: 0.3px;
  color: var(--chrome-dim); transition: color 0.2s, border-color 0.2s;
}
.project-jump-chip:hover, .project-jump-chip:focus-visible { color: var(--chrome-bright); border-color: var(--border-bright); }

/* Fade + rise reveal, reused per-section on scroll into view. Same
   transform/timing as the homepage hero's .hero-anim-pending load-in
   effect above — only the trigger differs (IntersectionObserver per
   section here, vs. once on page load there). See main.js. */
.reveal-pending {
  opacity: 0; transform: translateY(15px);
  transition: opacity 0.75s cubic-bezier(0.22, 0.61, 0.36, 1),
              transform 0.75s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.reveal-pending.reveal-in { opacity: 1; transform: translateY(0); }

.project-section { padding: 56px 0; border-bottom: 1px solid var(--border); scroll-margin-top: 96px; }
.project-section:last-child { border-bottom: none; }
.project-section-header { text-align: center; margin-bottom: 32px; }
.project-section-header .service-tag { margin-bottom: 14px; }
.project-desc {
  color: var(--body-text); font-size: 19px; line-height: 1.8;
  max-width: 620px; margin: 36px auto 0; text-align: center;
}

/* Fallback layout for projects with fewer than 3 photos — a plain
   single/dual image row, no coverflow mechanics. */
.project-fallback-images { display: flex; justify-content: center; gap: 20px; flex-wrap: wrap; }
.project-fallback-images .project-photo-frame {
  width: 100%; max-width: 480px; aspect-ratio: 4/3; border-radius: 6px; overflow: hidden;
  border: 1px solid var(--border-bright); background: var(--black-card);
}
.project-fallback-images.is-single .project-photo-frame { max-width: 620px; }
.project-photo-frame img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Coverflow carousel — ported from previews/project-coverflow-demo.html.
   See that file's own comments for why the transform/wheel/lock design
   looks the way it does; behaviour here is unchanged, only scoped to work
   as one of many instances on the same page (class-based lookups within
   each .coverflow root, not global ids — see main.js). */
.coverflow { position: relative; display: flex; align-items: center; justify-content: center; gap: 18px; padding: 20px 0; }
.cf-stage { position: relative; width: 476px; height: 357px; perspective: 1400px; }
.cf-photo {
  position: absolute; top: 0; left: 0; width: 476px; height: 357px;
  transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1), opacity 0.5s ease;
  transform-style: preserve-3d; cursor: pointer;
}
.cf-photo[data-pos="center"] { transform: translateX(0) translateZ(0) rotateY(0deg) scale(1); opacity: 1; z-index: 3; cursor: default; }
.cf-photo[data-pos="left"] { transform: translateX(-72%) translateZ(-140px) rotateY(25deg) scale(0.78); opacity: 0.5; z-index: 2; }
.cf-photo[data-pos="right"] { transform: translateX(72%) translateZ(-140px) rotateY(-25deg) scale(0.78); opacity: 0.5; z-index: 2; }
.cf-photo-frame { width: 100%; height: 100%; border-radius: 4px; overflow: hidden; border: 1px solid var(--border); background: var(--black-card); }
.cf-photo[data-pos="center"] .cf-photo-frame { border-color: var(--border-bright); }
.cf-photo-frame img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Placeholder photo slot (no real image) — used by the concept-demo project
   section until real photo groupings are confirmed. */
.cf-photo-inner {
  width: 100%; height: 100%; border: 1px dashed var(--border-bright); border-radius: 4px;
  background: var(--black-card);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
}
.cf-photo[data-pos="center"] .cf-photo-inner { border-style: solid; border-color: var(--border); }
.cf-photo-tag {
  display: inline-block; font-size: 13px; font-weight: 700; letter-spacing: 2px;
  text-transform: uppercase; color: var(--chrome-dark); border: 1px solid var(--border-bright);
  padding: 4px 10px; border-radius: 2px;
}
.cf-photo-inner span.cf-photo-label {
  font-family: 'Barlow Condensed', sans-serif; font-weight: 700; font-size: 18px;
  text-transform: uppercase; color: var(--chrome-dim); letter-spacing: 1px;
}

.cf-arrow {
  position: relative; z-index: 5; background: rgba(10,10,10,0.7); backdrop-filter: blur(6px);
  border: 1px solid rgba(200,200,200,0.12); color: var(--chrome-dim);
  width: 44px; height: 44px; border-radius: 2px; flex-shrink: 0;
  font-size: 22px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: color 0.2s, border-color 0.2s;
}
.cf-arrow:hover { color: var(--chrome-bright); border-color: var(--border-bright); }
.cf-sr-status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Narrow screens: drop the 3D wheel for a plain slide/crossfade single-photo
   view — see previews/project-coverflow-demo.html for the reasoning (the
   tilted side photos need horizontal room this width doesn't have). */
@media (max-width: 820px) {
  .coverflow { gap: 10px; }
  /* The off-canvas left/right slides below are translated a full stage-width
     to either side (opacity:0, pointer-events:none) so the crossfade has
     somewhere to animate from/to. Without clipping here, those slides still
     extend .cf-stage's scrollable overflow area even though nothing is
     visible, which is what let the page itself become horizontally
     draggable/rubber-banding on real mobile browsers. */
  .cf-stage { width: 100%; max-width: 320px; height: 240px; perspective: none; overflow: hidden; }
  .cf-photo { width: 100%; height: 100%; }
  .cf-photo[data-pos="center"] { transform: translateX(0) scale(1); opacity: 1; z-index: 3; }
  .cf-photo[data-pos="left"] { transform: translateX(-100%) scale(1); opacity: 0; z-index: 1; pointer-events: none; }
  .cf-photo[data-pos="right"] { transform: translateX(100%) scale(1); opacity: 0; z-index: 1; pointer-events: none; }
  .cf-arrow { width: 38px; height: 38px; font-size: 19px; }
}
/* ===== end projects page ===== */
