/* =============================================================
   Jampacked Services LLC — Brand stylesheet
   Design system: colors taken directly from the company logo,
   logo red #AC0D1F, black #000000, white #FFFFFF.
   NOTE: the token names 'navy' and 'copper' are kept for stability
   (Tailwind classes across all pages reference them). 'navy' now
   carries the logo black, 'copper' carries the logo red.
   Tailwind (via CDN) handles layout utilities; this file holds
   brand tokens, component styles, type, and motion.
   ============================================================= */

:root {
  /* --- Brand palette --- */
  --navy:        #121212;  /* logo black, main dark surfaces   */
  --navy-deep:   #000000;  /* logo black, deepest surfaces     */
  --navy-soft:   #2E2E2E;  /* lifted black, hover states       */
  --copper:      #AC0D1F;  /* logo red, CTAs and accents       */
  --copper-dark: #8A0A18;  /* logo red, hover                  */
  --copper-soft: #FBE8EA;  /* logo red tint, chips and avatars */
  --red-display: #C8102E;  /* logo red, big headlines on black */
  --red-light:   #EF3B4F;  /* logo red, small text on black    */
  --bg:          #F7F7F7;  /* near white page background       */
  --card:        #FFFFFF;  /* logo white, cards                */
  --line:        #E5E5E5;  /* hairline borders                 */
  --ink:         #121212;  /* logo black, body text            */
  --slate:       #5A5A5A;  /* muted secondary text             */
  --slate-light: #8C8C8C;  /* captions                         */

  /* --- Type --- */
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body:    "Inter", system-ui, sans-serif;

  /* --- Effects --- */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
  --shadow-md: 0 10px 30px -12px rgba(0, 0, 0, 0.14);
  --shadow-lg: 0 30px 60px -20px rgba(0, 0, 0, 0.22);
  --radius:    16px;
  --ease:      cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- Base ---------- */
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, .font-display {
  font-family: var(--font-display);
  letter-spacing: -0.015em;
  font-optical-sizing: auto;
}
body { font-optical-sizing: auto; }

/* Balanced, tighter headline wrapping */
.text-balance { text-wrap: balance; }

/* ---------- Eyebrow label ---------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--copper-dark);
}
.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 2px;
  background: var(--copper);
  border-radius: 2px;
}
.eyebrow--light { color: var(--red-light); }
.eyebrow--center::before { display: none; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.98rem;
  line-height: 1;
  padding: 0.95rem 1.6rem;
  border-radius: 12px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: transform 0.25s var(--ease), background 0.25s var(--ease),
              box-shadow 0.25s var(--ease), color 0.2s var(--ease);
  white-space: nowrap;
}
.btn:focus-visible { outline: 3px solid var(--copper); outline-offset: 3px; }
.btn svg { flex-shrink: 0; }

.btn-primary { background: var(--copper); color: #fff; box-shadow: 0 8px 20px -8px rgba(172, 13, 31, 0.45); }
.btn-primary:hover { background: var(--copper-dark); transform: translateY(-2px); box-shadow: 0 14px 26px -10px rgba(172, 13, 31, 0.55); }

.btn-navy { background: var(--navy); color: #fff; }
.btn-navy:hover { background: var(--navy-soft); transform: translateY(-2px); }

.btn-ghost { background: transparent; color: var(--navy); border-color: rgba(0,0,0,0.22); }
.btn-ghost:hover { border-color: var(--navy); background: rgba(0,0,0,0.05); transform: translateY(-2px); }

.btn-white { background: #fff; color: var(--navy); }
.btn-white:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }

.btn-outline-light { background: transparent; color: #fff; border-color: rgba(255,255,255,0.4); }
.btn-outline-light:hover { border-color: #fff; background: rgba(255,255,255,0.08); transform: translateY(-2px); }

/* ---------- Cards ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.card-hover:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }

/* Icon chip */
.icon-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 12px;
  background: var(--copper-soft);
  color: var(--copper-dark);
}

