/* PQC tickets cursor: a lattice point and its error vector.
   The trail points snap to a fixed grid rather than following smoothly — a
   lattice has discrete positions, and the short offset between where a point
   lands and where it ideally sits is the whole intuition ML-KEM rests on. */

.pt-cursor {
    position: fixed;
    top: 0;
    left: 0;
    width: 12px;
    height: 12px;
    margin: -6px 0 0 -6px;
    z-index: 9999;
    pointer-events: none;
    border-radius: 50%;
    background: rgba(167, 139, 250, 0.55);
    box-shadow: 0 0 0 1px rgba(125, 211, 252, 0.6);
    transition: transform 0.12s ease-out, background 0.2s ease;
    will-change: transform;
}

.pt-cursor-active {
    transform: scale(1.6);
    background: rgba(52, 211, 153, 0.6);
}

/* A lattice site the trail has snapped to. */
.pt-cursor-node {
    position: fixed;
    top: 0;
    left: 0;
    width: 4px;
    height: 4px;
    margin: -2px 0 0 -2px;
    z-index: 9998;
    pointer-events: none;
    border-radius: 50%;
    background: rgba(125, 211, 252, 0.7);
    will-change: transform, opacity;
}

/* The error vector: the offset between the true position and the lattice site. */
.pt-cursor-err {
    position: fixed;
    top: 0;
    left: 0;
    height: 1px;
    z-index: 9997;
    pointer-events: none;
    transform-origin: 0 50%;
    background: rgba(167, 139, 250, 0.4);
    will-change: transform, opacity, width;
}

/* ── Hiding the native pointer ──────────────────────────────────────── */
/*
 * Gated behind a class the cursor script adds to <body> once its elements are
 * in the DOM, never applied from CSS alone. If the script fails to load or
 * throws, the class is never set and the real pointer stays — a page that hides
 * the system cursor and then does not draw a replacement is unusable, and CSS
 * has no way to know whether the replacement arrived.
 *
 * The universal selector is deliberate: `cursor` is not inherited in the way
 * that matters here — links, buttons and resizable edges all set their own, so
 * hiding it on `body` alone leaves the arrow reappearing over exactly the
 * elements people move toward.
 */
.pt-cursor-on,
.pt-cursor-on * {
    cursor: none;
}

/*
 * Text entry keeps the real caret. A custom dot gives no indication of where a
 * character will land, and these are fields people actually type into.
 */
.pt-cursor-on input[type="text"],
.pt-cursor-on input[type="search"],
.pt-cursor-on input[type="email"],
.pt-cursor-on input[type="password"],
.pt-cursor-on textarea {
    cursor: text;
}

@media (pointer: coarse) {
    .pt-cursor,
    .pt-cursor-node,
    .pt-cursor-err {
        display: none;
    }
}
