/* ============================================================================
   SHARED COMPONENT KIT — services-with-photos, review marquee, service-area
   radar, quote form. Written once so all five sites behave identically.

   Every colour comes from a variable. A site sets its own palette in its own
   styles.css and this file inherits it. Do not hard-code a colour in here.

     --k-bg        page/section ground (dark)
     --k-surface   raised card on that ground
     --k-line      hairline border
     --k-ink       primary text on --k-bg
     --k-ink-2     muted text on --k-bg
     --k-accent    brand colour
     --k-accent-2  brighter brand colour, used for highlights
     --k-ease      shared easing curve
   ========================================================================== */
:root{ --k-ease:cubic-bezier(.16,1,.3,1); }

/* an author display: rule beats the UA [hidden] rule, which silently breaks
   every .btn and grid that relies on the attribute */
[hidden]{display:none !important}

/* ---------- 1. SERVICES, each with a photo ------------------------------- */
.svc-wrap{display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:20px}
.svc{background:var(--k-surface); border:1px solid var(--k-line); border-radius:18px;
  overflow:hidden; display:flex; flex-direction:column;
  transition:transform .35s var(--k-ease), border-color .35s var(--k-ease)}
.svc:hover{transform:translateY(-4px); border-color:var(--k-accent)}
.svc-media{position:relative; aspect-ratio:4/3; overflow:hidden; background:var(--k-bg)}
.svc-media img{width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .6s var(--k-ease)}
.svc:hover .svc-media img{transform:scale(1.05)}
/* every stock photo says so, on the photo, always */
.svc-chip{position:absolute; left:10px; bottom:10px; z-index:2; padding:4px 10px;
  border-radius:999px; font-size:10.5px; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; background:rgba(8,10,14,.74); color:#fff;
  border:1px solid rgba(255,255,255,.24); backdrop-filter:none}
.svc-chip.is-real{background:var(--k-accent); border-color:var(--k-accent)}
.svc-body{padding:20px 20px 22px; display:flex; flex-direction:column; gap:8px; flex:1}
.svc-body i{font-size:24px; color:var(--k-accent-2)}
.svc-body h3{margin:0; font-size:18px; color:var(--k-ink)}
.svc-body p{margin:0; font-size:14.5px; line-height:1.62; color:var(--k-ink-2)}

/* ---------- 2. REVIEW MARQUEE -------------------------------------------- */
/* Two rows travelling in opposite directions. Each row holds its cards twice
   so translateX(-50%) lands exactly on the seam and the loop is invisible. */
