/* work.css — "Featured Work", laid out and animated like lusion.co's home section (SPEC-WORK-LUSION; overrides every
   earlier description of #work). Measured there at 1440 px and written in vw so the proportions hold at any width:
     section     light (the body paints it; the stage canvas shows through), gutters 5vw, 12 columns, gap 2vw
     header      title 8vw / 400 / .9 / −.02em · blurb .9vw caps / 1.4, 21vw wide (fills the measure), at the end side, on the title's baseline
     cards       6 of 12 columns (633.6 px), rows aligned, row gap 80 px (fixed); the list starts 8vh under the header
     media       100 % × 65 %, radius 15 px, no border / shadow
     tags        .9vw caps / 400 / 1.15, margin 1.35vw / .9vw
     title       3vw / 400, a 1em-high box (the 1.15 text line pulled up .2em, overflow clipped); every letter is a column of 4
                 stacked copies (the reveal rolls through them); an arrow (.8em, top .1em) waits outside the clip at the start
     end pill    12vh under the grid, centred: white, 1vw caps / 500, padding 1vw 1.5vw, dot at the start, arrow on hover
   Vertical rhythm is NOT all vw on Lusion: header → list 8vh, row gap 80 px, grid → pill 12vh (measured at 1440×700/900,
   1920×1080/1300). ≤ 700 px has its own values (the mobile block).
   Paired with js/work.js (DOM: reveal state, hover / the centred card on touch, letter columns, loops, Drago) and
   js/scenes/work.js (the WebGL planes on the stage canvas behind <main>). Hooks written by JS:
     .work-card[data-w]          pre | in — the reveal (replays: back to pre once fully out of view). Also on .work-foot.
     .work-card[data-from]       1 = entered from below, -1 = from above (the DOM-media wipe starts on that side).
     .work-card.is-hover         fine-pointer hover, Tab focus, or the card nearest the viewport centre on touch: the media
                                 goes live; on a fine pointer the arrow also slides in and the letters shift 1.5em.
     #work.is-touch              work.js's touch mode (coarse pointer or ≤ 700 px): the arrow + the 1.5em shift are the
                                 title's RESTING layout on every card (the arrow slides in with the reveal); is-hover then
                                 only drives the media (Lusion mobile: titles never move while scrolling).
     .work-card.was-hover        the card has been hovered at least once (arms the DOM defocus on the way back).
     .work-card.is-playing       hovered AND its loop has frames: the DOM <video> fades over the poster (fallback mode).
     .work-card.is-live          Drago's illustration is running (hover only; frozen at rest).
     .work-media[data-gl=ready][data-gl-tex]  a GL plane draws this media and has pixels: the DOM picture steps aside
                                 (the box keeps the layout + the anchor; the <video> keeps decoding — it is the texture).
     .work-title.is-rolled       work.js built the letter columns (.wt-roll); the plain .wt-text stays for readers.
     --i / --r on .wt-s          the letter's index from the start / from the end (--i: the reveal roll). Hover stagger as
                                 measured on lusion.co (per-frame CDP samples): on the way IN the END letters lead and the
                                 arrow trails; on the way BACK the arrow leads, then the FIRST letters. Both are counted
                                 on --r (the leave is anchored on the last letter). 4.5 ms per letter.
   Title hover timing (lusion.co, CDP frame samples, repeatable within 2 ms):
     in  = letters 360 ms cubic-bezier(.2,.5,.2,1), the LAST letter at 0 and every letter 4.5 ms later than the one after
           it (--r); the arrow 280 ms cubic-bezier(.3,.4,.1,1) after 100 ms (it trails the letters).
     out = the arrow 200 ms cubic-bezier(.85,.3,.7,1) after 45 ms (it leads home); letters 310 ms cubic-bezier(.9,.3,.55,1)
           (a short ease-in that accelerates home), the FIRST letter first: the last letter waits --wt-out-last (65 ms,
           20 ms behind the arrow) and each letter before it 4.5 ms less (65 ms − --r × 4.5 ms; Lusion anchors the leave
           on the last letter — a 7-letter title's first letter goes at 38 ms, a 20-letter one's at once).
   The arrow stays opaque: the title's clip hides it at rest, as on Lusion.
   --wt-hover-roll (default 0 = Lusion: the 4-deep stack rolls on the reveal only, the hover is a pure horizontal shift);
   1 also rolls one copy on hover. No hover zoom anywhere (Lusion: none measured; PLANE.hover 0 in js/work.js).
   Motion: transform / translate / scale / opacity / clip-path / filter only. No hex colours (tokens.css). */

