﻿/* CANVAS */
body.boot-loading-active {
    overflow: hidden;
}

#boot-loading-overlay.boot-loading-overlay {
    position: fixed;
    inset: 0;
    z-index: 2147483647;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(4, 8, 18, 0.35);
    backdrop-filter: blur(28px) saturate(145%);
    -webkit-backdrop-filter: blur(28px) saturate(145%);
    opacity: 1;
    visibility: visible;
    pointer-events: all;
    transition: opacity 0.22s ease, visibility 0s linear 0s;
}

#boot-loading-overlay.boot-loading-overlay.is-hidden {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.22s ease, visibility 0s linear 0.22s;
}

.boot-loading-card {
    width: min(440px, 92vw);
    border-radius: 18px;
    padding: 24px 22px;
    border: 1px solid rgba(255, 255, 255, 0.25);
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.3), rgba(230, 236, 250, 0.2));
    box-shadow: 0 22px 52px rgba(0, 0, 0, 0.35);
    color: #0f172a;
    text-align: center;
    transform: translateY(0) scale(1);
    transition: transform 0.2s ease, opacity 0.2s ease;
}

.boot-loading-overlay.is-complete .boot-loading-card {
    transform: translateY(-4px) scale(0.985);
    opacity: 0.98;
}

.boot-loading-spinner {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 3px solid rgba(15, 23, 42, 0.18);
    border-top-color: rgba(15, 23, 42, 0.88);
    margin: 0 auto 14px;
    animation: boot-loading-spin 0.8s linear infinite;
}

.boot-loading-title {
    margin: 0;
    font-size: 1.12rem;
    font-weight: 700;
    letter-spacing: 0.01em;
}

.boot-loading-subtitle {
    margin-top: 8px;
    margin-bottom: 16px;
    font-size: 0.92rem;
    color: rgba(15, 23, 42, 0.72);
}

.boot-loading-bar {
    height: 10px;
    border-radius: 999px;
    background: rgba(15, 23, 42, 0.14);
    overflow: hidden;
}

.boot-loading-progress {
    width: 8%;
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, #2563eb, #3b82f6 55%, #60a5fa);
    transition: width 0.12s linear;
}

@keyframes boot-loading-spin {
    to {
        transform: rotate(360deg);
    }
}

@media (prefers-reduced-motion: reduce) {
    .boot-loading-spinner {
        animation: none;
    }

    .boot-loading-progress,
    #boot-loading-overlay.boot-loading-overlay,
    .boot-loading-card {
        transition: none;
    }
}

#canvas-viewport {
    position: absolute;
    top: var(--header-height);
    left: 0;
    width: 100%;
    height: calc(100% - var(--header-height));
    overflow: hidden;
    z-index: var(--z-canvas);
    cursor: default;
    touch-action: none;
    /* Prevent browser zooming/scrolling */
}

/* Disable browser selection on all canvas content by default */
#canvas-content,
#canvas-content * {
    user-select: none !important;
    -webkit-user-select: none !important;
}

/* Enable selection ONLY when actively editing text (element is focused) */
#canvas-content .text-editor:focus,
#canvas-content .code-editor:focus,
#canvas-content .chk-text:focus,
#canvas-content .note-title[contenteditable="true"] {
    user-select: text !important;
    -webkit-user-select: text !important;
}

/* Optimization: Disable hit testing during pan */
#canvas-viewport.is-panning #canvas-content {
    pointer-events: none;
}

#canvas-content {
    position: absolute;
    top: 0;
    left: 0;
    width: 50000px;
    height: 50000px;
    /* Dynamic grid using CSS custom properties - can be overridden per-project */
    --page-bg: var(--bg-color);
    --page-grid-color: var(--grid-color);
    --page-grid-size: 40px;
    background-color: var(--page-bg);
    background-image: linear-gradient(var(--page-grid-color) 1px, transparent 1px), linear-gradient(90deg, var(--page-grid-color) 1px, transparent 1px);
    background-size: var(--page-grid-size) var(--page-grid-size);
    transform-origin: 0 0;
    contain: layout style;
    /* Isolates layout/style recalculations */
}

/* Optimization: Hide dense grid at low zoom to save GPU and reduce visual noise */
#canvas-content.lod-minimal {
    background-image: none !important;
}

/* Connection lines layer - sits behind drawings and notes */
#connection-layer {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

