/* Paint-chip conveyor wall (hero background) */
.paint-wall {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
  background: var(--canvas);
}

.chip-track {
  display: flex;
  width: max-content;
  padding: 20px 0;
}

.chip {
  width: 56px;
  height: 84px;
  margin-right: 8px;
  border-radius: 4px;
  flex-shrink: 0;
  box-shadow: 0 4px 10px rgba(0,0,0,0.35);
  position: relative;
  overflow: hidden;
}

.paint-wall::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--canvas) 0%, transparent 15%, transparent 85%, var(--canvas) 100%);
}

@media (prefers-reduced-motion: no-preference) {
  .chip-track { animation: chipScroll 30s linear infinite; }
}
@keyframes chipScroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* Metallic finish: animated sheen sweep, static gradient when motion is reduced */
.f-metallic {
  background-image: linear-gradient(120deg, transparent 30%, rgba(255,255,255,0.45) 48%, transparent 66%);
  background-size: 200% 100%;
}
@media (prefers-reduced-motion: no-preference) {
  .f-metallic { animation: shimmer 2.6s linear infinite; }
}
@keyframes shimmer {
  0%   { background-position: -60px 0; }
  100% { background-position: 120px 0; }
}

/* Color-wheel spinner (compact badge, not full-bleed) */
.color-wheel {
  position: relative;
  width: 140px;
  height: 140px;
  flex-shrink: 0;
}

.wheel-ring {
  position: relative;
  width: 100%;
  height: 100%;
}
@media (prefers-reduced-motion: no-preference) {
  .wheel-ring { animation: wheelSpin 26s linear infinite; }
}
@keyframes wheelSpin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.wheel-chip {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border-radius: 5px;
  box-shadow: 0 3px 8px rgba(0,0,0,0.4);
}

.color-match-section {
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}

/* Pastel color rotation for the Services page blocks, same 5 tones used
   for the paint chips and the "What We Do" cards. Uses :nth-of-type, not
   :nth-child -- the <h1> page heading is also a sibling of these <article>
   blocks, which would throw off :nth-child's count by one. This rule is
   placed BEFORE .wood-grain below so wood-grain's own background wins the
   cascade tie for the 2 blocks that carry both classes. */
