/* YCP effects layer (16.10, research/effects_2026-10-16/EFFECTS.md). Loaded after ycp-sitewide / ycp-motion; reuses the motion
 * tokens (--m-fast/base/slow/reveal, --m-ease*, --m-dir, --m-stagger) and adds no reveal of its own.
 * Rules:
 * - only transform / translate / scale / opacity / clip-path / background-position|size are animated; nothing animates layout;
 * - every effect sits inside (prefers-reduced-motion:no-preference); pointer effects also inside (hover:hover) and (pointer:fine);
 * - state that needs the script (--mx/--my, data-fx-*) exists only under html.fx-on, which assets/js/ycp-effects.js adds itself;
 * - glass rule: nothing here puts backdrop-filter, filter, opacity<1, mask, clip-path, will-change or view-transition-name on an
 *   ANCESTOR of .ycp-hdr-bar / .ycp-sticky-atc / .ycp-wa-float / .ycp-gtile-panel / .ycp-sc__p (those become Backdrop Roots and
 *   the blur stops seeing the page). Effects live on pseudo-elements, on injected children, or on leaves (img, buttons, links);
 * - never on the PDP gallery, cart or checkout forms. */

@property --fx-glow{syntax:'<number>';inherits:true;initial-value:0}

:root{
  --fx-spot-r:320px;                       /* spotlight radius */
  --fx-ind:86 91 131;                      /* #565B83 */
  --fx-lav:142 146 191;                    /* #8E92BF */
  --fx-hi:196 199 240;                     /* highlight on the border glow */
  --fx-mq-w:clamp(150px,17vw,220px);       /* brand tile width in the marquee */
  --fx-grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (prefers-reduced-motion:no-preference){

/* =============== 1-3. cards: pointer spotlight, gentle 3D tilt, gradient border glow (desktop pointers only) ===============
   product cards = V4 a.ycp-card with a .ycp-stage, and Woo loop cards inside a .products section (PDP "דגמים דומים"); photo tiles = home category tiles
   (.ycp-gtile), room tiles (a.e-con[data-m-zoom], set by ycp-motion.js), archive subcategory tiles (.ycp-sc__t).
   --mx/--my (px inside the card) and --fx-rx/--fx-ry (deg) are written by ycp-effects.js on the hovered card only. */
@media (hover:hover) and (pointer:fine){
  /* 1. spotlight: one pseudo-element per card, faded in on hover */
  html.fx-on :is(.elementor a.ycp-card:has(.ycp-stage),.woocommerce .products ul.products li.product,.elementor a.ycp-gtile,.elementor a.e-con[data-m-zoom],.ycp-sc__t)::after{
    content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;opacity:0;
    transition:opacity var(--m-base,.24s) var(--m-ease,ease);
    background:radial-gradient(var(--fx-spot-r) circle at var(--mx,50%) var(--my,30%),rgb(var(--fx-lav) / .16),rgb(var(--fx-ind) / .05) 45%,rgb(var(--fx-ind) / 0) 70%)}
  html.fx-on :is(.elementor a.ycp-card:has(.ycp-stage),.woocommerce .products ul.products li.product)::after{z-index:2}
  /* photo tiles: a soft light instead of indigo (indigo disappears on a dark photo); stays under the frosted panel (z-index 1) */
  html.fx-on :is(.elementor a.ycp-gtile,.elementor a.e-con[data-m-zoom],.ycp-sc__t)::after{z-index:0;
    background:radial-gradient(var(--fx-spot-r) circle at var(--mx,50%) var(--my,30%),rgb(232 233 255 / .20),rgb(var(--fx-lav) / .07) 38%,rgb(var(--fx-lav) / 0) 70%)}
  /* room tiles: text is in-flow (not positioned), so the light goes under it, above the motion zoom copy (::before, z -1) */
  html.fx-on .elementor a.e-con[data-m-zoom]:not(.ycp-gtile)::after{z-index:-1}
  html.fx-on :is(.elementor a.ycp-card:has(.ycp-stage),.woocommerce .products ul.products li.product,.elementor a.ycp-gtile,.elementor a.e-con[data-m-zoom],.ycp-sc__t):is(:hover,:focus-visible)::after{opacity:1}
  html.fx-on .woocommerce .products ul.products li.product{position:relative}
  /* Woo loop cards: written as `.woocommerce .products ul.products li.product` (0,6,3 with :hover) so they outrank
     ycp.css `.woocommerce .related.products ul.products li.product:hover` (0,6,2) without !important */

  /* 2. tilt: product cards only (never the PDP gallery, text blocks or photo tiles). Max 2.5deg, perspective 900px, the
        2px lift of the global class kept. The motion layer's transition on transform (240ms) smooths the follow and the return. */
  html.fx-on :is(.elementor a.ycp-card:has(.ycp-stage),.woocommerce .products ul.products li.product):hover{
    transform:perspective(900px) translate3d(0,-2px,0) rotateX(var(--fx-rx,0deg)) rotateY(var(--fx-ry,0deg))}

  /* 3. border glow: padding-box trick. White fill in the padding box, an indigo border-box underneath, and a light spot that
        follows the pointer and fades in with the registered --fx-glow. Without @property the spot appears at once; without the
        script it sits at the top centre; with no support for any of it the global class's plain indigo hover border remains. */
  html.fx-on :is(.elementor a.ycp-card:has(.ycp-stage),.woocommerce .products ul.products li.product){
    transition:border-color var(--m-fast,.15s) var(--m-ease,ease),box-shadow var(--m-base,.24s) var(--m-ease,ease),transform var(--m-base,.24s) var(--m-ease,ease),scale var(--m-fast,.15s) var(--m-ease,ease),--fx-glow var(--m-slow,.42s) var(--m-ease,ease)}
  html.fx-on :is(.elementor a.ycp-card:has(.ycp-stage),.woocommerce .products ul.products li.product):hover{
    --fx-glow:1;border-color:transparent;
    background:linear-gradient(#fff,#fff) padding-box,
      radial-gradient(220px circle at var(--mx,50%) var(--my,0%),rgb(var(--fx-hi) / var(--fx-glow)),rgb(var(--fx-hi) / 0) 70%) border-box,
      linear-gradient(#565B83,#565B83) border-box}
}

/* =============== 4. shine sweep across the filled primary buttons, once per hover / keyboard focus ===============
   data-fx-shine is set by the script on filled-indigo CTAs (hero "לחנות", add to cart, sticky add to cart, chooser CTAs,
   footer/article consult CTA). The sweep runs in the reading direction (right to left in RTL) and snaps back unseen on leave. */
html.fx-on [data-fx-shine]{position:relative;overflow:hidden;isolation:isolate}
html.fx-on [data-fx-shine]::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(calc(var(--m-dir,1) * 105deg),rgb(255 255 255 / 0) 30%,rgb(255 255 255 / .26) 50%,rgb(255 255 255 / 0) 70%);
  translate:calc(var(--m-dir,1) * -110%) 0;transition:none}
html.fx-on [data-fx-shine]:is(:hover,:focus-visible)::before{translate:calc(var(--m-dir,1) * 110%) 0;transition:translate 750ms var(--m-ease,ease)}
html.fx-on [data-fx-shine]:is(:disabled,[aria-disabled=true],.is-busy)::before{display:none}

/* =============== 5. underline drawn from right to left (inline-start) on quiet text links ===============
   Only links that carry no underline today: footer columns + legal row, mega-menu links, article breadcrumbs.
   Body-copy links keep their permanent underline (WCAG 1.4.1); high-contrast mode keeps its forced underline. */
@media (hover:hover){
  html:not(.ycp-hc) :is(.ycp-ftr-cols .elementor-nav-menu--main .elementor-item,.ycp-ftr-legal a,.ycp-mega-link a,.ycp-mega-all a,.ycp-mega-util-a a,.ycp-mega-util-b a,.ycp-crumbs a){
    background-image:linear-gradient(currentColor,currentColor);background-repeat:no-repeat;
    background-origin:content-box;background-clip:content-box;background-position:100% 100%;background-size:0% 1px;
    -webkit-box-decoration-break:clone;box-decoration-break:clone;
    transition:background-size var(--m-slow,.42s) var(--m-ease,ease),color var(--m-fast,.15s) var(--m-ease,ease)}
  [dir=ltr]:not(.ycp-hc) :is(.ycp-ftr-cols .elementor-nav-menu--main .elementor-item,.ycp-ftr-legal a,.ycp-mega-link a,.ycp-mega-all a,.ycp-mega-util-a a,.ycp-mega-util-b a,.ycp-crumbs a){background-position:0 100%}
  html:not(.ycp-hc) :is(.ycp-ftr-cols .elementor-nav-menu--main .elementor-item,.ycp-ftr-legal a,.ycp-mega-link a,.ycp-mega-all a,.ycp-mega-util-a a,.ycp-mega-util-b a,.ycp-crumbs a):is(:hover,:focus-visible){background-size:100% 1px}
  /* footer column items are flex boxes as wide as the column: the line follows the words, not the column */
  .ycp-ftr-cols .elementor-nav-menu--main .elementor-item{width:fit-content}
}

/* =============== 6. magnetic pull on the main CTAs (≤4px, desktop pointers). Uses the individual `translate` property, so it
   composes with the global class's transform lift and the motion layer's press `scale`. =============== */
@media (hover:hover) and (pointer:fine){
  html.fx-on a[data-fx-magnet]{translate:var(--fx-tx,0px) var(--fx-ty,0px);
    transition:background-color var(--m-fast,.15s) var(--m-ease,ease),border-color var(--m-fast,.15s) var(--m-ease,ease),color var(--m-fast,.15s) var(--m-ease,ease),box-shadow var(--m-base,.24s) var(--m-ease,ease),transform var(--m-base,.24s) var(--m-ease,ease),scale var(--m-fast,.15s) var(--m-ease,ease),translate var(--m-base,.24s) var(--m-ease-out,ease-out)}
}

/* =============== 7-8. aurora + film grain behind the dark hero and the dark bands ===============
   The script appends <span class="fx-aurora" aria-hidden="true"><i></i><i></i><i></i></span> to each dark host 400ms after load
   (after the LCP paint), marks the host data-fx-dark, fades the layer in once (.fx-in) and runs the drift only while the host is
   on screen (.fx-run, one IntersectionObserver). Hosts: home / room / brand page hero, product-archive head, article hero (.ycp-bh),
   footer concierge band (.ycp-ftr-band), article consult band (.ycp-cta-band). z-index -1 inside the host's own stacking context:
   above the host background and the hero's Ken Burns copy, below every piece of content. Blobs are radial gradients (soft by
   nature, no filter:blur) moved by transform only. Grain = one static feTurbulence tile at 5%. */
[data-fx-dark]{isolation:isolate}
.fx-aurora{position:absolute;inset:0;z-index:-1;overflow:hidden;border-radius:inherit;pointer-events:none;opacity:0;transition:opacity 1.4s var(--m-ease,ease)}
.fx-in>.fx-aurora{opacity:1}
.fx-aurora i{position:absolute;display:block;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(closest-side,rgb(var(--c) / var(--a)),rgb(var(--c) / calc(var(--a) * .45)) 45%,rgb(var(--c) / 0));
  animation:fx-drift-a 36s ease-in-out infinite alternate;animation-play-state:paused}
.fx-in.fx-run>.fx-aurora i{animation-play-state:running} /* drift only once lit and on screen */
.fx-aurora i:nth-child(1){--c:var(--fx-ind);--a:.55;width:58%;top:-38%;inset-inline-start:-12%}
.fx-aurora i:nth-child(2){--c:var(--fx-lav);--a:.26;width:46%;bottom:-48%;inset-inline-end:-8%;animation-name:fx-drift-b;animation-duration:31s}
.fx-aurora i:nth-child(3){--c:63 67 102;--a:.5;width:36%;top:12%;inset-inline-start:38%;animation-name:fx-drift-c;animation-duration:40s}
.fx-aurora::after{content:"";position:absolute;inset:0;background:var(--fx-grain) 0 0/180px 180px repeat;opacity:.05}
/* narrow bands: blobs sized by height would vanish; the band keeps the same drift with wider, flatter light */
:is(.ycp-ftr-band,.ycp-cta-band)>.fx-aurora i:nth-child(1){width:46%;top:-120%}
:is(.ycp-ftr-band,.ycp-cta-band)>.fx-aurora i:nth-child(2){width:40%;bottom:-150%}
:is(.ycp-ftr-band,.ycp-cta-band)>.fx-aurora i:nth-child(3){width:30%;top:-60%}
@keyframes fx-drift-a{from{transform:translate3d(0,0,0) scale(1)}to{transform:translate3d(calc(var(--m-dir,1) * 14%),12%,0) scale(1.14)}}
@keyframes fx-drift-b{from{transform:translate3d(0,0,0) scale(1.08)}to{transform:translate3d(calc(var(--m-dir,1) * -16%),-10%,0) scale(.94)}}
@keyframes fx-drift-c{from{transform:translate3d(0,0,0) scale(.92)}to{transform:translate3d(calc(var(--m-dir,1) * -10%),14%,0) scale(1.1)}}

/* =============== 9. clip-path image reveal for category + room images, riding the motion layer's reveal ===============
   No observer of its own: ycp-motion.js adds .is-in (and --m-i for the stagger) to the reveal item; these rules start the clip on
   the same frame. Category tile = the <img> leaf (the frosted panel next to it never gets a clipped ancestor). Room tile = the
   tile itself (no glass inside; the brands tile, which has a panel, is excluded with :not(.ycp-gtile)). `backwards` holds the
   inset during the stagger delay and returns to clip-path:none at the end. */
@keyframes fx-clip{from{clip-path:inset(var(--fx-ci,8%) round var(--fx-cr,14px))}to{clip-path:inset(0 round var(--fx-cr,14px))}}
html.m-on :is(.is-in[data-m-reveal] a.ycp-gtile,a.ycp-gtile.is-in[data-m-reveal])>img{--fx-cr:16px;animation:fx-clip 700ms var(--m-ease-out,ease-out) calc(var(--m-i,0) * var(--m-stagger,50ms)) backwards}
html.m-on .is-in[data-m-reveal] a.e-con[data-m-zoom]:not(.ycp-gtile){--fx-cr:22px;animation:fx-clip 700ms var(--m-ease-out,ease-out) calc(var(--m-i,0) * var(--m-stagger,50ms)) backwards}
html.m-on a.e-con[data-m-zoom]:not(.ycp-gtile)[data-m-reveal].is-in{--fx-cr:22px;
  animation:m-rise var(--m-reveal,600ms) var(--m-ease-out,ease-out) calc(var(--m-i,0) * var(--m-stagger,50ms)) both,fx-clip 700ms var(--m-ease-out,ease-out) calc(var(--m-i,0) * var(--m-stagger,50ms)) backwards}

/* =============== 10. brand-logo marquee on the home brands strip ===============
   Layout is CSS (first paint already has the one-row strip, so nothing jumps when the script builds the loop); the script moves
   the tiles into .fx-mq__track > .fx-mq__g, appends one aria-hidden copy (links tabindex -1), sets the loop time and data-fx-mq.
   Pauses on hover, on keyboard focus (and then becomes a plain scrollable row so the focused logo can scroll into view) and
   off screen. Without the script the row scrolls sideways; under reduced motion the original grid stays. */
body.home .ycp-section .ycp-container>.e-con:has(a[href*="/brand/"] img){
  display:flex!important;flex-wrap:nowrap!important;gap:0!important;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;padding-block:4px!important;
  -webkit-mask-image:linear-gradient(to right,transparent,#000 7%,#000 93%,transparent);mask-image:linear-gradient(to right,transparent,#000 7%,#000 93%,transparent)}
body.home .ycp-section .ycp-container>.e-con:has(a[href*="/brand/"] img)::-webkit-scrollbar{display:none}
body.home .ycp-section .ycp-container>.e-con:has(a[href*="/brand/"] img) a[href*="/brand/"]{flex:0 0 var(--fx-mq-w);width:var(--fx-mq-w)!important;min-width:0;margin-inline-end:16px!important}
[data-fx-mq]{overflow:hidden!important}
.fx-mq__track{display:flex;flex:none;width:max-content;animation:fx-mq var(--fx-mq-dur,60s) linear infinite;animation-play-state:paused}
.fx-mq__g{display:flex;flex:none}
[data-fx-mq].fx-run .fx-mq__track{animation-play-state:running}
[data-fx-mq]:is(:hover,:focus-within) .fx-mq__track{animation-play-state:paused}
[data-fx-mq].fx-mq--static{overflow-x:auto!important}
[data-fx-mq].fx-mq--static .fx-mq__track{animation:none}
@keyframes fx-mq{to{translate:calc(var(--m-dir,1) * -50%) 0}}

/* =============== 11. reading progress on articles: a 2px indigo line on the floating bar's bottom edge ===============
   CSS scroll-driven (compositor), on the bar's own ::after (a child of the glass surface, never an ancestor of it).
   Grows from the inline-start edge. Browsers without scroll timelines show nothing. */
@supports (animation-timeline:scroll()){
  body.single-post .ycp-hdr-bar::after{content:"";position:absolute;inset-inline:var(--ycp-bar-r,20px);bottom:-1px;height:2px;border-radius:2px;pointer-events:none;
    background:linear-gradient(to left,#565B83,#8E92BF);transform-origin:right center;scale:0 1;
    animation:fx-progress linear both;animation-timeline:scroll(root block)}
  [dir=ltr] body.single-post .ycp-hdr-bar::after{transform-origin:left center;background:linear-gradient(to right,#565B83,#8E92BF)}
  @keyframes fx-progress{to{scale:1 1}}
}

}

@media print{.fx-aurora,.ycp-hdr-bar::after{display:none!important}}
/* (17.10) the button-label hover guard found in phase 1 now lives in css/sitewide_v1.css (P1 17.10), not duplicated here */