.connection-line {
    stroke: var(--text-secondary);
    pointer-events: none;
}

#drawing-layer {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
    pointer-events: none;
}

#hover-layer {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10000;
    pointer-events: none;
}

#interaction-layer {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10000;
    display: none;
    cursor: crosshair;
    pointer-events: none;
}

#interaction-layer[style*="display: block"],
#interaction-layer[style*="display:block"] {
    pointer-events: all;
}

/* When drawing tools are active, prevent text selection on canvas content */
body.drawing-active #canvas-content .note {
    user-select: none;
    -webkit-user-select: none;
    pointer-events: none;
}
body.drawing-active #canvas-content .note .note-body,
body.drawing-active #canvas-content .note .note-header {
    pointer-events: none;
}

.drawn-line {
    pointer-events: auto;
    cursor: pointer;
    /* fill: none; Removed to allow SVG fill attribute to work */
    stroke-linecap: round;
    stroke-linejoin: round;
    /* Removed transition to prevent global flicker on selection */
    /* Each line is isolated to its own compositing layer */
    /* will-change removed to save memory unless interactive */
}

.drawn-line.dynamic-ink {
    stroke: var(--ink-color);
}

.hover-path-preview {
    fill: none;
    stroke: var(--accent-color);
    stroke-opacity: 0.9;
    pointer-events: none;
}

.selected-line {
    /* Use only filter for selection highlight - purely GPU composited, no layout recalc */
    /* Both radii use CSS vars so they can be compensated for SVG scale (filters operate in local coords) */
    filter: drop-shadow(0 0 var(--glow-radius, 4px) var(--accent-color)) drop-shadow(0 0 var(--glow-radius-inner, 1px) var(--accent-color)) !important;
    will-change: filter;
}

/* Selection Gizmo */
#selection-gizmo {
    position: absolute;
    pointer-events: none;
    cursor: move;
    display: none;
    border: 1.5px solid var(--accent-color);
    z-index: 10001;
    will-change: left, top, width, height, transform;
    contain: layout style;
}

/* GPU layer promotion for gizmo handles to prevent rendering artifacts */
.gizmo-handle {
    position: absolute;
    width: 12px;
    height: 12px;
    background: white;
    border: 2px solid var(--accent-color);
    border-radius: 3px;
    pointer-events: auto;
    will-change: transform;
    backface-visibility: hidden;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    transition: box-shadow 0.15s ease;
}

.gizmo-handle:hover {
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);
}

.handle-tl {
    top: -7px;
    left: -7px;
    cursor: nwse-resize;
}

.handle-tr {
    top: -7px;
    right: -7px;
    cursor: nesw-resize;
}

.handle-bl {
    bottom: -7px;
    left: -7px;
    cursor: nesw-resize;
}

.handle-br {
    bottom: -7px;
    right: -7px;
    cursor: nwse-resize;
}

.handle-rot {
    top: -28px;
    left: 50%;
    transform: translateX(-50%);
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--accent-color);
    border: 2px solid white;
    cursor: grab;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}

#vertex-handle-layer {
    position: absolute;
    inset: 0;
    z-index: 10002;
    pointer-events: none;
}

.vertex-handle {
    position: absolute;
    width: 12px;
    height: 12px;
    margin-left: -6px;
    margin-top: -6px;
    border-radius: 50%;
    border: 2px solid var(--accent-color);
    background: var(--surface-color);
    box-shadow: 0 1px 3px rgba(0,0,0,0.2), 0 0 0 2px rgba(var(--accent-rgb), 0.16);
    pointer-events: auto;
    cursor: grab;
    will-change: left, top;
}

.vertex-handle:active {
    cursor: grabbing;
}

#selection-box {
    position: absolute;
    border: 1px dashed var(--accent-color);
    background: rgba(0, 122, 204, 0.1);
    display: none;
    pointer-events: none;
    z-index: 10002;
    transform-origin: 0 0;
    /* GPU compositing to prevent repaint artifacts during rapid updates */
    will-change: left, top, width, height;
    contain: strict;
}

.selected-line {
    /* Use only filter for selection highlight - purely GPU composited, no layout recalc */
    /* Both radii use CSS vars so they can be compensated for SVG scale (filters operate in local coords) */
    filter: drop-shadow(0 0 var(--glow-radius, 4px) var(--accent-color)) drop-shadow(0 0 var(--glow-radius-inner, 1px) var(--accent-color)) !important;
    /* Smooth fade in/out of glow */
    transition: filter 0.1s ease-out;
    will-change: filter;
}

