/* cursor.css — custom cursor, label blob, click ripple and the hover-roll labels (SPEC §3.8).
   cursor.js writes every transform; this file holds the looks and the state colours. No hex colours (tokens only —
   the one exception is the pearl ribbon's three tints below: the owner's spec asks for hues outside the palette).

   The root is display:contents so each part is its own fixed layer in the ROOT stacking context: that is what lets
   mix-blend-mode:difference on the dot and ring invert the page, the WebGL canvas and the dark preloader beneath them
   (a positioned / z-indexed wrapper would isolate the blend). The parts sit just above the preloader so the intro has
   a cursor too; dialogs live in the top layer anyway, and the cursor hides while one is open. */

.cursor{display:contents}
.c-dot,.c-ring,.c-blob,.c-ripple{position:fixed;top:0;left:0;z-index:calc(var(--z-preloader) + 2);pointer-events:none;
  border-radius:50%;box-sizing:border-box;transform:scale(0);contain:layout style}
html:not(.has-cursor) :is(.c-dot,.c-ring,.c-blob){display:none}

/* dot: 6 px, raw pointer */
.c-dot{width:6px;height:6px;margin:-3px 0 0 -3px;background:var(--white);mix-blend-mode:difference;will-change:transform}

/* ring: 40 px, 1.5 px; links fade its border to .5, the blob hides it */
.c-ring{width:40px;height:40px;margin:-20px 0 0 -20px;border:1.5px solid var(--white);mix-blend-mode:difference;will-change:transform;
  transition:border-color 300ms linear,opacity 220ms linear}
.cursor.is-link .c-ring{border-color:color-mix(in srgb,var(--white) 50%,transparent)}
.cursor.is-blob .c-ring{opacity:0}

/* label blob: 88 px accent disc with an 11 px label whose chars roll up (cursor.js, WAAPI) */
.c-blob{width:88px;height:88px;margin:-44px 0 0 -44px;display:grid;place-items:center;background:var(--accent);color:var(--white);
  will-change:transform;transition:background-color 220ms linear,color 220ms linear}
/* over a surface filled with the accent ([data-cursor-invert]): white blob, accent label */
.cursor.is-invert .c-blob{background:var(--white);color:var(--accent)}
.c-label{display:block;max-width:80px;overflow:hidden;overflow:clip;padding-inline-start:.12em;
  font:700 11px/1.35 var(--font-latin);letter-spacing:.12em;text-transform:uppercase;white-space:nowrap;text-align:center}
:lang(he) .c-label{font-family:var(--font-he);letter-spacing:.04em;padding-inline-start:.04em}
.c-ch{display:inline-block}

/* lens trail (SPEC-OWNER-2 §O4): cursor.js moves and scales LENS_N of these along the pointer's path; each blurs what is
   under it through a soft radial mask, so the page smears like liquid behind the cursor. Above all page content, under
   the dot / ring / blob (dialogs are in the top layer, and the trail hides while one is open). No colour of its own.
   Hidden at rest; .lens-on (only while it moves) brings visibility and will-change. */
.c-lens{position:fixed;top:0;left:0;z-index:calc(var(--z-preloader) + 1);width:190px;height:190px;margin:-95px 0 0 -95px;
  border-radius:50%;pointer-events:none;transform:scale(0);visibility:hidden;contain:layout style size;
  -webkit-backdrop-filter:blur(10px) saturate(1.15);backdrop-filter:blur(10px) saturate(1.15);
  -webkit-mask-image:radial-gradient(closest-side,black 38%,rgba(0,0,0,.6) 70%,transparent);
  mask-image:radial-gradient(closest-side,black 38%,rgba(0,0,0,.6) 70%,transparent)}
.cursor.lens-on .c-lens{visibility:visible;will-change:transform}
html:not(.has-cursor) :is(.c-lens,.c-pearl),html.reduced :is(.c-lens,.c-pearl){display:none}

