/* interact.css - on-page interaction chrome (interact.js): selection boxes and handles,
   hover outlines, rubber band, snap guides, drawing / placement ghosts, read-out badges,
   and the pointer cursors / touch behaviour of each tool (body[data-tool], [data-tool-kind]).

   Everything lives inside a page's .tool-layer, i.e. inside .page-space where 1 CSS px =
   1 pt and the page is scaled by var(--s). Anything that must keep a constant on-screen
   size divides by var(--s). */

/* ------------------------------------------------------------------ containers */

.sel-root,
.sel-fx {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
    --hs: 9px;          /* handle size on screen */
    --hit: 5px;         /* extra invisible grab margin around handles */
    --rot-off: 22px;    /* distance of the rotation handle above the box */
}

@media (pointer: coarse) {
    .sel-root { --hs: 14px; --hit: 9px; --rot-off: 30px; }
}

/* ------------------------------------------------------------------ selection */

.sel-box,
.sel-group,
.sel-hover,
.rubber,
.tool-layer .ghost,     /* scoped: ui.js buttons carry .ghost too (the default variant) */
.sel-line,
.handle,
.sel-stem,
.snap-guide,
.sel-badge,
.sel-eraser,
.sel-draw {
    position: absolute;
    box-sizing: border-box;
}

.sel-box {
    box-shadow: 0 0 0 calc(1.25px / var(--s)) var(--select);
    pointer-events: auto;           /* a finger can drag the selection without scrolling */
    touch-action: none;
}
.sel-box.locked {
    box-shadow: none;
    outline: calc(1.25px / var(--s)) dashed var(--select);
    outline-offset: calc(1px / var(--s));
}
.sel-root.multi .sel-box {
    box-shadow: 0 0 0 calc(1px / var(--s)) var(--select);
    background: var(--select-soft);
}

.sel-group {
    outline: calc(1px / var(--s)) dashed var(--select);
    outline-offset: calc(4px / var(--s));
}

.sel-line {
    height: calc(14px / var(--s));
    margin-top: calc(-7px / var(--s));
    transform-origin: 0 50%;
    pointer-events: auto;
    touch-action: none;
}
.sel-line::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    border-top: calc(1.25px / var(--s)) dashed var(--select);
}

/* handles: constant screen size, centred on their anchor */
.handle {
    width: calc(var(--hs) / var(--s));
    height: calc(var(--hs) / var(--s));
    transform: translate(-50%, -50%);
    background: var(--paper);
    border: calc(1.25px / var(--s)) solid var(--select);
    border-radius: calc(2px / var(--s));
    pointer-events: auto;
    touch-action: none;
}
.handle::after {
    content: "";
    position: absolute;
    inset: calc(var(--hit) / var(--s) * -1);
}
/* A box only about three handle-widths across (a check mark, a dot) would be buried under its
   own handles and their grab margins, so nothing would be left to press to move it. Its
   handles (interact.js isTiny) sit just outside instead and the body stays draggable. */
.tiny { --off: calc(var(--hs) / var(--s) / 2); }
.tiny > .handle::after { display: none; }
.tiny > .h-nw { margin: calc(var(--off) * -1) 0 0 calc(var(--off) * -1); }
.tiny > .h-n  { margin-top: calc(var(--off) * -1); }
.tiny > .h-ne { margin: calc(var(--off) * -1) 0 0 var(--off); }
.tiny > .h-e  { margin-left: var(--off); }
.tiny > .h-se { margin: var(--off) 0 0 var(--off); }
.tiny > .h-s  { margin-top: var(--off); }
.tiny > .h-sw { margin: var(--off) 0 0 calc(var(--off) * -1); }
.tiny > .h-w  { margin-left: calc(var(--off) * -1); }
.h-nw { left: 0;    top: 0; }
.h-n  { left: 50%;  top: 0; }
.h-ne { left: 100%; top: 0; }
.h-e  { left: 100%; top: 50%; }
.h-se { left: 100%; top: 100%; }
.h-s  { left: 50%;  top: 100%; }
.h-sw { left: 0;    top: 100%; }
.h-w  { left: 0;    top: 50%; }
.h-pt,
.h-rot { border-radius: 50%; }
.h-rot {
    left: 50%;
    top: calc(var(--rot-off) / var(--s) * -1);
    background: var(--select);
    border-color: var(--paper);
}
.sel-stem {
    left: 50%;
    top: calc(var(--rot-off) / var(--s) * -1);
    height: calc(var(--rot-off) / var(--s));
    width: 0;
    border-left: calc(1px / var(--s)) solid var(--select);
    pointer-events: none;
}