/* When transforming, fade out the glow smoothly */
.selected-line.transforming {
    filter: drop-shadow(0 0 0 transparent) drop-shadow(0 0 0 transparent) !important;
}

/* Fix for rendering glitches/ghosting when transforming notes */
.note.transforming {
    /* Promote to GPU layer and disable anti-aliasing jitter */
    will-change: transform, width, height, left, top;
    backface-visibility: hidden;
    transform: translateZ(0);
    /* Force hardware accel */
    /* Fix: "Repaint Hack" - Large transparent shadow forces browser to invalidate wider area */
    box-shadow: 0 0 0 50px rgba(0, 0, 0, 0) !important;
    outline: 1px solid transparent;
    /* Eat sub-pixel artifacts */
    outline: 1px solid transparent;
    /* Eat sub-pixel artifacts */

    /* Corner rendering fixes */
    background-clip: padding-box;
    isolation: isolate;
    /* Create new stacking context */
    overflow: hidden !important;
    /* Clip content strictly during transform */
}

/* Ensure children don't cause flickering */
.note.transforming * {
    backface-visibility: hidden;
    pointer-events: none;
}

#eraser-cursor {
    position: fixed;
    width: 30px;
    height: 30px;
    border: 2px solid rgba(255, 0, 0, 0.5);
    background: rgba(255, 0, 0, 0.1);
    border-radius: 50%;
    pointer-events: none;
    z-index: 20000;
    transform: translate(-50%, -50%);
    display: none;
}

#size-indicator-cursor {
    position: fixed;
    width: 10px;
    height: 10px;
    box-sizing: border-box;
    /* Include border in size calculation */
    border: 2px solid var(--accent-color);
    background: rgba(0, 122, 204, 0.2);
    border-radius: 50%;
    pointer-events: none;
    z-index: 20000;
    transform: translate(-50%, -50%);
    display: none;
    transition: width 0.05s, height 0.05s;
}

/* ============================================
   HIGH PERFORMANCE OPTIMIZATIONS
   ============================================ */

/* Base optimization: Allow browser to skip rendering off-screen notes */
.note {
    content-visibility: auto;
    contain-intrinsic-size: 200px 300px;
}

/* Notes with custom borders need overflow:visible - the border (SVG stroke or
   ::after pseudo-element) extends beyond note bounds. content-visibility:auto
   creates implicit contain:paint which clips that overflow. */
.note.has-custom-border {
    content-visibility: visible;
}

/* Virtualized notes (completely off-screen at low zoom) */
/* Virtualized notes (completely off-screen at low zoom) */
.note.virtualized {
    visibility: hidden;
    /* content-visibility: hidden; replaced with visibility: hidden to preserve layout size for intersection observer */
}

/* Dragging optimization - promote to GPU layer */
.note.dragging {
    will-change: transform, left, top;
}

.note.dragging .note-body {
    pointer-events: none;
}

/* ============================================
   4-TIER LEVEL OF DETAIL (LOD) SYSTEM
   ============================================ */

/* LOD Tier: Full (>80% zoom) - All details visible, no special rules needed */

/* LOD Tier: Medium (40-80% zoom) - Slightly simplified */
.lod-medium .note {
    /* Performance: Remove shadow to reduce GPU fill rate cost */
    box-shadow: none !important;
}

.lod-medium .sticky-note.sticky-diamond .note-body,
.lod-medium .sticky-note.sticky-heart .note-body,
.lod-medium .sticky-note.sticky-hexagon .note-body,
.lod-medium .sticky-note.sticky-speech-bubble .note-body {
    filter: none !important;
}

.lod-medium .code-editor,
.lod-medium .text-editor {
    font-size: 0.85em;
}

.lod-medium .line-numbers {
    display: none;
}

.lod-medium .chk-delete-btn {
    display: none;
}

/* LOD Tier: Low (20-40% zoom) - Significant simplification */
.lod-low .note {
    /* Performance: Remove shadow and radius to simplify compositing */
    box-shadow: none !important;
    border-radius: 0 !important;
    border: 1px solid var(--grid-color);
    /* Simpler border */
}

.lod-low .sticky-note.sticky-diamond .note-body,
.lod-low .sticky-note.sticky-heart .note-body,
.lod-low .sticky-note.sticky-hexagon .note-body,
.lod-low .sticky-note.sticky-speech-bubble .note-body {
    filter: none !important;
}