/* pearl ribbon (SPEC-WORK-LUSION): every lens has a twin with the same box and the same transform (cursor.js). Its fill
   is a pale iridescent strip ACROSS the stroke (the box's x axis is turned along the pointer's motion): a cyan edge, a
   lilac core, a pink edge, soft-edged, the lens's radial mask rounding its ends — multiplied onto the page, so it only
   ever tints light surfaces and leaves dark type / pictures alone. cursor.js adds .lens-pearl while the pointer is
   over a light band (light / lilac); over dark bands, project pages and the preloader the twins are fully transparent
   and hidden.
   --o (inline, per twin): .1 at the head → .05 at the tail, so the overlapping chain stays a pale ≤ 18 % wash.
   (A twin, not a ::after of .c-lens: the lens is an isolated group — backdrop-filter + mask — so a child could not
   blend with the page, and multiplying the lens itself would multiply its blurred backdrop onto the page too.) */
.c-pearl{position:fixed;top:0;left:0;z-index:calc(var(--z-preloader) + 1);width:190px;height:190px;margin:-95px 0 0 -95px;
  border-radius:50%;pointer-events:none;transform:scale(0);visibility:hidden;opacity:0;contain:layout style size;
  mix-blend-mode:multiply;
  background:linear-gradient(to bottom,transparent 26%,var(--pearl-a) 40%,var(--pearl-b) 50%,var(--pearl-c) 60%,transparent 74%);
  -webkit-mask-image:radial-gradient(closest-side,black 38%,rgba(0,0,0,.6) 70%,transparent);
  mask-image:radial-gradient(closest-side,black 38%,rgba(0,0,0,.6) 70%,transparent);
  transition:opacity 300ms linear,visibility 0s linear 300ms}
.cursor{--pearl-a:rgb(96 222 255);--pearl-b:rgb(176 150 255);--pearl-c:rgb(255 146 210)}
.cursor.lens-on.lens-pearl .c-pearl{visibility:visible;opacity:var(--o,.1);will-change:transform;transition:opacity 300ms linear,visibility 0s}

/* ripple: pooled 48 px rings; cursor.js sets --ripple (accent on light bands, dark-ink on dark ones, the mood accent
   for 2 s after a mood change) and animates scale + opacity */
.c-ripple{width:48px;height:48px;margin:-24px 0 0 -24px;border:1.5px solid var(--ripple,var(--accent));opacity:0}
html.reduced .c-ripple{display:none}

/* system cursor: hidden while the custom one runs; text fields keep the caret; dialogs (top layer, above the custom
   cursor) keep the system cursor */
html.has-cursor,html.has-cursor *{cursor:none}
html.has-cursor :is(input,textarea,[contenteditable]:not([contenteditable="false"])){cursor:text}
html.has-cursor dialog,html.has-cursor dialog *{cursor:auto}
html.has-cursor dialog :is(a[href],button,[role=button],summary,label){cursor:pointer}

/* ---------------------------------------------------------------- hover-roll (§3.8.5)
   [data-roll] host > .roll[aria-hidden] > (.roll-run[dir]) > .roll-w[dir] > .roll-c(--i) > span + span, then .sr-only.
   Each char is a 1.2 em window; on hover / focus both copies slide up one window, 16 ms apart. (1.2 em rather than
   1.1 em so descenders — g, p, y, ק, ף — are not clipped.) */
.roll{display:inline}
.roll-run{unicode-bidi:isolate}
.roll-w{display:inline-block;white-space:nowrap}
.roll-c{display:inline-block;overflow:hidden;overflow:clip;height:1.2em;line-height:1.2;vertical-align:top}
.roll-c>span{display:block;transition:transform 520ms var(--ease-in-out) calc(var(--i,0) * 16ms)}
.roll-c>span+span{color:var(--roll-ink,var(--accent))}
/* On the light and lilac bands an 11 px accent label falls to ≈ 3.0–3.5 : 1 (QA r1): there the second copy keeps the
   text colour and the roll alone carries the hover. The mood pill sits on the sculpture: the same. */
:is([data-theme=light],[data-theme=lilac],.mood-btn){--roll-ink:currentColor}
@media (hover:hover){
  :is(a,button,[role=button]):hover .roll-c>span{transform:translateY(-100%)}
}
:is(a,button,[role=button]):focus-visible .roll-c>span,
.is-pressed .roll-c>span{transform:translateY(-100%)}
/* surfaces whose hover fill is the accent (or that sit on it): the second copy keeps the text colour */
:is(.pill--primary,.site-header .pill--talk,.cta-bar .pill){--roll-ink:currentColor}
html.reduced .roll-c>span{transition:none}