#work{--w-gut:5vw;--w-gap:2vw;--w-rad:15px;--w-tags:max(11px,.9vw);--w-title:max(26px,3vw);--wt-slot:1.5em;--wt-hover-roll:0;--dx:1;
  --w-ease:cubic-bezier(.4,0,.1,1);--wt-stag:4.5ms;--wt-out-last:65ms;
  --wt-in:calc(360ms * var(--tempo)) cubic-bezier(.2,.5,.2,1);--wt-out:calc(310ms * var(--tempo)) cubic-bezier(.9,.3,.55,1);
  --wt-ar-in:calc(280ms * var(--tempo)) cubic-bezier(.3,.4,.1,1) 100ms;--wt-ar-out:calc(200ms * var(--tempo)) cubic-bezier(.85,.3,.7,1) 45ms}
[dir=rtl] #work{--dx:-1}
#work.work{background:transparent;color:var(--ink)}

/* ============================================================== header */
.work-head{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--w-gap);
  padding:calc(var(--u,0) * 1lvh + var(--header-h) + 3.5vw) var(--w-gut) 0}
/* the heading's box is pulled back .07em so the F's stem ink starts on the gutter, flush with the card edges below it
   (Lusion does the same; Manrope's F has .07em of side bearing at this size) */
#work .work-h{margin:0;margin-inline-start:-.07em;min-width:0;font-size:8vw;font-weight:400;line-height:.9;letter-spacing:-.02em;white-space:nowrap}
/* Heebo, measured separately: the ע that starts "עבודות נבחרות" has .088em of side bearing on its start (right) side */
:lang(he) #work .work-h{margin-inline-start:-.088em;line-height:1;letter-spacing:-.01em}
.work-blurb{flex:none;width:21vw;min-width:230px;margin:0;font:400 var(--w-tags)/1.4 var(--font-latin);letter-spacing:0;text-transform:uppercase}
:lang(he) .work-blurb{font-family:var(--font-he)}

/* ============================================================== grid */
.work-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--w-gap);row-gap:80px;align-items:start;
  padding:8vh var(--w-gut) 0}
.work-card{position:relative;grid-column:span 6;min-width:0}
.work-card.has-arrival{will-change:transform}
/* The rectangle itself follows scroll now, with the same pose in WebGL. Keep
   its DOM fallback intact during the trip; the title's rolling reveal remains. */
html.js:not(.reduced) .work-card.has-arrival .work-media{clip-path:none!important}
html.js:not(.reduced) .work-card.has-arrival .work-media .wm-inner{scale:1!important}
html.js:not(.reduced) .work-card.has-arrival .drago-ui{scale:1!important}
html.reduced .work-card.has-arrival{will-change:auto;transform:none!important}
.work-link{display:block;color:inherit;text-decoration:none;border-radius:var(--w-rad);outline-offset:8px;-webkit-tap-highlight-color:transparent}
.work-link:focus-visible{outline:2px solid var(--accent-deep)}

/* ---------- media ---------- */
.work-media{position:relative;display:block;aspect-ratio:100/65;border-radius:var(--w-rad);overflow:hidden;overflow:clip;isolation:isolate;
  background:color-mix(in srgb,var(--ink) 6%,var(--light))}
.wm-inner{position:absolute;inset:0;display:block;transform-origin:50% 50%;transition:scale calc(650ms * var(--tempo)) var(--w-ease)}
.wm-inner>:is(img,video){position:absolute;inset:0;display:block;width:100%;height:100%;max-width:none;object-fit:cover}
.work-card:is([data-work=hillel],[data-work=save]) .wm-inner>:is(img,video){object-position:50% 0}
/* DOM fallback of the hover (no WebGL / the plane has no pixels yet), the plane's shader in CSS (lusion.co, measured
   by the media's sharpness every frame): IN = the picture is at its softest on the hover's first frame (≈ 6 px) and
   resolves over ≈ 200 ms, easing out, while the loop cross-fades over the still in the same window; a loop whose first
   frame comes later (.is-late, work.js) fades in under a second, lighter pulse; OUT = only a slight softening (≈ 30 %,
   160 ms) while the still returns. No zoom. */