.service-block:nth-of-type(5n+2) { background: #E3C79A; }
.service-block:nth-of-type(5n+3) { background: #C9D6D0; }
.service-block:nth-of-type(5n+4) { background: #D7C7B5; }
.service-block:nth-of-type(5n+5) { background: #E8D9E6; }

/* Wood-grain - ties to the real faux-wood-grain garage-door service.
   Light oak tones to match the pastel canvas, was dark brown when the
   site used a dark canvas. The soft radial highlight this used to add via
   its own ::before now comes from the universal metallic sheen below
   instead (an element can only have one ::before).

   Selector is `.service-block.wood-grain`, not just `.wood-grain`: the
   color-rotation rules above are `.service-block:nth-of-type(...)`, which
   has two selector components (higher specificity) versus a bare
   `.wood-grain`'s one -- a bare class would silently lose regardless of
   source order (confirmed via computed-style check: background-image
   came back "none" on both wood-grain blocks before this fix). Matching
   the specificity here makes it a real tie, which source order (this
   rule comes after) then correctly resolves in wood-grain's favor. */
.service-block.wood-grain {
  background-color: #E3C79A;
  background-image:
    repeating-linear-gradient(90deg,
      rgba(90,58,26,0.10) 0px, rgba(90,58,26,0.10) 2px,
      transparent 2px, transparent 6px),
    repeating-linear-gradient(90deg,
      rgba(255,255,255,0.15) 0px, rgba(255,255,255,0.15) 1px,
      transparent 1px, transparent 14px),
    linear-gradient(180deg, #EAD3A8, #D9B37F 60%, #E3C79A);
}
.wood-grain p {
  color: var(--paper);
}

/* Metallic shine, every service block including wood-grain -- mirrors how
   the real epoxy/roof-coating photos catch light, and reads as a lacquer
   sheen on the wood-grain blocks. */
.service-block::before {
  content: "";
  position: absolute;
  top: -50%;
  left: -60%;
  width: 40%;
  height: 200%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,0.55), transparent);
  transform: translateX(0%) rotate(20deg);
  z-index: 1;
}
@media (prefers-reduced-motion: no-preference) {
  .service-block::before { animation: glossSweep 3.2s ease-in-out infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .service-block::before { transform: translateX(250%) rotate(20deg); }
}
@keyframes glossSweep {
  0%   { transform: translateX(0%) rotate(20deg); }
  55%  { transform: translateX(475%) rotate(20deg); }
  100% { transform: translateX(475%) rotate(20deg); }
}

/* Native CSS scroll-reveal utility -- no JS, compositor-driven */
.reveal-up {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: no-preference) {
  .reveal-up {
    animation: revealFadeUp linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 30%;
  }
}
@keyframes revealFadeUp {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}
@supports not (animation-timeline: view()) {
  .reveal-up { opacity: 1; transform: none; animation: none; }
}

/* Before/after scroll-driven wipe -- epoxy-floor pair only, see spec */
.ba-wipe {
  view-timeline-name: --wipe-progress;
  view-timeline-axis: block;
}
.ba-wipe-frame {
  position: relative;
  border-radius: var(--radius-card-lg);
  overflow: hidden;
}
.ba-wipe-frame img { display: block; width: 100%; height: auto; }

.ba-wipe-before-mask {
  position: absolute;
  inset: 0;
  overflow: hidden;
  clip-path: inset(0 50% 0 0);
}
.ba-wipe-before-mask img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (prefers-reduced-motion: no-preference) {
  .ba-wipe-before-mask {
    animation: wipeProgress linear both;
    animation-timeline: --wipe-progress;
    animation-range: entry 10% cover 60%;
  }
}
@keyframes wipeProgress {
  from { clip-path: inset(0 0% 0 0); }
  to   { clip-path: inset(0 100% 0 0); }
}
@supports not (animation-timeline: view()) {
  .ba-wipe-before-mask { clip-path: inset(0 50% 0 0); animation: none; }
}

.ba-wipe-labels {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  color: var(--muted);
  font-weight: 600;
  font-size: 0.875rem;
}

/* "What We Do" interactive service cards: metallic-pastel tiles, a
   mouse-tracking glow (mirrors cliffindus.com's cursor-tracking highlight),
   and a soft scroll-reactive blob background behind the section. Requires
   src/assets/js/services-interactive.js -- this is the one place on the
   site with real client-side JS, added specifically for this effect. */
.blob-layer {
  position: absolute;
  inset: -60px;
  z-index: 0;
  filter: blur(50px);
  opacity: 0.55;
  pointer-events: none;
  will-change: transform;
}
.blob { position: absolute; border-radius: 50%; }
.blob-1 { width: 260px; height: 260px; background: var(--surface-card); top: -60px; left: -40px; }
.blob-2 { width: 300px; height: 300px; background: #C9D6D0; bottom: -80px; right: -60px; }
.blob-3 { width: 220px; height: 220px; background: #E8D9E6; top: 45%; left: 55%; }

@media (prefers-reduced-motion: reduce) {
  /* Static positions only -- the scroll-driven drift is JS, and JS itself
     already checks prefers-reduced-motion before wiring up the scroll
     listener (see services-interactive.js), but this rule guarantees no
     residual transform lingers if that check is ever bypassed. */
  .blob-layer { transform: none !important; }
}

/* Pastel color rotation, reusing the same 5 pastel tones from paintChips.js */
.service-card:nth-child(5n+2) { background: #E3C79A; }
.service-card:nth-child(5n+3) { background: #C9D6D0; }
.service-card:nth-child(5n+4) { background: #D7C7B5; }
.service-card:nth-child(5n+5) { background: #E8D9E6; }

/* Metallic sheen sweep, every card, same technique as .f-metallic */
.service-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background-image: linear-gradient(120deg, transparent 30%, rgba(255,255,255,0.6) 48%, transparent 66%);
  background-size: 220% 100%;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .service-card::before { animation: shimmer 3.4s linear infinite; }
}

/* Mouse-tracking glow -- --mx/--my/--glow are set by services-interactive.js */
.service-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,0.75), transparent 50%);
  opacity: var(--glow, 0);
  transition: opacity 0.15s ease;
  pointer-events: none;
}
