/* ==========================================================================
   BarberGo — motion layer

   Loaded after site.css (and after rtl.css on Arabic pages), so every RTL
   override for motion lives HERE rather than in rtl.css — otherwise it would
   be overwritten by this file.

   Nothing in this file is allowed to hide content unless the `js` class is on
   <html>. That class is set by an inline script in <head>, so with JavaScript
   disabled the page renders exactly as it did before the motion layer existed.

   Everything animates transform and opacity only — both composited, neither
   triggers layout.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Scroll reveals

   motion.js stamps [data-reveal] onto a selector list, then removes the
   attribute again ~700ms after the element has arrived. That cleanup matters:
   once the attribute is gone the element carries no transform and no
   transition of its own, so the hover rules in §5 apply with ordinary
   specificity instead of fighting a leftover `transform: none`.
   -------------------------------------------------------------------------- */

.js [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
              transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.js [data-reveal].is-in {
  opacity: 1;
  transform: translateY(0);
}

/* Arming window. Elements are visible until motion.js tags them, so tagging
   would otherwise animate them from opacity 1 down to 0 over 600ms — an
   element sitting just below the fold would visibly fade OUT and back in if
   you reached it mid-transition. This class suppresses the transition for the
   single frame in which the tags are applied. */
.m-arming [data-reveal] { transition: none !important; }

/* Vertical only, in both directions. A horizontal reveal would enter from the
   wrong edge in Arabic, so the axis is never mirrored — it is simply not used. */

/* --------------------------------------------------------------------------
   2. Cut-line divider

   Injected by motion.js between landing sections. A dashed rule that a teal
   "cut" sweeps across while a small scissors rides the leading edge.
   -------------------------------------------------------------------------- */

.cut-line {
  position: relative;
  max-width: var(--wrap);
  margin-inline: auto;
  height: 30px;
  padding-inline: 24px;
  overflow: hidden;
}

.cut-line-track {
  position: absolute;
  inset-inline: 24px;
  top: 50%;
  height: 2px;
  margin-top: -1px;
}

/* The uncut remainder. */
.cut-line-dash {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(90deg, var(--outline) 0 8px, transparent 8px 16px);
  background-size: 16px 2px;
  opacity: 0.7;
}

/* The cut itself, sweeping from the inline start. */
.cut-line-solid {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--teal), var(--teal-mid));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1.1s cubic-bezier(0.33, 0.9, 0.35, 1);
}

/* Full-width rider: a percentage translate on a 100%-wide element equals the
   whole track, so the scissors can traverse it without JS measuring anything. */
.cut-line-rider {
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  transition: transform 1.1s cubic-bezier(0.33, 0.9, 0.35, 1);
}

/* The rider is 24px wide, so 28px tall — half of that centres it on the rule. */
.cut-line-rider .bg-sciss-svg {
  position: absolute;
  inset-inline-end: -14px;
  top: 50%;
  margin-top: -14px;
  transform: rotate(90deg);
}

.cut-line.is-in .cut-line-solid { transform: scaleX(1); }
.cut-line.is-in .cut-line-rider { transform: translateX(0); }

/* RTL: the cut runs right-to-left, so both the sweep origin and the rider's
   start edge flip. */
[dir="rtl"] .cut-line-solid { transform-origin: right center; }
[dir="rtl"] .cut-line-rider { transform: translateX(100%); }
[dir="rtl"] .cut-line.is-in .cut-line-rider { transform: translateX(0); }
[dir="rtl"] .cut-line-rider .bg-sciss-svg { transform: rotate(-90deg); }

/* --------------------------------------------------------------------------
   3. The scissors companion (landing page only — body.m-landing)

   Always pointer-events:none. It sits above the sticky nav (z-index 50) and
   below the skip link (z-index 100).
   -------------------------------------------------------------------------- */

.bg-sciss {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 60;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
  will-change: transform;
}

.bg-sciss.is-live { opacity: 1; }

/* Blades pivot about the rivet at (24,34) in the viewBox. --ba is the half
   angle: 0deg reads as closed, 12deg as resting-open. */