.wm-video{opacity:0;transition:opacity calc(150ms * var(--tempo)) linear}
.work-card.is-playing .wm-video{opacity:1;transition-duration:calc(200ms * var(--tempo))}
html.js:not(.reduced) .work-card.is-hover .work-media:not([data-gl=ready][data-gl-tex]):not(.work-media--drago) .wm-inner{animation:w-defocus-in calc(200ms * var(--tempo)) cubic-bezier(.45,.5,.85,.9)}
html.js:not(.reduced) .work-card.is-hover.is-late .work-media:not([data-gl=ready][data-gl-tex]):not(.work-media--drago) .wm-inner{animation:w-defocus-late calc(200ms * var(--tempo)) cubic-bezier(.45,.5,.85,.9)}
html.js:not(.reduced) .work-card.was-hover:not(.is-hover) .work-media:not([data-gl=ready][data-gl-tex]):not(.work-media--drago) .wm-inner{animation:w-defocus-out calc(160ms * var(--tempo)) linear}
@keyframes w-defocus-in{0%{filter:blur(6px)}100%{filter:blur(0)}}
@keyframes w-defocus-late{0%{filter:blur(3.6px)}100%{filter:blur(0)}}
@keyframes w-defocus-out{0%{filter:blur(0)}45%{filter:blur(1.8px)}100%{filter:blur(0)}}
/* A GL plane draws this media and has pixels (scenes/work.js): keep the box for layout + the anchor, hide the DOM
   picture. The video keeps decoding at opacity 0 — it is the plane's texture. */
html.js:not(.reduced) .work-media[data-gl=ready][data-gl-tex]{background:none;clip-path:none!important}
html.js:not(.reduced) .work-media[data-gl=ready][data-gl-tex] .wm-inner{opacity:0;transition:none}

/* ---------- tags line ---------- */
.work-tags{margin:max(14px,1.35vw) 0 max(9px,.9vw);font:400 var(--w-tags)/1.15 var(--font-latin);letter-spacing:0;text-transform:uppercase;text-wrap:balance}
:lang(he) .work-tags{font-family:var(--font-he)}

/* ---------- title: arrow + letters ---------- */
/* The title box is 1em high, like Lusion's line 2 (so the card measures like theirs: 502.3 px at 1440), and the text's
   1.15 line sits .2em ABOVE the box top (Lusion pulls its inner line up .2em): the caps start right at the box top and
   the tags → caps gap matches. The letters sit in taller slots (--wt-slot 1.5em, centred on that raised 1.15 line, so
   the baseline lands where a 1.15 line puts it, minus .2em) so a column's next copy is fully below the window at rest.
   The window (clip-path; the layout keeps the 1em box) is the box plus .2em above for ascenders that rise past the
   caps (Heebo's ל reaches .063em above the box top in "הלל ישראל", accents), .2em below for descenders (g, ן, ק:
   ≤ 1.02em measured) and .07em past the start side for the arrow's antialiasing — nothing clips, and at rest no
   other copy of a column reaches the window (the next one starts 1.5em down). */
#work .work-title{position:relative;display:block;height:1em;margin:0;font-size:var(--w-title);font-weight:400;line-height:1.15;letter-spacing:0;
  clip-path:inset(-.2em 0 -.2em -.07em)}
