/* ============================================================
   SW CURSOR - playful trailing label
   Mirrors the nav's palette and chamfered corner so the tag reads
   as part of the same object family.
   ============================================================ */

.sw-cursor {
  --swc-bg: #141414;
  --swc-fg: #f4f4f2;
  --swc-accent: var(--sw-accent);
  --swc-notch: 11px;

  /* A point at the viewport's corner, not a box over the whole
     viewport. The dot and the label are placed by transform from
     here, so they need no area to sit in - and a full-screen box
     over every composited layer on the page became a full-screen
     layer of its own, rasterised and blended each frame to show a
     10px dot. */
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  z-index: 9999;
  pointer-events: none;   /* never intercepts a click */
}

/* Both move every frame the pointer does. On their own layers the
   move is the compositor's job; without one, each frame repainted
   the tag and re-sorted the page's layers around it. */
.sw-cursor-dot,
.sw-cursor-label {
  will-change: transform;
}

/* ------------------------------------------------------------
   Dot - the honest pointer position
   ------------------------------------------------------------ */
.sw-cursor-dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;   /* centre on the coordinate */
  border-radius: 50%;
  background: var(--swc-bg);
  border: 0 solid var(--swc-accent);

  /* width/height/margin carry the grab states below. They are box
     properties on purpose: the script tweens this element's scale
     for the press squash, so driving the ring off scale too would
     have the two overwriting each other. Split this way they
     compose - a press still squashes an open ring. */
  transition: background 0.3s ease,
    width 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
    height 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
    margin 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
    border-color 0.25s ease, border-width 0.25s ease;
}

.sw-cursor.is-active .sw-cursor-dot {
  background: var(--swc-accent);
}

/* ------------------------------------------------------------
   Grab states - the dot answers instead of a system cursor

   The pill used to swap cursor: grab / grabbing. That is an OS
   glyph: it lands in one frame, has no easing, and sits next to
   the studio's own dot looking borrowed. The dot carries it now.

   The easing is slightly springy, so the open reads as the dot
   reacting rather than a state flag being flipped.
   ------------------------------------------------------------ */

/* Actually carrying: the ring closes back down onto a solid core,
   which reads as the grip shutting. */
.sw-cursor.is-grabbing .sw-cursor-dot {
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  background: var(--swc-accent);
  border-width: 0;
}

@media (prefers-reduced-motion: reduce) {
  .sw-cursor-dot {
    transition: background 0.3s ease;
  }
}

/* ------------------------------------------------------------
   Label - the part that lags and tilts

   Offset down-right of the dot so it trails the pointer rather
   than sitting under it and hiding what is being pointed at.
   The chamfer is cut with clip-path: a bevel that `border-radius`
   cannot describe, matching the nav's SVG-drawn corners.
   ------------------------------------------------------------ */
.sw-cursor-label {
  position: absolute;
  top: 0;
  left: 0;
  /* Sits above and to the RIGHT of the pointer. The bottom-left corner
     is the anchor, so these two margins are the gap the dot is given:
     up, and across to clear it. */
  transform-origin: 0% 100%;
  margin: -14px 0 0 14px;
  white-space: nowrap;
}

/* Near the right edge the tag flips to the pointer's left. The
   horizontal gap mirrors with it, so the dot keeps the same clearance
   on whichever side the tag has moved to. */
.sw-cursor-label.is-flipped {
  margin-left: -14px;
}

/* Carries the surface and the scale. Kept off the outer box so the
   speed-driven growth and the hover/press tweens do not overwrite
   one another's transform. */
.sw-cursor-label-inner {
  padding: 0.55rem 1.05rem;
  /* No max-width: the swap animates this box to a measured pixel
     width, and a clamp here would fight that tween. Wording is kept
     short at the source instead. */
  box-sizing: border-box;

  background: var(--swc-bg);
  color: var(--swc-fg);
  font-family: "Inter Tight", sans-serif;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: 0.01em;
  white-space: nowrap;

  clip-path: polygon(
    var(--swc-notch) 0,
    100% 0,
    100% calc(100% - var(--swc-notch)),
    calc(100% - var(--swc-notch)) 100%,
    0 100%,
    0 var(--swc-notch)
  );

  /* Clips the swapping line while it slides in and out */
  overflow: hidden;
  transition: background 0.3s ease, color 0.3s ease;
}

.sw-cursor.is-active .sw-cursor-label-inner {
  background: var(--swc-accent);
  color: #14140f;
}

/* Over an accent surface (the footer) the accent plate would vanish
   into it, so the tag stays dark and the dot goes ink. Set by
   js/cursor.js from the background under the target. */
.sw-cursor.is-active.on-accent .sw-cursor-label-inner {
  background: var(--swc-bg);
  color: var(--swc-fg);
}

.sw-cursor.on-accent .sw-cursor-dot {
  background: var(--swc-bg);
  border-color: var(--swc-bg);
}

/* ------------------------------------------------------------
   Tone - accent wording on something that does not click

   is-active above flips the WHOLE tag to an accent plate, which is
   the language for "this is interactive". Some labels want the
   accent without that promise: the footer wordmark is the studio's
   own name, not a link.

   So this keeps the dark plate and puts the green on the type
   instead. Set with [data-cursor-tone="accent"] on the target; the
   script mirrors it to data-tone on the root (js/cursor.js).

   Guarded against is-active, which would otherwise leave green type
   on a green plate if a tone ever landed on a link.
   ------------------------------------------------------------ */
.sw-cursor[data-tone="accent"]:not(.is-active) .sw-cursor-label-inner {
  color: var(--swc-accent);
}

/* On a link the tone wins over the accent plate: dark plate, green
   type (the work-table images). Keeps the plate dark so it is never
   green on green. */
.sw-cursor.is-active[data-tone="accent"] .sw-cursor-label-inner {
  background: var(--swc-bg);
  color: var(--swc-accent);
}

.sw-cursor-text {
  display: block;
  white-space: nowrap;
  /* The box animates its width around this line, so the line must not
     be squeezed by it mid-tween - otherwise the incoming wording is
     clipped from the right while the box is still catching up. */
  width: max-content;
}

/* One per word, so the swap can stagger them (js/cursor.js). */
.sw-cursor-word {
  display: inline-block;
  will-change: transform;
}

/* ------------------------------------------------------------
   No trailing label where there is no pointer to trail, and none
   for anyone who asked for less motion.
   ------------------------------------------------------------ */
@media (pointer: coarse), (prefers-reduced-motion: reduce) {
  .sw-cursor {
    display: none;
  }
}

/* Fill tone - the accent plate without the link promise. The
   featured work list is browsed by hover, not clicked, but its
   label wears the same green plate as the work page's pictures.
   Set with [data-cursor-tone="fill"]. */
.sw-cursor[data-tone="fill"] .sw-cursor-label-inner {
  background: var(--swc-accent);
  color: #14140f;
}
