/* IYKYK copy of /site/'s kit stylesheet (fm/shur-hero f7e6d11, protos/site/kit/interaction-kit.css),
   verbatim down to the IYKYK patches at the end. */
/* SHUR interaction kit: the small-circle cursor that inverts what it passes over and grows over
   things you can hover, with its label (View, Play, Drag) shown inverted inside it; the
   shapes; and hover autoplay. See README.md for the API and the earlier build each piece is
   recovered from.

   Sizes are unitless px so the circle can be drawn once and scaled:
   --ik-dot (12), --ik-press (64), --ik-disc (88, with a label), --ik-lens (176). */

:root {
  --ik-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ik-ease-io: cubic-bezier(0.65, 0, 0.35, 1);
}

/* ---------- Cursor ----------
   One fixed layer in mix-blend-mode: difference (C R2 203533f, C R3 5ac14c6): the white circle
   inverts whatever is under it, and the label inside is black, so its letters show the page
   uninverted through the inverted disc. The blend is on the cursor layer only; page type is
   never filtered. It moves by transform only, from one rAF loop; the label is never scaled. */
.ik-cursor,
.ik-window {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--ik-z, 2147483000);
  pointer-events: none;
  opacity: 0;
  transition: opacity 240ms linear;
}

.ik-cursor {
  mix-blend-mode: difference;
}

/* (site patch, gate round 5: with a label the circle is drawn as itself, white with its label
   in ink, not blended, so the label reads on every row: over a hovered name, mid-grey names or
   bright footage the difference blend left it no contrast. The small dot still inverts.) */
.ik-cursor:is([data-state='view'], [data-state='play'], [data-state='drag']) {
  mix-blend-mode: normal;
}

html.ik-cursor-on .ik-cursor {
  opacity: 1;
}

.ik-dot {
  position: absolute;
  top: -88px;
  left: -88px;
  width: 176px;
  height: 176px;
  border-radius: 50%;
  background: #fff;
  transform: scale(calc(var(--ik-dot, 12) / 176));
  transition: transform 420ms var(--ik-ease-out);
  will-change: transform;
}

.ik-cursor:is([data-state='link'], [data-state='disc']) .ik-dot {
  transform: scale(calc(var(--ik-press, 64) / 176));
}

.ik-cursor:is([data-state='view'], [data-state='play'], [data-state='drag']) .ik-dot {
  transform: scale(calc(var(--ik-disc, 88) / 176));
}

.ik-cursor[data-state='lens'] .ik-dot {
  transform: scale(calc(var(--ik-lens, 176) / 176));
}

