/* ProTech Innovations — shared motion library (Agent 18)
   Companion to assets/css/main.css. Load AFTER main.css.
   Scope: scroll reveal + shared micro-interactions ONLY.
   - Motion uses transform + opacity ONLY. Nothing here moves layout.
   - No webfonts, no external requests, no new text colours, no new claims.
   - The hidden reveal state applies ONLY under html.js-motion, a class
     added by assets/js/motion.js itself. With JS disabled, or if motion.js
     fails to load, .reveal elements render fully visible — content never
     depends on JS to be readable. See REPORT.md for the reasoning.
   - Demos, menu toggle, ?topic= note, and calculator behaviour are
     untouched: this file adds no rules for .demo steps, .menu-toggle,
     #request-form, or calculator elements. */

/* 1. Contract tokens not already defined in main.css.
   Values that overlap main.css are identical to it (verified):
   --radius-md 14px = main.css --radius; --radius-lg 18px = main.css
   --radius-lg. --shadow-sm/--shadow-md already exist in main.css and
   are NOT redeclared here. */
:root{
  --ink:#0B1220;
  --paper:#fff;
  --radius-sm:8px;
  --radius-md:14px;
  --radius-lg:18px;
  --shadow-lg:0 20px 48px rgba(11,18,32,.14);
  --ease-out:cubic-bezier(.22,.61,.36,1);
  --dur-fast:150ms;
  --dur-normal:300ms;
  --dur-slow:600ms;
}

/* 2. Scroll reveal (contract: hidden = opacity 0, translateY 16px).
   JS adds .is-visible via IntersectionObserver and unobserves the
   element (one-shot). Stagger is NOT done with CSS transition-delay —
   motion.js staggers by delaying the class addition (data-reveal-delay),
   so later hover transitions on the same element are never delayed. */
html.js-motion .reveal{
  opacity:0;
  transform:translateY(16px);
  transition:opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}
html.js-motion .reveal.is-visible{
  opacity:1;
  transform:none;
}

/* Optional directional variants. LTR-oriented: on RTL pages (ar/) prefer
   plain .reveal, because translateX does not mirror automatically.
   Use ONLY on inset content (cards, text blocks inside .wrap) — never on
   a full-bleed element, where a horizontal offset could overflow. */
html.js-motion .reveal-from-left{
  opacity:0;
  transform:translateX(-12px);
  transition:opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}
html.js-motion .reveal-from-right{
  opacity:0;
  transform:translateX(12px);
  transition:opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}
html.js-motion .reveal-scale{
  opacity:0;
  transform:scale(.97);
  transition:opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}
html.js-motion .reveal-from-left.is-visible,
html.js-motion .reveal-from-right.is-visible,
html.js-motion .reveal-scale.is-visible{
  opacity:1;
  transform:none;
}

/* Revealed elements that also carry a hover lift (cards, buttons):
   the reveal itself animates at --dur-slow, but while hovered the
   transition runs at --dur-fast so the lift feels immediate. On unhover
   it settles back at --dur-slow, which reads as a soft landing. */
html.js-motion .card.reveal.is-visible:hover,
html.js-motion .btn.reveal.is-visible:hover{
  transition-duration:var(--dur-fast);
}

/* 3. Micro-interactions. Each rule adds ONE property to what main.css
   already sets (later file, same specificity, per-property merge), so
   existing colours, shadows, and backgrounds are never overridden. */

/* Buttons: lift on hover, press on active. main.css keeps owning the
   background-colour and box-shadow changes. */
.btn{
  transition:background-color var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}
.btn:hover{transform:translateY(-1px);}
.btn:active{transform:translateY(1px) scale(.99);}

/* Cards: gentle lift on hover. main.css keeps owning the shadow change. */
.card{
  transition:box-shadow var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}
.card:hover{transform:translateY(-3px);}

/* Header nav links: animated underline bar (transform scaleX only).
   Nav links have no native underline, so this is purely additive.
   Excludes .btn (the nav call-to-action button) and the dropdown
   button (a <button>, not an <a>, so it is excluded automatically).
   Content links keep their native underline untouched (accessibility:
   underlines must stay recognisable as links). Footer links likewise
   keep main.css's native hover underline. */
nav.main a:not(.btn){position:relative;}
nav.main a:not(.btn)::after{
  content:"";
  position:absolute;
  left:12px;
  right:12px;
  bottom:6px;
  height:2px;
  border-radius:2px;
  background:var(--teal);
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform var(--dur-fast) var(--ease-out);
}
nav.main a:not(.btn):hover::after,
nav.main a:not(.btn):focus-visible::after{transform:scaleX(1);}
nav.main a:not(.btn):dir(rtl)::after{transform-origin:right center;}

/* 4. Smooth anchor behaviour (identical to main.css, repeated here so
   motion.css is self-contained if ever loaded without it). Anchor
   targets already carry scroll-margin-top in main.css for the sticky
   header, so smooth scrolling never hides a heading underneath it. */
html{scroll-behavior:smooth;}

/* 5. Reduced motion — MUST stay last in this file. Turns ALL motion
   off and renders content fully visible, per contract. main.css also
   forces *{transition:none!important} under reduced motion; this block
   additionally resets the transform/hover endpoints that transitions
   alone cannot reset. */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto;}
  html.js-motion .reveal,
  html.js-motion .reveal-from-left,
  html.js-motion .reveal-from-right,
  html.js-motion .reveal-scale{
    opacity:1;
    transform:none;
    transition:none;
  }
  .btn:hover,
  .btn:active,
  .card:hover{transform:none;}
  nav.main a:not(.btn)::after{display:none;}
}