.lod-low .note-header {
    border-radius: 0 !important;
}


.lod-low .code-editor,
.lod-low .text-editor {
    font-size: 0.7em;
    line-height: 1.2;
}

.lod-low .line-numbers {
    display: none;
}

.lod-low .chk-checkbox,
.lod-low .chk-delete-btn {
    display: none;
}

.lod-low .voice-waveform {
    display: none;
    /* Hide complex waveform canvas completely */
}

/* Disable interaction on non-header children in Low LOD to save hit-test CPU */
.lod-low .note .note-body {
    pointer-events: none;
}

.lod-low .drawn-line {
    shape-rendering: optimizeSpeed;
    /* Disable anti-aliasing for lines */
    pointer-events: none;
    /* Make lines click-through in low detail */
}

/* Ensure note itself is still selectable */
.lod-low .note {
    pointer-events: auto;
}

.lod-low .voice-note-container::before {
    content: 'Voice Note';
    display: block;
    text-align: center;
    color: var(--text-secondary);
}

/* LOD Tier: Minimal (<20% zoom) - Bounding boxes only */
.lod-minimal .note-body {
    display: none;
    /* Use display: none instead of visibility: hidden to skip layout/paint entirely */
}

.lod-minimal .note {
    min-height: 40px;
    background: var(--bg-secondary);
    /* Ensure it has a background since body is gone */
    border: 1px solid var(--border-color);
}

.lod-minimal .note::after {
    /* Colored block representation */
    content: '';
    position: absolute;
    inset: 4px;
    background: var(--accent-color);
    border-radius: 2px;
    opacity: 0.2;
}

.lod-minimal .img-wrapper img {
    opacity: 0.3;
    filter: blur(2px);
}

.lod-minimal .img-wrapper img {
    opacity: 0.3;
    filter: blur(2px);
}

/* Optimization: Hides off-screen elements completely at low zoom */
/* .virtualized rule removed as it was destructive */

/* Drawing LOD Optimization (backwards compatible) */
.low-detail-mode .drawn-line {
    shape-rendering: optimizeSpeed;
    /* Keep stroke-linecap: round (the default) - setting 'butt' makes
       zero-length paths (dots/points) invisible because butt caps have
       no extent on a zero-length segment. */
    stroke-linejoin: bevel;
}

.low-detail-mode .drawn-line.dynamic-ink {
    filter: none !important;
}

/* Lazy loading placeholder styling */
.note[data-type="image"] img[data-loading="true"] {
    opacity: 0.5;
}

.note[data-type="image"] img:not([data-loaded="true"]) {
    background: var(--grid-color);
    min-height: 100px;
}

/* ============================================
   DROP OVERLAY
   ============================================ */
#drop-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.2);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: var(--z-drop-overlay);
    display: none;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
}

#drop-overlay.visible {
    display: flex;
    opacity: 1;
}

.drop-overlay-content {
    background: var(--header-bg);
    border: 2px dashed var(--accent-color);
    padding: 40px 60px;
    border-radius: var(--radius-xl);
    text-align: center;
    box-shadow: var(--shadow-xl);
    transform: scale(0.9);
    transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.320, 1.275);
    backdrop-filter: var(--backdrop-blur);
    -webkit-backdrop-filter: var(--backdrop-blur);
}

#drop-overlay.visible .drop-overlay-content {
    transform: scale(1);
}

.drop-icon {
    width: 64px;
    height: 64px;
    color: var(--accent-color);
    margin-bottom: 20px;
    animation: bounce 2s infinite ease-in-out;
}

@keyframes bounce {

    0%,
    100% {
        transform: translateY(0);
    }

    50% {
        transform: translateY(-10px);
    }
}

.drop-overlay-content h2 {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text-primary);
}

.drop-overlay-content p {
    margin: 10px 0 0 0;
    color: var(--text-secondary);
    font-size: 1rem;
}

/* Blur effect for main app content when overlay is active */
body.drag-active #canvas-viewport,
body.drag-active #app-header,
body.drag-active #floating-dock,
body.drag-active #options-bar,
body.drag-active #bottom-toolbar {
    filter: blur(4px);
    transition: filter 0.3s ease;
}




.note.selected .pdf-interaction-overlay {
    cursor: default;
}