.bg-blade {
  transform-box: view-box;
  transform-origin: 24px 34px;
  transition: transform 0.13s cubic-bezier(0.3, 1.6, 0.5, 1);
}
.bg-blade-a { transform: rotate(calc(var(--ba, 12deg) * -1)); }
.bg-blade-b { transform: rotate(var(--ba, 12deg)); }

.bg-sciss-svg {
  overflow: visible;
  filter: drop-shadow(0 2px 3px rgba(11, 20, 20, 0.3));
}

/* Legibility halo — see the `limb()` note in motion.js. Teal-on-teal is
   invisible in the hero, so every stroke is underpainted in near-white. */
.bg-halo {
  stroke: rgba(255, 255, 255, 0.95);
  stroke-linecap: round;
  fill: none;
}

/* --------------------------------------------------------------------------
   4. Hair clippings — emitted on each snip.
   -------------------------------------------------------------------------- */

.bg-clip-layer {
  position: fixed;
  inset: 0;
  z-index: 59;
  pointer-events: none;
  overflow: hidden;
}

.bg-clip {
  position: absolute;
  width: 7px;
  height: 2px;
  border-radius: 2px;
  animation: bg-fall 0.75s cubic-bezier(0.4, 0.1, 0.8, 1) forwards;
}

@keyframes bg-fall {
  0%   { opacity: 1; transform: translate3d(0, 0, 0) rotate(var(--r, 0deg)); }
  100% { opacity: 0; transform: translate3d(var(--dx, 0px), var(--dy, 40px), 0) rotate(calc(var(--r, 0deg) + 220deg)); }
}

/* --------------------------------------------------------------------------
   5. Landing polish
   -------------------------------------------------------------------------- */

/* Sticky nav gains weight once you leave the top of the page. */
.nav {
  transition: box-shadow 0.25s ease, background-color 0.25s ease;
}
.nav-inner { transition: min-height 0.25s ease; }
.nav.is-stuck {
  box-shadow: 0 6px 24px rgba(30, 43, 43, 0.09);
  background: rgba(250, 247, 241, 0.93);
}
.nav.is-stuck .nav-inner { min-height: 62px; }

/* Hover feedback — the site previously had none on either card type. */
.card, .mode-card {
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--e2);
  border-color: var(--teal-pale);
}
.mode-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--e3);
}

/* Hero parallax. The phones and chips inside .hero-art already animate their
   own transform via the `floaty` keyframes in site.css, so parallax is applied
   to the CONTAINER and never to those children. */
.js .hero-art { transform: translate3d(0, var(--par, 0px), 0); }
.js .hero-copy { transform: translate3d(0, var(--par-copy, 0px), 0); }

/* site.css sets `transform: scale(0.92)` on .hero-art at this breakpoint.
   Restating it here keeps the scale while adding the parallax offset — without
   this line the rule above would silently drop the scale on tablets. */
@media (max-width: 900px) {
  .js .hero-art { transform: translate3d(0, var(--par, 0px), 0) scale(0.92); }
}

/* --------------------------------------------------------------------------
   6. Reduced motion

   site.css already collapses animation and transition durations globally, but
   that cannot stop a requestAnimationFrame loop — motion.js checks the same
   query and never starts one. These rules are the CSS half of that contract:
   nothing is left hidden or offset.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }
  .cut-line-solid { transform: scaleX(1); }
  .cut-line-rider { display: none; }
  .bg-sciss, .bg-clip-layer { display: none; }
  .card:hover, .mode-card:hover { transform: none; }
  .js .hero-art, .js .hero-copy { transform: none; }
}

/* Restate under reduced motion too, so the scale survives there as well.
   Written flat rather than as a nested @media — nested at-rules need CSS
   Nesting support, and this file must not depend on it. */
@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .js .hero-art { transform: scale(0.92); }
}

@media print {
  .bg-sciss, .bg-clip-layer, .cut-line { display: none; }
  .js [data-reveal] { opacity: 1; transform: none; }
}