/* ---------- Header ---------- */
.site-header {
  transition: background 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
.site-header.scrolled {
  background: rgba(247, 245, 242, 0.9);
  backdrop-filter: saturate(180%) blur(12px);
  box-shadow: var(--shadow-sm);
  border-bottom-color: var(--line);
}
.nav-link { position: relative; color: var(--navy); font-weight: 500; transition: color 0.2s; }
.nav-link::after {
  content: ""; position: absolute; left: 0; bottom: -4px; height: 2px; width: 0;
  background: var(--copper); transition: width 0.28s var(--ease);
}
.nav-link:hover { color: var(--copper-dark); }
.nav-link:hover::after,
.nav-link[aria-current="page"]::after { width: 100%; }
.nav-link[aria-current="page"] { color: var(--copper-dark); }

/* Header sitting over a dark hero image (home page): light text until scrolled */
.site-header.over-hero:not(.scrolled) .nav-link,
.site-header.over-hero:not(.scrolled) .logo-name,
.site-header.over-hero:not(.scrolled) [data-nav-toggle] { color: #fff; }
.site-header.over-hero:not(.scrolled) .logo-name .text-copper-dark { color: var(--red-light); }
.site-header.over-hero:not(.scrolled) .logo-sub { color: rgba(255,255,255,0.72); }
.site-header.over-hero:not(.scrolled) .nav-link[aria-current="page"] { color: var(--red-light); }
.site-header.over-hero:not(.scrolled) .nav-link::after { background: var(--red-light); }
.site-header.over-hero:not(.scrolled) .logo-chip { background: rgba(255,255,255,0.12); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.25); }
.site-header.over-hero:not(.scrolled) .btn-ghost { color: #fff; border-color: rgba(255,255,255,0.4); }
.site-header.over-hero:not(.scrolled) .btn-ghost:hover { border-color: #fff; background: rgba(255,255,255,0.08); }

/* ---------- Hero ---------- */
.hero-overlay {
  background:
    radial-gradient(120% 90% at 50% 45%, rgba(0,0,0,0.45) 0%, rgba(0,0,0,0.82) 100%),
    linear-gradient(180deg, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.45) 40%, rgba(0,0,0,0.8) 100%);
}

/* Thin animated top rule under header on hero */
.rule-copper { height: 3px; background: linear-gradient(90deg, var(--copper) 0%, var(--red-light) 50%, var(--copper) 100%); }

/* The logo red is deep, so as small text on black it falls below the
   accessible contrast threshold. On dark surfaces, lift it to --red-light. */
footer .text-copper,
.bg-navy .text-copper,
.bg-navy-deep .text-copper { color: var(--red-light); }
footer .hover\:text-copper:hover,
.bg-navy .hover\:text-copper:hover,
.bg-navy-deep .hover\:text-copper:hover { color: var(--red-light); }

.bg-navy .text-copper:is(h1 *, h2 *),
.bg-navy-deep .text-copper:is(h1 *, h2 *) { color: var(--red-display); }

/* Comfortable tap targets on phones (WCAG 2.2 target size). */
footer ul a,
footer ul button { display: inline-flex; align-items: center; min-height: 36px; }
.tap-link { display: inline-flex; align-items: center; min-height: 40px; }

/* 24 hour emergency badge in the hero */
.emergency-pill {
  display: inline-flex; align-items: center; gap: 0.65rem;
  padding: 0.8rem 1.5rem; border-radius: 999px;
  background: rgba(172, 13, 31, 0.22);
  border: 1px solid rgba(239, 59, 79, 0.5);
  color: #fff; font-weight: 700; font-size: 1.02rem; letter-spacing: 0.01em;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease);
}
.emergency-pill:hover { background: rgba(172, 13, 31, 0.38); border-color: var(--red-light); }
.emergency-pill:focus-visible { outline: 3px solid var(--red-light); outline-offset: 3px; }
/* Rings are scaling pseudo elements, not animated box-shadows. A box-shadow
   animation repaints every frame, which is what made phones stutter. */
@keyframes pulse-ring-scale {
  0%   { transform: scale(1); opacity: 0.7; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}
.pulse-dot {
  position: relative;
  width: 9px; height: 9px; border-radius: 50%; background: var(--red-light); flex-shrink: 0;
}
.pulse-dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: var(--red-light);
  animation: pulse-ring-scale 1.8s ease-out infinite;
}

@media (prefers-reduced-motion: reduce) { .pulse-dot { animation: none; } }

/* Long form text pages (privacy policy) */
.legal { color: var(--slate); line-height: 1.75; }
.legal .legal-lead { font-size: 1.15rem; color: var(--ink); }
.legal h2 {
  font-family: var(--font-display); color: var(--ink);
  font-size: clamp(1.3rem, 2.6vw, 1.6rem); font-weight: 700;
  margin-top: 2.5rem; margin-bottom: 0.75rem;
}
.legal p { margin-bottom: 1rem; }
.legal ul { margin: 0 0 1rem 1.15rem; list-style: disc; }
.legal li { margin-bottom: 0.4rem; }
.legal strong { color: var(--ink); }
.legal a { color: var(--copper-dark); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.legal a:hover { color: var(--copper); }

/* Offer chips that sit beside the emergency badge in the hero */
.offer-pill {
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.8rem 1.5rem; border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: #fff; font-weight: 600; font-size: 1.02rem;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease);
}
.offer-pill:hover { background: rgba(255,255,255,0.16); border-color: rgba(255,255,255,0.45); }
.offer-pill:focus-visible { outline: 3px solid var(--red-light); outline-offset: 3px; }
.offer-pill__value { font-weight: 800; font-size: 1.12rem; color: var(--red-light); }

/* Oversized hero call to action buttons */
.btn-hero {
  font-size: 1.12rem;
  padding: 1.15rem 2.4rem;
  border-radius: 14px;
}
@media (max-width: 639px) { .btn-hero { width: 100%; } }

/* Credential badges sitting in the hero */
.cred-badge {
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.5rem 0.95rem; border-radius: 10px;
  background: rgba(255,255,255,0.1);
  border: 1px solid rgba(255,255,255,0.2);
}
@media (min-width: 1024px) { .cred-badge { backdrop-filter: blur(4px); } }
.cred-badge--seal { padding: 0.35rem 0.5rem; background: rgba(255,255,255,0.95); border-color: rgba(255,255,255,0.95); }
.cred-badge--seal:hover { background: #fff; }
.cred-badge__text {
  display: inline-flex; align-items: center; gap: 0.45rem;
  color: #fff; font-size: 0.9rem; font-weight: 600; white-space: nowrap;
}
.cred-badge__text svg { color: var(--red-light); }

/* Footer social links */
.social-link {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 10px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.14);
  color: rgba(255,255,255,0.8);
  transition: background 0.2s var(--ease), color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.social-link--sm { width: 32px; height: 32px; border-radius: 8px; }

/* Brand colours. Each platform keeps its own colour so visitors recognise it
   instantly. The two brands whose colour is black (X and TikTok) get a light
   border, otherwise they disappear against the dark hero and footer. */
.social-link[data-social="facebook"]  { background: #1877F2; border-color: #1877F2; color: #fff; }
.social-link[data-social="instagram"] { background: linear-gradient(45deg, #F58529 5%, #DD2A7B 45%, #8134AF 70%, #515BD4 100%); border-color: transparent; color: #fff; }
.social-link[data-social="tiktok"]    { background: #010101; border-color: rgba(255,255,255,0.45); color: #fff; }
.social-link[data-social="youtube"]   { background: #FF0000; border-color: #FF0000; color: #fff; }
.social-link[data-social="x"]         { background: #000; border-color: rgba(255,255,255,0.45); color: #fff; }
.social-link[data-social="linkedin"]  { background: #0A66C2; border-color: #0A66C2; color: #fff; }
.social-link[data-social="nextdoor"]  { background: #8ED500; border-color: #8ED500; color: #111; }

.social-link:hover { filter: brightness(1.15); transform: translateY(-2px); }
.social-link { transition: filter 0.2s var(--ease), transform 0.2s var(--ease); }
@media (prefers-reduced-motion: reduce) { .social-link:hover { transform: none; } }
.social-link:focus-visible { outline: 3px solid var(--red-light); outline-offset: 3px; }

/* ---------- Hero motion ----------
   Three separate movements, deliberately slow so it reads as cinematic
   rather than busy: the photo drifts in a long zoom, the content fades
   up in sequence on load, and the photo parallaxes on scroll (js).
   Every one of them is switched off for prefers-reduced-motion. */

.hero-media__img {
  width: 100%; height: 100%;
  object-fit: cover;
  transform-origin: 58% 45%;
}
/* A full screen image compositing forever is fine on a desktop, but not worth
   the battery or the jank on a phone. */
@media (min-width: 1024px) {
  .hero-media__img {
    animation: hero-drift 34s ease-in-out infinite alternate;
    will-change: transform;
  }
  .hero-media__img.is-offscreen { animation-play-state: paused; }
}
@keyframes hero-drift {
  from { transform: scale(1.02); }
  to   { transform: scale(1.11); }
}

/* Staggered entrance. Each direct child of .hero-content comes in just
   after the one above it, so the eye is led down to the buttons. */
.hero-content > * {
  opacity: 0;
  animation: hero-enter-anim 0.85s var(--ease) forwards;
}
@keyframes hero-enter-anim {
  from { opacity: 0; transform: translateY(20px); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
.hero-content > *:nth-child(1) { animation-delay: 0.10s; }
.hero-content > *:nth-child(2) { animation-delay: 0.22s; }
.hero-content > *:nth-child(3) { animation-delay: 0.34s; }
.hero-content > *:nth-child(4) { animation-delay: 0.46s; }
.hero-content > *:nth-child(5) { animation-delay: 0.58s; }
.hero-content > *:nth-child(6) { animation-delay: 0.70s; }
.hero-content > *:nth-child(7) { animation-delay: 0.82s; }
.hero-content > *:nth-child(8) { animation-delay: 0.94s; }

/* Scroll cue */
.hero-cue {
  position: absolute; left: 50%; bottom: clamp(16px, 4vh, 34px);
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  color: rgba(255,255,255,0.6);
  font-size: 0.68rem; font-weight: 700;
  letter-spacing: 0.3em; text-transform: uppercase;
  pointer-events: none;
  opacity: 0;
  animation: hero-enter-anim 0.8s var(--ease) 1.5s forwards;
  transition: opacity 0.4s var(--ease);
}
.hero-cue svg { animation: hero-cue-bounce 1.8s ease-in-out infinite; }
@keyframes hero-cue-bounce {
  0%, 100% { transform: translateY(0); opacity: 0.55; }
  50%      { transform: translateY(5px); opacity: 1; }
}
body.scrolled-past-top .hero-cue { opacity: 0 !important; }

@media (prefers-reduced-motion: reduce) {
  .hero-media__img { animation: none; transform: scale(1.04); }
  .hero-content > *, .hero-cue { animation: none; opacity: 1; filter: none; transform: none; }
  .hero-cue svg { animation: none; }
}

/* ---------- Stars ---------- */
.stars { display: inline-flex; gap: 2px; color: #E8A94B; }

/* ---------- Reviews marquee (sideways auto scroll) ---------- */
.marquee {
  position: relative;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}
.marquee-track {
  display: flex;
  gap: 1.5rem;
  width: max-content;
  animation: marquee-scroll 52s linear infinite;
  will-change: transform;
}
/* Pause when the visitor hovers or focuses a card, so they can read it */
.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track,
.marquee-track.is-offscreen { animation-play-state: paused; }
.review-card { width: 330px; flex: 0 0 auto; }
@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .marquee-track { animation: none; }
}

/* ---------- Section rhythm ---------- */
.section { padding-block: clamp(4rem, 8vw, 7rem); }

/* ---------- Reveal on scroll ---------- */
/* Matches the hero entrance: rise, sharpen, fade in. Sections stagger
   automatically, see the cascade logic in js/main.js. */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.85s var(--ease), transform 0.85s var(--ease);
}
.reveal.in { opacity: 1; transform: none; }

/* Blur is the costly part of the entrance and phones feel it across dozens of
   elements, so desktop gets the full treatment and phones get rise and fade. */
@media (min-width: 1024px) {
  .reveal {
    filter: blur(6px);
    transition: opacity 0.85s var(--ease), transform 0.85s var(--ease), filter 0.85s var(--ease);
  }
  .reveal.in { filter: blur(0); }
}
.reveal[data-delay="1"] { transition-delay: 0.09s; }
.reveal[data-delay="2"] { transition-delay: 0.18s; }
.reveal[data-delay="3"] { transition-delay: 0.27s; }

/* Photos settle out of a slight push in, echoing the hero drift. Run as a
   one shot animation rather than a transition so the gallery hover zoom
   still works normally once it has finished. */
@media (min-width: 1024px) {
  .reveal.in .photo { animation: photo-settle 1.3s var(--ease); }
}
@keyframes photo-settle {
  from { transform: scale(1.07); }
  to   { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
  .reveal.in .photo { animation: none; }
  .btn:hover, .card-hover:hover { transform: none !important; }
}

/* ---------- Placeholder flag (dev-visible) ---------- */
/* Anything wrapped in .placeholder-flag carries a small badge so nothing
   fake is mistaken for confirmed content before it's replaced. */
.placeholder-flag { position: relative; }
.placeholder-flag::before {
  content: "PLACEHOLDER";
  position: absolute; top: 8px; right: 8px; z-index: 5;
  font: 700 0.6rem/1 var(--font-body);
  letter-spacing: 0.08em;
  background: #B4322B; color: #fff;
  padding: 4px 7px; border-radius: 5px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.25);
  pointer-events: none;
}

/* ---------- Modal ---------- */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(0, 0, 0, 0.62);
  backdrop-filter: blur(4px);
  opacity: 0; visibility: hidden;
  transition: opacity 0.3s var(--ease), visibility 0.3s var(--ease);
}
.modal-backdrop.open { opacity: 1; visibility: visible; }
.modal-panel {
  transform: translateY(16px) scale(0.98);
  transition: transform 0.35s var(--ease);
}
.modal-backdrop.open .modal-panel { transform: none; }

/* ---------- Forms ---------- */
.field-label { font-weight: 600; font-size: 0.86rem; color: var(--navy); margin-bottom: 0.35rem; display: block; }
.field {
  width: 100%;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.8rem 0.95rem;
  font: inherit; font-size: 0.96rem; color: var(--ink);
  transition: border-color 0.2s, box-shadow 0.2s;
}
.field::placeholder { color: var(--slate-light); }
.field:focus { outline: none; border-color: var(--copper); box-shadow: 0 0 0 3px rgba(172,13,31,0.15); }
.field:user-invalid { border-color: #C0453B; box-shadow: 0 0 0 3px rgba(192,69,59,0.12); }
.field-error { color: #B4322B; font-size: 0.8rem; margin-top: 0.3rem; display: none; }
.field-error.show { display: block; }
textarea.field { resize: vertical; min-height: 120px; }

/* Floating mobile call button */
.floating-call {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 50;
  box-shadow: 0 12px 30px -8px rgba(172,13,31,0.55);
}
/* This button only exists on phones, so the old repainting shadow animation
   was costing exactly the devices it runs on. */
.floating-call::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: rgba(172, 13, 31, 0.45);
  animation: pulse-ring-scale 2.6s ease-out infinite;
  z-index: -1;
}
@media (prefers-reduced-motion: reduce) {
  .floating-call::after, .pulse-dot::after { animation: none; opacity: 0; }
}

/* Marquee-ish trust bar divider dots */
.dot-sep::before { content: "•"; color: var(--copper); margin: 0 0.75rem; }

/* Form status message */
.form-status { display: none; margin-top: 1rem; padding: 0.85rem 1rem; border-radius: 10px; font-size: 0.92rem; font-weight: 500; }
.form-status.loading { background: #EEF2F6; color: var(--slate); }
.form-status.error { background: #FBEAE8; color: #B4322B; border: 1px solid #F0C9C4; }
.form-status.success { background: #E7F3EC; color: #1F7A45; border: 1px solid #C4E4D0; }

/* Image frame — shows a clean navy fill until the real photo is dropped in,
   so a missing image never looks broken. */
.media { background: linear-gradient(135deg, var(--navy) 0%, var(--navy-soft) 100%); position: relative; }

/* Before/After image frame */
.gallery-img { border-radius: 14px; overflow: hidden; box-shadow: var(--shadow-md); }
.gallery-img img { transition: transform 0.6s var(--ease); }
.gallery-img:hover img { transform: scale(1.05); }