[dir=rtl] #work .work-title{clip-path:inset(-.2em -.07em -.2em 0)}
.wt-text{position:relative;top:-.2em;display:block;line-height:1.15;white-space:nowrap}
.work-title.is-rolled .wt-text{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
/* The hover (lusion.co, measured): the letters shift 1.5em toward the end, the END letters leading (--r); the arrow
   follows from outside the clip at the start side (−1em → 0), trailing them. Leaving: the arrow leads home, fast,
   then the FIRST letter, then the last (65 ms − --r × 4.5 ms), accelerating home. No vertical roll on hover
   (--wt-hover-roll 0). The arrow keeps opacity 1: the clip hides it. Timing: --wt-in / --wt-out / --wt-ar-in /
   --wt-ar-out / --wt-out-last on #work (header). */
.wt-arrow{position:absolute;top:.1em;inset-inline-start:0;display:block;width:.8em;height:.8em;
  transform:translate3d(calc(-1em * var(--dx)),0,0);transition:transform var(--wt-ar-out)}
.wt-arrow>svg{display:block;width:100%;height:100%;overflow:visible}
[dir=rtl] .wt-arrow>svg{scale:-1 1}
.work-card.is-hover .wt-arrow{transform:translate3d(0,0,0);transition:transform var(--wt-ar-in)}
/* the letters: a row of columns, each 4 copies deep (work.js builds them) */
.wt-roll{position:absolute;top:calc((1.15em - var(--wt-slot)) / 2 - .2em);inset-inline-start:-.04em;display:flex;white-space:nowrap;pointer-events:none}
:lang(he) .wt-roll{inset-inline-start:0}
.wt-w{display:flex;flex:none}
.wt-sp{display:block;flex:none;width:.3em}
/* transform = the hover shift; translate = the reveal roll (both on .wt-s, independent) */
.wt-s{--wt-reveal:translate calc(1000ms * var(--tempo)) var(--ease-out) calc(160ms + var(--cd,0ms) + var(--i,0) * 26ms);
  display:flex;flex:none;flex-direction:column;transform:translate3d(0,0,0);
  transition:transform var(--wt-out) calc(var(--wt-out-last) - var(--r,0) * var(--wt-stag)),var(--wt-reveal)}
.wt-s>span{display:block;height:var(--wt-slot);line-height:var(--wt-slot)}
.work-card.is-hover .wt-s{transform:translate3d(calc(1.5em * var(--dx)),calc(var(--wt-hover-roll) * -25%),0);
  transition:transform var(--wt-in) calc(var(--r,0) * var(--wt-stag)),var(--wt-reveal)}
/* touch mode (work.js: #work.is-touch — coarse pointer or ≤ 700 px; Lusion mobile): every card's title rests shifted
   with its arrow in; the arrow slides in with the card's reveal (and back out once the card is fully out of view, so
   it replays). The centred card's is-hover drives only its media. */
#work.is-touch .wt-s{transform:translate3d(calc(1.5em * var(--dx)),0,0);transition:var(--wt-reveal)}
#work.is-touch .wt-arrow{transform:translate3d(0,0,0);transition:transform calc(700ms * var(--tempo)) var(--ease-out) calc(420ms + var(--cd,0ms))}
#work.is-touch .work-card[data-w=pre] .wt-arrow{transform:translate3d(calc(-1em * var(--dx)),0,0);transition:none}
#work.is-touch .work-card[data-w=pre] .wt-s{transition:none}

/* ============================================================== reveal (replays every pass) */
/* The GL plane runs its own reveal (scenes/work.js); these are the DOM parts + the DOM-media fallback. The letters
   roll down through their 4-deep stack (Lusion: translateY(-400%) → 0 as the card enters). */
.work-grid>.work-card:nth-child(even){--cd:90ms}
html.js:not(.reduced) .work-card .work-tags{transition:translate calc(var(--d-l) * var(--tempo)) var(--ease-out) calc(60ms + var(--cd,0ms)),opacity var(--d-fade) linear calc(60ms + var(--cd,0ms))}
html.js:not(.reduced) .work-card[data-w=pre] .work-tags{translate:0 .9em;opacity:0;transition:none}
html.js:not(.reduced) .work-card[data-w=pre] .wt-s{translate:0 -100%;transition:none}
/* DOM media (fallback / Drago): a clip wipe from the entry side + a zoom-out */
html.js:not(.reduced) .work-card[data-w=pre] .work-media:not([data-gl=ready][data-gl-tex]){clip-path:inset(100% 0 0 0 round var(--w-rad));transition:none}
html.js:not(.reduced) .work-card[data-w=pre][data-from="-1"] .work-media:not([data-gl=ready][data-gl-tex]){clip-path:inset(0 0 100% 0 round var(--w-rad))}
html.js:not(.reduced) .work-card[data-w=in] .work-media:not([data-gl=ready][data-gl-tex]){clip-path:inset(0 0 0 0 round var(--w-rad));
  transition:clip-path calc(1100ms * var(--tempo)) var(--ease-out) var(--cd,0ms)}
html.js:not(.reduced) .work-card[data-w=pre] .work-media:not([data-gl=ready][data-gl-tex]) .wm-inner{scale:1.16;transition:none}
html.js:not(.reduced) .work-card[data-w=in]:not(.is-hover):not(.was-hover) .work-media:not([data-gl=ready][data-gl-tex]) .wm-inner{transition:scale calc(1400ms * var(--tempo)) var(--ease-out) var(--cd,0ms)}

/* ============================================================== end pill → #contact */
/* Lusion's "SEE ALL PROJECTS": on hover the dot grows into the fill, the label slides into the dot's place and turns
   white, the arrow comes in from the end and stops 1 × --p from it (label → arrow ≈ .8 × --p, as measured). */
.work-foot{display:flex;justify-content:center;padding:12vh var(--w-gut) max(72px,6vw)}
.work-cta{--p:clamp(14px,1vw,22px);position:relative;display:inline-flex;align-items:center;gap:var(--p);height:calc(var(--p) * 3.375);
  padding-inline:calc(var(--p) * 1.625) calc(var(--p) * 1.5);border-radius:var(--r-pill);overflow:hidden;overflow:clip;isolation:isolate;
  background:var(--white);color:var(--ink);font:500 var(--p)/1.15 var(--font-latin);letter-spacing:0;text-transform:uppercase;text-decoration:none;white-space:nowrap;
  -webkit-tap-highlight-color:transparent;transition:color calc(300ms * var(--tempo)) linear}
:lang(he) .work-cta{font-family:var(--font-he)}
.work-cta:focus-visible{outline:2px solid var(--accent-deep);outline-offset:4px}
.wc-dot{position:relative;z-index:-1;flex:none;width:calc(var(--p) * .5);height:calc(var(--p) * .5);border-radius:50%;background:currentColor;
  transition:scale calc(520ms * var(--tempo)) var(--w-ease),background-color calc(200ms * var(--tempo)) linear}
.wc-text{display:block;transition:translate calc(520ms * var(--tempo)) var(--w-ease)}
.wc-arrow{position:absolute;top:50%;inset-inline-end:var(--p);display:block;width:calc(var(--p) * 1.2);height:calc(var(--p) * 1.2);margin-top:calc(var(--p) * -.6);
  translate:calc(var(--p) * 3 * var(--dx)) 0;transition:translate calc(520ms * var(--tempo)) var(--w-ease)}
.wc-arrow>svg{display:block;width:100%;height:100%}
[dir=rtl] .wc-arrow>svg{scale:-1 1}
.work-cta:focus-visible{color:var(--white)}
.work-cta:focus-visible .wc-dot{scale:80;background:var(--accent)}
.work-cta:focus-visible .wc-text{translate:calc(var(--p) * -1.5 * var(--dx)) 0}
.work-cta:focus-visible .wc-arrow{translate:0 0}
@media (hover:hover) and (pointer:fine){
  .work-cta:hover{color:var(--white)}
  .work-cta:hover .wc-dot{scale:80;background:var(--accent)}
  .work-cta:hover .wc-text{translate:calc(var(--p) * -1.5 * var(--dx)) 0}
  .work-cta:hover .wc-arrow{translate:0 0}
}
html.js:not(.reduced) .work-foot .work-cta{transition:color calc(300ms * var(--tempo)) linear,translate calc(var(--d-l) * var(--tempo)) var(--ease-out),opacity var(--d-fade) linear}
html.js:not(.reduced) .work-foot[data-w=pre] .work-cta{translate:0 28px;opacity:0;transition:none}

/* ============================================================== Drago: a designed dialer teaser (no real data) */
/* Frozen at rest; alive on hover (work.js: .is-live) with the same defocus as the picture cards (no zoom). */
.work-media--drago{container-type:inline-size;perspective:1400px;perspective-origin:50% 40%;
  --dg-on:var(--accent-soft);--dg-wrap:var(--dark-ink);--dg-line:rgba(241,242,250,.08);--dg-fs:max(10px,1.45cqw);
  background:radial-gradient(90% 80% at 88% 0%,color-mix(in srgb,var(--accent) 38%,transparent),transparent 62%),
             radial-gradient(70% 70% at 0% 100%,color-mix(in srgb,var(--accent) 16%,transparent),transparent 60%),var(--dark)}
.work-media--drago::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.55;
  background-image:radial-gradient(rgba(241,242,250,.16) 1px,transparent 1.4px);background-size:3cqw 3cqw;
  -webkit-mask-image:radial-gradient(75% 75% at 50% 45%,black 30%,transparent 100%);mask-image:radial-gradient(75% 75% at 50% 45%,black 30%,transparent 100%)}
