/* Custom cursor */
.custom-cursor {
    position: fixed;
    /* Required. Position is applied as a transform (see cursor.js), which
       offsets from this element's static position — and as the last child of
       <body> that sits a full viewport below the origin. Anchoring to 0,0
       makes the transform absolute against the viewport. */
    left: 0;
    top: 0;
    width: 10.5px;
    height: 10.5px;
    background: #ffffff;
    border-radius: 50%;
    pointer-events: none;
    z-index: 9999;
    mix-blend-mode: normal; /* Default blend mode */
    box-shadow: 0 0 1px #ffffff;
    opacity: 1;
    /* mix-blend-mode is not an animatable property; it was a no-op here. */
    transition:
        opacity 0.3s ease,
        width 0.3s ease,
        height 0.3s ease,
        border-radius 0.3s ease;
    font-family: "JetBrains Mono", monospace;
    font-size: 0.9rem;
    color: #ffffff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    font-weight: 500;
    letter-spacing: 0.05em;
    line-height: 1.2;
    /* Position is driven by cursor.js as a single transform (see setPosition);
       this is just the pre-first-move resting state. */
    transform: translate3d(0, 0, 0) translate(-50%, -50%);
}

/* Hide cursor when not hovering over the document */
body:not(:hover) .custom-cursor,
body.window-inactive .custom-cursor {
    opacity: 0;
}

/* Same-origin embeds (Metamorph3D) get their native cursor killed and their
   mousemove mirrored onto the parent page by site-preview.js, so the one
   custom-cursor dot keeps tracking right across the iframe boundary - no
   rule needed here for that case.

   Cross-origin embeds (oradin.io) can't be reached by same-origin policy:
   no killing its native cursor, no mirroring its mousemove. The lightbox
   gets a `lightbox-cross-origin` class for that case, and the only options
   left are showing two cursors at once or hiding ours while over the iframe
   so its own real cursor shows. Scoped to :hover on the iframe itself (not
   the whole lightbox/backdrop) - otherwise moving into the backdrop around
   the frame hid both the custom dot AND the native cursor (forced off by
   the `*` rule below), leaving no visible cursor at all outside the frame. */
body:has(.site-preview-lightbox.lightbox-cross-origin #sitePreviewLightboxIframe:hover)
    .custom-cursor {
    opacity: 0 !important;
}

/* Hide the system cursor everywhere.
   This has to be a universal !important: styles.css sets `cursor: pointer` on
   ~11 interactive elements (.ai-button, .nav-item, buttons, links, swatches),
   and those class-level rules beat both inheritance from body and any plain
   element selector — which is what let the system hand show through.
   Dropping the old chain's four :not() negations keeps the same result
   without making the style engine evaluate them against every node; the
   text-field exceptions below win on specificity instead. */
* {
    cursor: none !important;
}

/* Allow native text cursor on input and textarea fields.
   Higher specificity than `*`, so these win despite both being !important. */
.form-input,
.form-textarea,
input,
textarea {
    cursor: text !important;
}

/* Restore user-select on form fields */
.form-input,
.form-textarea,
input[type="email"],
textarea {
    user-select: text !important;
    -webkit-user-select: text !important;
    -moz-user-select: text !important;
}

/* Touch/mobile/tablet: no real pointer exists, so the custom dot and the
   hidden system cursor both just add a dead element and dead styling.
   (hover: none) is the reliable signal, unlike UA sniffing. */
@media (hover: none), (pointer: coarse) {
    * {
        cursor: auto !important;
    }

    .custom-cursor {
        display: none !important;
    }
}