.rv{position:relative; overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
.rv-row{display:flex; gap:16px; width:max-content; padding:8px 0}
.rv-row.a{animation:rv-left 46s linear infinite}
.rv-row.b{animation:rv-right 54s linear infinite}
@keyframes rv-left{from{transform:translate3d(0,0,0)} to{transform:translate3d(-50%,0,0)}}
@keyframes rv-right{from{transform:translate3d(-50%,0,0)} to{transform:translate3d(0,0,0)}}
.rv:hover .rv-row{animation-play-state:paused}
.rv-card{flex:none; width:330px; background:var(--k-surface); border:1px solid var(--k-line);
  border-radius:16px; padding:20px}
/* a real Google review is outlined in the brand colour; a sample is dashed.
   The difference must be visible without reading the chip. */
.rv-card.is-real{border-color:var(--k-accent); border-width:2px}
.rv-card.is-sample{border-style:dashed; opacity:.9}
.rv-head{display:flex; align-items:center; gap:11px; margin-bottom:11px}
.rv-av{width:38px; height:38px; border-radius:50%; flex:none; display:grid; place-items:center;
  font-weight:700; font-size:15px; color:#fff; background:var(--k-accent)}
.rv-who{flex:1; min-width:0}
.rv-who b{display:block; font-size:14.5px; color:var(--k-ink); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis}
.rv-who span{display:block; font-size:11.5px; color:var(--k-ink-2)}
.rv-tag{flex:none; padding:3px 9px; border-radius:999px; font-size:9.5px; font-weight:800;
  letter-spacing:.09em; text-transform:uppercase}
.rv-tag.real{background:var(--k-accent); color:#fff}
.rv-tag.sample{background:transparent; color:var(--k-ink-2); border:1px solid var(--k-line)}
.rv-stars{color:#f5a623; font-size:14px; letter-spacing:1px; margin-bottom:9px}
.rv-card p{margin:0; font-size:14px; line-height:1.65; color:var(--k-ink-2)}
.rv-src{display:block; margin-top:12px; padding-top:11px; border-top:1px solid var(--k-line);
  font-size:11px; color:var(--k-ink-2)}
.rv-card.is-real .rv-src{color:var(--k-accent-2); font-weight:600}

/* ---------- 3. SERVICE-AREA RADAR ---------------------------------------- */
.radar{position:relative; width:min(560px,100%); aspect-ratio:1; margin-inline:auto;
  --r-max:44%}
.radar-face{position:absolute; inset:0; border-radius:50%;
  background:radial-gradient(circle at 50% 50%,
    color-mix(in srgb,var(--k-accent) 16%,transparent), transparent 68%)}
.radar-ring{position:absolute; left:50%; top:50%; translate:-50% -50%; border-radius:50%;
  border:1px solid var(--k-line)}
.radar-ring.r1{width:36%; height:36%}
.radar-ring.r2{width:62%; height:62%}
.radar-ring.r3{width:88%; height:88%}
.radar-cross{position:absolute; left:50%; top:6%; bottom:6%; width:1px;
  background:var(--k-line); translate:-50% 0}
.radar-cross.h{left:6%; right:6%; top:50%; bottom:auto; width:auto; height:1px;
  translate:0 -50%}
/* the sweep is one conic gradient rotating; a pulse is a ring scaling out */
.radar-sweep{position:absolute; inset:0; border-radius:50%;
  background:conic-gradient(from 0deg,
    color-mix(in srgb,var(--k-accent-2) 42%,transparent) 0deg,
    transparent 46deg, transparent 360deg);
  animation:radar-spin 5.5s linear infinite; transform-origin:50% 50%}
@keyframes radar-spin{to{transform:rotate(360deg)}}
.radar-pulse{position:absolute; left:50%; top:50%; width:88%; height:88%; translate:-50% -50%;
  border-radius:50%; border:1px solid var(--k-accent-2); opacity:0;
  animation:radar-pulse 3.6s ease-out infinite}
.radar-pulse:nth-of-type(2){animation-delay:1.2s}
.radar-pulse:nth-of-type(3){animation-delay:2.4s}
@keyframes radar-pulse{
  0%{transform:scale(.12); opacity:0}
  14%{opacity:.75}
  100%{transform:scale(1); opacity:0}
}
.radar-core{position:absolute; left:50%; top:50%; translate:-50% -50%; z-index:4;
  padding:9px 16px; border-radius:999px; background:var(--k-accent); color:#fff;
  font-size:12.5px; font-weight:800; letter-spacing:.05em; white-space:nowrap;
  box-shadow:0 6px 22px -8px var(--k-accent)}
.radar-town{position:absolute; z-index:3; translate:-50% -50%; padding:5px 11px;
  border-radius:999px; font-size:11.5px; font-weight:600; white-space:nowrap;
  color:var(--k-ink-2); background:var(--k-surface); border:1px solid var(--k-line);
  transition:color .45s var(--k-ease), background .45s var(--k-ease),
             border-color .45s var(--k-ease), transform .45s var(--k-ease)}
.radar-town.lit{color:var(--k-ink); border-color:var(--k-accent-2);
  background:color-mix(in srgb,var(--k-accent) 26%,var(--k-surface));
  transform:translateZ(0) scale(1.07)}
.radar-town i{font-style:normal; opacity:.62; margin-left:5px; font-size:10px}
@media (max-width:560px){
  .radar{width:100%}
  .radar-town{font-size:9.5px; padding:4px 8px}
  .radar-town i{display:none}
  .radar-core{font-size:10.5px; padding:7px 12px}
}

/* ---------- 4. QUOTE FORM ------------------------------------------------- */
.qf{display:grid; gap:14px}
.qf-row{display:grid; grid-template-columns:1fr 1fr; gap:12px}
@media (max-width:620px){.qf-row{grid-template-columns:1fr}}
.qf-field{display:flex; flex-direction:column; gap:6px; min-width:0}
.qf-field label{font-size:11px; font-weight:700; letter-spacing:.09em; text-transform:uppercase;
  color:var(--k-ink-2)}
/* grid items default to min-width:auto, so a <select> refuses to shrink below
   its longest option and shoves the whole form past the viewport */
.qf-field input,.qf-field select,.qf-field textarea{width:100%; min-width:0; font:inherit;
  font-size:15.5px; padding:12px 13px; border-radius:11px; color:var(--k-ink);
  background:var(--k-bg); border:1px solid var(--k-line); appearance:none}
.qf-field textarea{resize:vertical}
.qf-field select{background-image:
    linear-gradient(45deg,transparent 50%,var(--k-ink-2) 50%),
    linear-gradient(135deg,var(--k-ink-2) 50%,transparent 50%);
  background-position:calc(100% - 19px) 21px,calc(100% - 14px) 21px;
  background-size:5px 5px,5px 5px; background-repeat:no-repeat; padding-right:38px}
.qf-field input:focus,.qf-field select:focus,.qf-field textarea:focus{
  border-color:var(--k-accent-2); outline:none}
.qf-note{font-size:11.5px; line-height:1.65; color:var(--k-ink-2); margin:2px 0 0}
.qf-done{text-align:center; padding:10px 0}
.qf-done h3{margin:0 0 8px; font-size:20px; color:var(--k-ink)}
.qf-done p{margin:0 0 16px; font-size:14.5px; color:var(--k-ink-2)}

/* ---------- reduced motion ----------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .rv-row,.radar-sweep,.radar-pulse{animation:none !important}
  .rv-row{transform:none !important}
  .radar-pulse{opacity:.28; transform:translate(-50%,-50%) scale(1)}
  .svc,.svc-media img{transition:none}
  /* with the sweep stopped, every town is simply shown lit */
  .radar-town{color:var(--k-ink); border-color:var(--k-accent-2)}
}