.drago-ui{position:absolute;inset:9% 9% 10%;display:grid;grid-template-columns:1.18fr 1fr;grid-template-rows:auto auto minmax(0,1fr);
  grid-template-areas:"head head" "kpis kpis" "call agents";gap:2cqw;padding:2.4cqw;border-radius:2.2cqw;overflow:hidden;
  font:500 var(--dg-fs)/1.2 var(--font-latin);color:var(--dark-ink);transform-origin:50% 55%;
  background:linear-gradient(180deg,color-mix(in srgb,var(--dark) 82%,var(--accent)) 0%,var(--dark) 70%);
  border:1px solid rgba(241,242,250,.11);
  box-shadow:0 4cqw 9cqw -2cqw rgba(0,0,0,.7),0 0 0 1px rgba(104,114,246,.10),inset 0 1px 0 rgba(255,255,255,.07);
  transition:scale calc(650ms * var(--tempo)) var(--w-ease)}
html.js:not(.reduced) .work-card[data-w=pre] .drago-ui{scale:1.1;transition:none}
html.js:not(.reduced) .work-card.is-hover .drago-ui{animation:w-defocus-in calc(200ms * var(--tempo)) cubic-bezier(.45,.5,.85,.9)}
html.js:not(.reduced) .work-card.was-hover:not(.is-hover) .drago-ui{animation:w-defocus-out calc(160ms * var(--tempo)) linear}
.dg-head{grid-area:head;display:flex;align-items:center;justify-content:space-between;gap:2cqw}
.dg-brand{display:inline-flex;align-items:center;gap:1.1cqw;font-weight:700;letter-spacing:.16em}
.dg-logo{display:block;width:2.8cqw;height:2.8cqw;border-radius:.8cqw;background:linear-gradient(135deg,var(--accent),var(--accent-soft));
  box-shadow:0 0 2.2cqw color-mix(in srgb,var(--accent) 60%,transparent)}