/* While a text object is being typed into, its box must not swallow clicks in the editor. */
body:has(#pages textarea:focus) .sel-box { pointer-events: none; }
body:has(#pages textarea:focus) .sel-root .handle,
body:has(#pages textarea:focus) .sel-root .sel-stem { display: none; }

/* ------------------------------------------------------------------ feedback */

.sel-hover {
    box-shadow: 0 0 0 calc(1px / var(--s)) var(--select);
    opacity: 0.55;
}

.rubber {
    border: calc(1px / var(--s)) solid var(--select);
    background: var(--select-soft);
}

.snap-guide.v {
    width: 0;
    border-left: calc(1px / var(--s)) dashed var(--select);
}
.snap-guide.h {
    height: 0;
    border-top: calc(1px / var(--s)) dashed var(--select);
}

.tool-layer .ghost {
    pointer-events: none;
    outline: calc(1px / var(--s)) dashed var(--select);
    outline-offset: calc(1px / var(--s));
}
.tool-layer .ghost.sel-drawing { outline-style: solid; }

.sel-draw {
    left: 0;
    top: 0;
    overflow: visible;
    pointer-events: none;
}

.sel-badge {
    transform-origin: 0 0;
    padding: 3px 6px;
    border-radius: var(--radius-xs);
    background: var(--select);          /* orange like the selection it measures; readable on the white page in both themes */
    color: var(--marker-text);
    font: 500 11px/1.2 var(--font-mono);
    white-space: nowrap;
    box-shadow: var(--shadow-1);
    pointer-events: none;
}

.sel-eraser {
    width: calc(12px / var(--s));
    height: calc(12px / var(--s));
    transform: translate(-50%, -50%);
    border-radius: 50%;
    border: calc(1.5px / var(--s)) solid var(--text);
    box-shadow: 0 0 0 calc(1px / var(--s)) var(--paper);
    pointer-events: none;
}

/* screen-reader announcements ("Text selected") */
.sel-live {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ------------------------------------------------------------------ cursors */
/* Cursor images are pointer glyphs, black with a white halo so they read on any page. */

body[data-tool-kind="click"] #pages .page,
body[data-tool-kind="drag-box"] #pages .page,
body[data-tool-kind="drag-line"] #pages .page { cursor: crosshair; }

body[data-tool="text"] #pages .page { cursor: text; }

body[data-tool-kind="custom"] #pages .page { cursor: var(--tool-cursor, crosshair); }

body[data-tool-kind="ink"] #pages .page {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z' stroke='white' stroke-width='3.5'/%3E%3Cpath d='M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z' stroke='black' stroke-width='1.5'/%3E%3C/svg%3E") 2 22, crosshair;
}

body[data-tool-kind="eraser"] #pages .page {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none'%3E%3Ccircle cx='12' cy='12' r='7' stroke='white' stroke-width='3.5'/%3E%3Ccircle cx='12' cy='12' r='7' stroke='black' stroke-width='1.5'/%3E%3C/svg%3E") 12 12, cell;
}

body[data-tool-kind="hand"] #pages .page,
body[data-tool-kind="hand"] #pages .page * { cursor: grab; }
body[data-space]:not([data-gesture]) #pages,
body[data-space]:not([data-gesture]) #pages * { cursor: grab !important; }

body[data-placing] #pages .page { cursor: copy; }

body[data-tool-kind="select"][data-hover="obj"] #pages .page,
body[data-tool-kind="select"] .sel-box,
body[data-tool-kind="select"] .sel-line { cursor: move; }
body[data-tool-kind="select"] .sel-box.locked,
body[data-tool-kind="select"] .sel-line.locked { cursor: default; }

.cur-ns   { cursor: ns-resize; }
.cur-ew   { cursor: ew-resize; }
.cur-nesw { cursor: nesw-resize; }
.cur-nwse { cursor: nwse-resize; }
.cur-move { cursor: move; }
.cur-rot {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8M21 3v5h-5' stroke='white' stroke-width='4'/%3E%3Cpath d='M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8M21 3v5h-5' stroke='black' stroke-width='1.75'/%3E%3C/svg%3E") 11 11, grab;
}

/* During a drag #pages captures the pointer; the cursor the drag started with (handle,
   tool, move, grabbing) is pinned through --gesture-cursor, set by interact.js. */
body[data-gesture] #pages,
body[data-gesture] #pages * { cursor: var(--gesture-cursor, auto) !important; }

/* No accidental text selection or native drags while a gesture runs. */
body[data-gesture] {
    -webkit-user-select: none;
    user-select: none;
}

/* ------------------------------------------------------------------ touch */
/* Drawing and creation tools own one-finger drags on the page (interact.js pans with two).
   Select and click tools keep native one-finger scrolling; the selection box and handles
   opt out individually (above). */

body[data-tool-kind="ink"] #pages .page,
body[data-tool-kind="eraser"] #pages .page,
body[data-tool-kind="drag-box"] #pages .page,
body[data-tool-kind="drag-line"] #pages .page,
body[data-tool-kind="custom"] #pages .page,
body[data-placing] #pages .page { touch-action: none; }