.ik-label {
  position: absolute;
  top: calc(var(--ik-disc, 88) * -0.5px);
  left: calc(var(--ik-disc, 88) * -0.5px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: calc(var(--ik-disc, 88) * 1px);
  height: calc(var(--ik-disc, 88) * 1px);
  color: #000;
  font: 500 12px / 16px var(--ik-font, var(--base-sans, 'Geist', 'Geist Fallback', system-ui, sans-serif));
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 120ms linear;
}

.ik-cursor:is([data-state='view'], [data-state='play'], [data-state='drag']) .ik-label {
  opacity: 1;
  transition: opacity 220ms linear 140ms;
}

.ik-icon {
  display: none;
  flex: none;
  fill: currentColor;
}

.ik-cursor[data-state='play'] .ik-play,
.ik-cursor[data-state='drag'] .ik-drag {
  display: block;
}

/* Frame: the zoom-frame's corner marks around the pointer, with the work's name under them
   (C R1 380d82a loupe), white in the difference layer so they read on any ground. */
.ik-frame {
  position: absolute;
  top: calc(var(--ik-frame-h, 104px) / -2);
  left: calc(var(--ik-frame-w, 168px) / -2);
  width: var(--ik-frame-w, 168px);
  height: var(--ik-frame-h, 104px);
  --ik-dx: calc(var(--ik-frame-w, 168px) / 2 - 7px);
  --ik-dy: calc(var(--ik-frame-h, 104px) / 2 - 7px);
}

.ik-frame i {
  position: absolute;
  width: 14px;
  height: 14px;
  border: 0 solid #fff;
  opacity: 0;
  transition: transform 420ms var(--ik-ease-out), opacity 200ms linear;
}

.ik-frame i:nth-child(1) {
  top: 0;
  left: 0;
  border-width: 1px 0 0 1px;
  transform: translate(var(--ik-dx), var(--ik-dy));
}

.ik-frame i:nth-child(2) {
  top: 0;
  right: 0;
  border-width: 1px 1px 0 0;
  transform: translate(calc(var(--ik-dx) * -1), var(--ik-dy));
}

.ik-frame i:nth-child(3) {
  bottom: 0;
  left: 0;
  border-width: 0 0 1px 1px;
  transform: translate(var(--ik-dx), calc(var(--ik-dy) * -1));
}

.ik-frame i:nth-child(4) {
  right: 0;
  bottom: 0;
  border-width: 0 1px 1px 0;
  transform: translate(calc(var(--ik-dx) * -1), calc(var(--ik-dy) * -1));
}

.ik-cursor[data-state='frame'] .ik-frame i {
  opacity: 1;
  transform: none;
}

.ik-caption {
  position: absolute;
  margin: 0;
  font: 600 15px / 20px var(--ik-font, var(--base-sans, 'Geist', 'Geist Fallback', system-ui, sans-serif));
  letter-spacing: -0.01em;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 200ms linear;
}

.ik-cursor .ik-caption {
  top: calc(var(--ik-frame-h, 104px) / 2 + 10px);
  left: calc(var(--ik-frame-w, 168px) / -2);
  color: #fff;
}

.ik-cursor[data-state='frame'] .ik-caption {
  opacity: 1;
}

/* Window: the hovered work, still or clip, trails below-right of the pointer (hero Lead ·
   Cursor b74e20e). Its own layer, outside the blend, so the work shows as it is. */
.ik-window {
  width: var(--ik-window-w, 288px);
  aspect-ratio: 16 / 9;
  will-change: transform;
  transition: opacity 360ms var(--ik-ease-io);
}

.ik-window img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ik-window .ik-caption {
  top: calc(100% + 10px);
  left: 0;
  color: var(--ik-ink, var(--ink, #eef0fb));
  opacity: 1;
}

html.ik-cursor-on .ik-window[data-on] {
  opacity: 1;
  transition: opacity 600ms var(--ik-ease-out);
}

.ik-cursor:is([data-state='native'], [data-state='hidden']) {
  visibility: hidden;
}

/* The native cursor hides only while the custom one is on; text fields keep theirs. */
html.ik-cursor-on,
html.ik-cursor-on * {
  cursor: none !important;
}

html.ik-cursor-on :is(input, textarea, select, [contenteditable]:not([contenteditable='false']), [data-cursor='native']),
html.ik-cursor-on [data-cursor='native'] *,
html.ik-cursor-on:has(dialog:modal) * {
  cursor: revert !important;
}

/* A modal dialog sits in the top layer, over any z-index: the native cursor takes over there. */
html:has(dialog:modal) :is(.ik-cursor, .ik-window) {
  visibility: hidden;
}

@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
  .ik-cursor,
  .ik-window {
    display: none;
  }
}

/* ---------- Hover autoplay ----------
   The clip sits over the still and shows once its first frame is ready. */
.ik-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  pointer-events: none;
  transition: opacity 320ms linear;
}

.ik-video.ik-on {
  opacity: 1;
  transition-duration: 200ms;
}

/* ---------- IYKYK patches ----------
   The owner (2026-10-29 8:56 AM PT): over the email the circle says Let's talk, "inverted
   (difference) inside the circle only, no box/bar". So on IYKYK the labelled circle keeps the
   difference blend: the disc inverts the ground under it and its black label shows the ground
   uninverted through it. Nothing outside the circle is ever inverted. */
.ik-cursor:is([data-state='view'], [data-state='play'], [data-state='drag']) {
  mix-blend-mode: difference;
}
/* a field with its own labelled circle hides the native caret cursor under it (the typing
   caret in the field is unchanged) */
html.ik-cursor-on.ik-cursor-on :is(input, textarea)[data-cursor]:not([data-cursor='native']) {
  cursor: none !important;
}

/* The pill (owner, 2026-10-29 ~9:00 AM PT, after minalstudio.com's cursor): one white card the
   size of its label, 40px tall, clipped down to the 12px dot of Direction C round 2 (203533f)
   at rest; over anything you can press it unclips into the whole pill in place, centred on the
   pointer (minal: clip-path inset(0 round 50em), 0.4s cubic-bezier(.75,0,.25,1); its quarter rise
   is left out: CURSOR SPEC, the pill stays on the pointer).
   The whole layer stays in difference: the page under the pill inverts live, and the black label
   shows the page through it. The label fades in at once and out after 0.25s (minal), and is
   never scaled: only the card (its ::before) pops. The circle shapes (disc, link, lens) keep the
   kit's disc. */
.ik-pill {
  position: absolute;
  top: -20px;
  left: calc(var(--ik-pill-w, 40) * -0.5px);
  width: calc(var(--ik-pill-w, 40) * 1px);
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 400ms cubic-bezier(0.75, 0, 0.25, 1);
}
.ik-pill::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: #fff;
  clip-path: inset(calc(50% - var(--ik-dot, 12) * 0.5px) round 999px);
  transition: clip-path 400ms cubic-bezier(0.75, 0, 0.25, 1);
}
.ik-pill .ik-label {
  position: relative;
  top: auto;
  left: auto;
  flex: none;
  width: auto;
  height: auto;
  padding: 0 16px;
  transition: opacity 150ms ease-in-out 250ms;
}
.ik-cursor:is([data-state='view'], [data-state='play'], [data-state='drag']) .ik-pill::before { clip-path: inset(0 round 999px); }
.ik-cursor:is([data-state='view'], [data-state='play'], [data-state='drag']) .ik-pill .ik-label { opacity: 1; transition: opacity 150ms ease-in-out; }
.ik-cursor:is([data-state='dot'], [data-state='view'], [data-state='play'], [data-state='drag']) .ik-dot { visibility: hidden; }
.ik-cursor:not([data-state='dot'], [data-state='view'], [data-state='play'], [data-state='drag']) .ik-pill { visibility: hidden; }
/* The cursor rides its own compositor layer, so following the pointer is a transform on that
   layer and nothing under it repaints (owner, 10:01 AM PT: smooth tracking). */
.ik-cursor { will-change: transform; }