.dg-live{display:inline-flex;align-items:center;gap:.9cqw;padding:.55cqw 1.2cqw;border-radius:var(--r-pill);font-weight:700;letter-spacing:.16em;
  color:var(--dg-on);background:color-mix(in srgb,var(--dg-on) 13%,transparent);border:1px solid color-mix(in srgb,var(--dg-on) 26%,transparent)}
.dg-live-dot,.dg-status{position:relative;display:block;flex:none;width:1.1cqw;height:1.1cqw;min-width:5px;min-height:5px;border-radius:50%;background:currentColor}
.dg-live-dot::after,.dg-status::after{content:"";position:absolute;inset:0;border-radius:50%;background:inherit;opacity:0}
.dg-kpis{grid-area:kpis;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.4cqw}
.dg-kpi{display:flex;flex-direction:column;gap:.9cqw;padding:1.5cqw 1.7cqw;border-radius:1.3cqw;background:rgba(241,242,250,.035);border:1px solid var(--dg-line);min-width:0}
.dg-kpi-v{display:flex;font-size:4.4cqw;font-weight:600;line-height:1;letter-spacing:-.04em;font-variant-numeric:tabular-nums}
[dir=rtl] .dg-kpi-v{justify-content:flex-end}
.dg-kpi-l,.dg-agents-l,.dg-calling-l{font-weight:700;letter-spacing:.14em;color:var(--muted-dark);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
:lang(he) :is(.dg-kpi-l,.dg-agents-l,.dg-calling-l,.dg-brand,.dg-live){letter-spacing:.02em;font-family:var(--font-he)}
/* odometer digits (built by work.js): 0 → the value when the card reveals. Each digit sits in a slot taller than the
   glyph (--dg-slot) and the window is one slot, so no sliver of the digit above / below shows while it rolls;
   negative margins keep the line box at 1em. */
.dg-kpi-v{--dg-slot:1.36em}
.dg-d{display:inline-block;height:var(--dg-slot);margin-block:calc((1em - var(--dg-slot)) / 2);overflow:hidden;overflow:clip;vertical-align:top}
.dg-ds{display:flex;flex-direction:column;transform:translate3d(0,0,0)}
.dg-ds>span{display:block;height:var(--dg-slot);line-height:var(--dg-slot)}
.work-card[data-w=in] .dg-ds{transform:translate3d(0,calc(var(--d) * -10%),0);
  transition:transform calc(1500ms * var(--tempo)) var(--ease-out) calc(250ms + var(--j) * 90ms)}
.dg-call{grid-area:call;position:relative;display:flex;flex-direction:column;justify-content:space-between;gap:1.6cqw;min-height:0;padding:1.8cqw;border-radius:1.3cqw;overflow:hidden;
  background:linear-gradient(160deg,color-mix(in srgb,var(--accent) 16%,transparent),color-mix(in srgb,var(--accent) 4%,transparent));
  border:1px solid color-mix(in srgb,var(--accent) 34%,transparent)}
.dg-wave{display:flex;align-items:center;gap:.7cqw;height:clamp(18px,8cqw,64px);flex:1;min-height:0}
.dg-bar{display:block;flex:1;height:100%;border-radius:99px;transform:scaleY(var(--s,.3));transform-origin:50% 50%;will-change:transform;
  background:linear-gradient(180deg,var(--accent-soft),var(--accent) 55%,var(--accent-soft))}
.dg-calling{display:flex;align-items:center;gap:1.2cqw}
.dg-calling-line{position:relative;flex:1;height:2px;border-radius:2px;background:rgba(241,242,250,.12);overflow:hidden}
.dg-calling-line>i{position:absolute;inset:0 auto 0 0;width:40%;background:linear-gradient(90deg,transparent,var(--accent-soft),transparent);
  transform:translate3d(-100%,0,0);animation:dg-run 1.7s var(--ease-in-out) infinite;animation-play-state:paused}
[dir=rtl] .dg-calling-line>i{animation-name:dg-run-rtl}
.dg-calling-l{color:var(--accent-soft)}
.dg-agents{grid-area:agents;display:flex;flex-direction:column;gap:1.1cqw;min-height:0}
.dg-agent-list{display:flex;flex-direction:column;gap:.9cqw;margin:0;padding:0;list-style:none}
.dg-agent{display:flex;align-items:center;gap:1.2cqw;padding:1.05cqw 1.3cqw;border-radius:1.1cqw;background:rgba(241,242,250,.035);border:1px solid var(--dg-line)}
.dg-agent[data-status=accent]{color:var(--accent)}
.dg-agent:is([data-status=soft],[data-status=green]){color:var(--dg-on)}      /* green / amber: the markup's first */
.dg-agent:is([data-status=ivory],[data-status=amber]){color:var(--dg-wrap)}    /* frame, mapped into the palette */
.dg-agent[data-status=muted]{color:var(--muted-dark)}
.dg-bar-name{display:block;height:.8cqw;min-height:3px;width:44%;border-radius:99px;background:rgba(241,242,250,.22)}
.dg-bar-time{display:block;height:.8cqw;min-height:3px;width:16%;margin-inline-start:auto;border-radius:99px;background:currentColor;opacity:.55;transform-origin:left center}
[dir=rtl] .dg-bar-time{transform-origin:right center}
.dg-sweep{position:absolute;inset:0;z-index:3;pointer-events:none;transform:translate3d(-120%,0,0);
  background:linear-gradient(105deg,transparent 30%,rgba(241,242,250,.07) 44%,rgba(241,242,250,.16) 50%,rgba(241,242,250,.07) 56%,transparent 70%)}
/* alive only while hovered / the centred card on touch (work.js toggles .is-live) */
.work-card.is-live .dg-calling-line>i{animation-play-state:running}
.work-card.is-live .dg-live-dot::after,.work-card.is-live .dg-agent[data-status=accent] .dg-status::after{animation:w-ping 1.5s var(--ease-out) infinite}
.work-card.is-live .dg-agent:is([data-status=soft],[data-status=green]) .dg-bar-time{animation:dg-grow 2.4s linear infinite}
.dg-bar:nth-child(1){--s:.28}.dg-bar:nth-child(2){--s:.46}.dg-bar:nth-child(3){--s:.38}.dg-bar:nth-child(4){--s:.66}
.dg-bar:nth-child(5){--s:.52}.dg-bar:nth-child(6){--s:.9}.dg-bar:nth-child(7){--s:.74}.dg-bar:nth-child(8){--s:.84}
.dg-bar:nth-child(9){--s:.5}.dg-bar:nth-child(10){--s:.6}.dg-bar:nth-child(11){--s:.36}.dg-bar:nth-child(12){--s:.24}
@keyframes w-ping{from{transform:scale(1);opacity:.7}to{transform:scale(3.2);opacity:0}}
@keyframes dg-run{from{transform:translate3d(-100%,0,0)}to{transform:translate3d(250%,0,0)}}
@keyframes dg-run-rtl{from{transform:translate3d(250%,0,0)}to{transform:translate3d(-100%,0,0)}}
@keyframes dg-grow{from{transform:scaleX(.35)}to{transform:scaleX(1)}}

/* ============================================================== mobile (≤ 700 px): one column, full width */
/* lusion.co at 390×844: 15 px gutters, title 6.5vw, blurb 3.5vw / 1.4 over the full width with 10.5vw above and below
   it, row gap 32 px, tags on tight 1.15 lines (ours keep the 11 px floor, SPEC §3.19). Every card's title rests with
   its arrow in and shifted 1.5em once the card has entered (#work.is-touch above): titles never move while scrolling. */
@media (max-width:700px){
  #work{--w-gut:15px;--w-tags:11px;--w-title:6.5vw}
  .work-head{flex-direction:column;align-items:flex-start;gap:10.5vw;padding-top:calc(var(--u,0) * 1lvh + var(--header-h) + 8vw)}
  #work .work-h{font-size:15vw;white-space:normal}
  .work-blurb{align-self:stretch;width:auto;min-width:0;max-width:none;padding-bottom:0;font-size:max(11px,3.5vw);line-height:1.4}
  .work-grid{grid-template-columns:minmax(0,1fr);row-gap:32px;padding-top:10.5vw}
  .work-card{grid-column:auto}
  .work-grid>.work-card:nth-child(even){--cd:0ms}
  .work-tags{margin:14px 0 9px;line-height:1.15;text-wrap:pretty}
  .work-foot{padding:14vw var(--w-gut) calc(18vw + 96px + env(safe-area-inset-bottom))}   /* the pill clears the mobile CTA bar */
  .drago-ui{inset:7% 6% 8%;gap:1.8cqw;padding:2.2cqw;grid-template-columns:1fr 1fr}
  .dg-agents-l,.dg-calling-l{display:none}
  .dg-agent:nth-child(n+4){display:none}
  .dg-kpi-l{letter-spacing:.04em}
  .work-media--drago{--dg-fs:max(11px,1.45cqw)}          /* the 11 px floor (SPEC §3.19), even for decoration */
}

/* ============================================================== reduced motion + no JS: static, instant states */
html.reduced .work-card[data-w=pre] :is(.work-tags,.work-title,.work-media){opacity:0}
html.reduced .work-card[data-w=in] :is(.work-tags,.work-title,.work-media){opacity:1;transition:opacity 400ms linear}
html.reduced .work-foot[data-w=pre] .work-cta{opacity:0}
html.reduced .work-foot[data-w=in] .work-cta{opacity:1;transition:opacity 400ms linear,color 200ms linear}
html.reduced :is(.wt-s,.wt-arrow,.wm-inner,.wm-video,.drago-ui,.wc-dot,.wc-text,.wc-arrow){transition:none!important;animation:none!important}
html.reduced .wt-s{translate:none!important}
html.reduced .work-card .dg-ds{transition:none!important}           /* no odometer roll: the values just are */
