/* edet-board.css — the visual board layer (edet-board.js). Cards live inside
   .dr-canvas so they pan/zoom with the page+grid; grid-desk only. The layer is
   pointer-events:none so empty board area falls through to the page (edit) or
   the host (pan) — only cards capture input. Tokens from site.css. */
.dr-board { display: none; }

/* Show/Hide paper (View panel + grid right-click). Hiding the page gives an
   empty grid board; it's only meaningful on the grid desk. Kept in layout
   (visibility) so the canvas geometry + deskRecenter anchor are unchanged. */
.edet-app[data-editor-mode="wysiwyg"][data-desk="grid"][data-show-paper="hide"] .ProseMirror { visibility: hidden; }
/* With the paper hidden, the text→card DOTTED anchor lines point at nothing (the
   text/page is gone) — hide them too. Card→card connectors stay (cards remain). */
.edet-app[data-show-paper="hide"] .dr-board-anchor-g { display: none; }

.edet-app[data-editor-mode="wysiwyg"][data-desk="grid"] .dr-board {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 2;              /* above the page (.ProseMirror) */
    pointer-events: none;    /* empty board click → page/host beneath */
}

/* Empty-board discoverability hint — centered in the viewport, gated to the grid
   desk (same condition as the board layer) so it never shows while writing flat.
   Appended to #dr-editor-host (untransformed) by renderEmptyHint(). */
.dr-board-empty { display: none; }
.edet-app[data-editor-mode="wysiwyg"][data-desk="grid"] .dr-board-empty {
    display: block;
    position: absolute;
    left: 50%;
    top: 44%;
    transform: translate(-50%, -50%);
    z-index: 3;
    width: min(24rem, 82vw);
    text-align: center;
    pointer-events: none;
}
.dr-board-empty-inner {
    pointer-events: auto;
    background: var(--edet-glass, color-mix(in srgb, var(--bg) 60%, transparent));
    backdrop-filter: var(--edet-blur, blur(9px)) saturate(115%);
    -webkit-backdrop-filter: var(--edet-blur, blur(9px)) saturate(115%);
    border: 1px solid var(--rule);
    border-radius: 12px;
    padding: 1.1rem 1.2rem 1.2rem;
    box-shadow: var(--shadow-lg, 0 10px 40px rgba(0,0,0,.35));
}
.dr-board-empty-inner strong { display: block; font-size: var(--text-md); color: var(--fg); margin-bottom: 0.4rem; }
.dr-board-empty-inner p { margin: 0 0 0.9rem; color: var(--fg-muted); font-size: var(--text-sm); line-height: 1.5; }

.dr-board-card {
    position: absolute;
    width: 240px;
    box-sizing: border-box;
    pointer-events: auto;
    background: var(--bg-elevated);
    border: 1px solid color-mix(in srgb, var(--fg) 10%, transparent);
    border-radius: 12px;
    box-shadow: var(--shadow-md);
    color: var(--fg);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    cursor: grab;
    user-select: none;
    touch-action: none;
    overflow: hidden;
    /* flex column so a resized (explicit) height grows the body; with no height set
       it's content-sized, identical to before. */
    display: flex;
    flex-direction: column;
    transition: box-shadow var(--dur-fast) var(--ease-smooth), transform var(--dur-fast) var(--ease-smooth);
}
.dr-board-card .dr-board-body { flex: 1 1 auto; min-height: 0; }
.dr-board-card:hover { box-shadow: var(--shadow-lg); }
.dr-board-card.is-dragging { cursor: grabbing; transform: scale(1.02); box-shadow: var(--shadow-lg); }
.dr-board-card.is-resizing { box-shadow: var(--shadow-lg); }
/* bottom-right resize handle — a quiet corner that brightens on hover */
.dr-board-resize {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 16px;
    height: 16px;
    cursor: nwse-resize;
    z-index: 2;
    opacity: 0;
    transition: opacity var(--dur-fast) var(--ease-smooth);
    background:
        linear-gradient(135deg, transparent 0 50%, color-mix(in srgb, var(--fg) 45%, transparent) 50% 60%, transparent 60% 72%, color-mix(in srgb, var(--fg) 45%, transparent) 72% 82%, transparent 82%);
}
.dr-board-card:hover .dr-board-resize, .dr-board-card.is-resizing .dr-board-resize { opacity: 1; }
.dr-board-card.kind-ref { border-left: 3px solid var(--accent); }
.dr-board-card.is-missing .dr-board-headtitle { text-decoration: line-through; opacity: 0.7; }
.dr-board-card.is-linking { outline: 2px solid var(--accent); outline-offset: 2px; }

/* header = a quiet drag rail; grip + actions fade in on hover (Apple-clean) */
.dr-board-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    height: 26px;
    padding: 0 0.5rem;
    color: var(--fg-muted);
    font-size: var(--text-xs);
}
.dr-board-card:not(.kind-note):not(.kind-ref) .dr-board-head { border-bottom: 1px solid color-mix(in srgb, var(--fg) 8%, transparent); }
.dr-board-grip { letter-spacing: -1px; opacity: 0; transition: opacity var(--dur-fast) var(--ease-smooth); cursor: grab; }
.dr-board-card:hover .dr-board-grip { opacity: 0.5; }
.dr-board-glyph { flex: 0 0 auto; color: var(--accent); }
.dr-board-headtitle { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.dr-board-acts { flex: 0 0 auto; display: inline-flex; gap: 0.15rem; opacity: 0; transition: opacity var(--dur-fast) var(--ease-smooth); }
.dr-board-card:hover .dr-board-acts, .dr-board-card:focus-within .dr-board-acts { opacity: 1; }
.dr-board-act {
    pointer-events: auto;
    border: none;
    background: transparent;
    color: var(--fg-muted);
    cursor: pointer;
    padding: 0 0.25rem;
    line-height: 1;
    font-size: var(--text-xs);
    border-radius: 5px;
}
.dr-board-act:hover { color: var(--accent); background: var(--row-hover); }

.dr-board-body { padding: 0.5rem 0.6rem; }
.dr-board-label { font-weight: 600; line-height: 1.3; word-break: break-word; text-transform: capitalize; }

/* media cards HUG the media's native aspect ratio: the card width is the only
   size control and the media height is always `width ÷ ratio`, so the image/video
   fills the body edge-to-edge with NO letterbox bars (ever — sized or not). The
   body wraps it tightly (no padding, no fixed height). The body's aspect-ratio is
   set inline from the media's natural dimensions (JS) so the box is correct even
   before the bytes load. Media is non-interactive so the card drags via its
   header (video keeps its own controls). */
.dr-board-card.kind-image .dr-board-body,
.dr-board-card.kind-gif .dr-board-body,
.dr-board-card.kind-video .dr-board-body { padding: 0; }
.dr-board-img,
.dr-board-video {
    display: block;
    width: 100%;
    height: auto;        /* = width ÷ media ratio → no letterbox, no cropping */
}
.dr-board-img { pointer-events: none; -webkit-user-drag: none; }
.dr-board-card.is-sized .dr-board-text { height: 100%; }
.dr-board-link { color: var(--accent); text-decoration: underline; word-break: break-all; }

/* connecting lines (SVG inside the board layer; canvas-local coords) */
.dr-board-edges {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: visible;       /* lines may run beyond the layer box */
    pointer-events: none;
}
/* connector = a fat transparent hit line (easy target) + a thin visible line.
   Hover brightens it; CLICK selects it (distinct colour + glow) and outlines the
   two cards it joins; right-click removes. */
.dr-board-edge-g { cursor: pointer; }
.dr-board-edge-hit { stroke: transparent; stroke-width: 22; pointer-events: stroke; fill: none; }
.dr-board-edge-vis { stroke: var(--accent); stroke-width: 2; pointer-events: none; fill: none; transition: stroke var(--dur-fast) var(--ease-smooth), stroke-width var(--dur-fast) var(--ease-smooth); }
.dr-board-edge-g:hover .dr-board-edge-vis { stroke-width: 3.5; }
.dr-board-edge-g.is-selected .dr-board-edge-vis { stroke: var(--status-warn); stroke-width: 4; }
.dr-board-card.is-connected { outline: 2px solid var(--status-warn); outline-offset: 3px; }
/* text→card lines are the SAME interactive <g> as a connector — just dashed —
   so click-select + right-click-remove work identically. (The fat hit line runs
   over the page; the page sits below the board, so a click on the dashed line
   targets the line, a click anywhere else still hits the page.) */
.dr-board-anchor-g .dr-board-edge-vis { stroke-dasharray: 5 4; opacity: 0.85; }
/* line labels read on ANY backdrop (dark desk, light paper, image) via a solid pill
   behind the text — light-on-light over the page used to make them vanish. */
.dr-board-edgelabel-bg {
    fill: color-mix(in srgb, var(--bg) 84%, transparent);
    stroke: color-mix(in srgb, var(--fg) 16%, transparent);
    stroke-width: 1;
    pointer-events: auto;
    cursor: pointer;
}
.dr-board-edgelabel {
    fill: var(--fg);
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
    pointer-events: auto;
    cursor: pointer;
}

/* music chip — cover art + title/artist + Open, over its own native player */
.dr-board-musicchip { display: flex; flex-direction: column; gap: 0.5rem; }
.dr-board-musichead { display: flex; align-items: center; gap: 0.6rem; }
.dr-board-musicart {
    flex: 0 0 auto;
    width: 40px; height: 40px;
    border-radius: 7px;
    background-size: cover;
    background-position: center;
    background-color: color-mix(in srgb, var(--accent) 16%, var(--bg-elevated));
    display: flex; align-items: center; justify-content: center;
    color: var(--accent); font-size: var(--text-md);
}
.dr-board-musicmeta { min-width: 0; flex: 1 1 auto; }
.dr-board-musicname { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
.dr-board-musicsub { color: var(--fg-muted); font-size: var(--text-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
.dr-board-musicopen { flex: 0 0 auto; color: var(--fg-muted); text-decoration: none; font-size: var(--text-xs); pointer-events: auto; }
.dr-board-musicopen:hover { color: var(--accent); }

/* music picker — search + scrollable two-line rows */
.dr-board-msearch {
    width: 100%; box-sizing: border-box; height: var(--control-h, 32px);
    margin-bottom: 0.6rem; padding: 0 0.6rem;
    background: var(--btn-bg); border: 1px solid var(--btn-border); border-radius: 8px;
    color: var(--fg); font: inherit;
}
.dr-board-mlist { max-height: 50vh; overflow-y: auto; }
.dr-board-pi-meta { display: flex; flex-direction: column; min-width: 0; }
.dr-board-pi-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dr-board-pi-sub { color: var(--fg-muted); font-size: var(--text-xs); }

/* picker / music modal (reuses the doc picker for both) */
.dr-board-modal-back {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--bg) 55%, transparent);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}
.dr-board-modal {
    width: min(520px, 92vw);
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    background: var(--bg-elevated);
    border: 1px solid var(--rule);
    border-radius: 10px;
    box-shadow: var(--shadow-lg);
    font-family: var(--font-mono);
}
.dr-board-modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--rule);
    font-weight: 600;
}
.dr-board-modal-x { border: none; background: transparent; color: var(--fg-muted); cursor: pointer; font-size: var(--text-md); }
.dr-board-modal-x:hover { color: var(--accent); }
.dr-board-modal-body { padding: 0.8rem 0.9rem; overflow-y: auto; }
.dr-board-phint, .dr-board-pempty { color: var(--fg-muted); font-size: var(--text-sm); margin: 0 0 0.6rem; }
.dr-board-pgroup h4 { margin: 0.6rem 0 0.3rem; color: var(--fg-dim); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.06em; }
.dr-board-pgroup ul { list-style: none; margin: 0; padding: 0; }
.dr-board-pitem {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    width: 100%;
    text-align: left;
    padding: 0.35rem 0.5rem;
    border: none;
    background: transparent;
    color: var(--fg);
    font: inherit;
    border-radius: 6px;
    cursor: pointer;
}
.dr-board-pitem:hover:not(:disabled) { background: var(--row-hover); color: var(--accent); }
.dr-board-pitem:disabled { opacity: 0.4; cursor: not-allowed; }

.dr-board-text,
.dr-board-note {
    width: 100%;
    box-sizing: border-box;
    resize: none;
    border: none;
    background: transparent;
    color: var(--fg);
    font: inherit;
    outline: none;
    cursor: text;        /* note fields are for typing, not dragging */
}
.dr-board-text { padding: 0; }

/* compact custom audio player (music cards) — token-styled, with a volume slider */
.dr-board-player { display: flex; align-items: center; gap: 0.4rem; }
.dr-board-pbtn {
    flex: 0 0 auto; width: 26px; height: 26px;
    display: flex; align-items: center; justify-content: center;
    border: none; border-radius: 999px;
    background: var(--accent); color: var(--bg);
    font-size: var(--text-xs); cursor: pointer;
}
.dr-board-pbtn:hover { background: var(--accent-hover); }
.dr-board-ptime { flex: 0 0 auto; color: var(--fg-muted); font-size: var(--text-xs); font-variant-numeric: tabular-nums; min-width: 2.4em; }
.dr-board-seek { flex: 1 1 auto; min-width: 0; }
.dr-board-vol { flex: 0 0 auto; width: 48px; }
.dr-board-player input[type="range"] {
    -webkit-appearance: none; appearance: none;
    height: 4px; border-radius: 999px; cursor: pointer;
    background: color-mix(in srgb, var(--fg) 22%, transparent);
}
.dr-board-player input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: 12px; height: 12px; border-radius: 50%; background: var(--accent); border: none; cursor: pointer;
}
.dr-board-player input[type="range"]::-moz-range-thumb { width: 12px; height: 12px; border-radius: 50%; background: var(--accent); border: none; cursor: pointer; }
.dr-board-note {
    border-top: 1px solid var(--rule);
    background: color-mix(in srgb, var(--bg) 50%, transparent);
    color: var(--fg-muted);
    font-size: var(--text-xs);
    padding: 0.35rem 0.6rem;
}

/* read-only manuscript notice (a split chapter's preview) — sits atop the editor
   pane with the two ways to actually write. Tokens only, matches the site. */
.dr-readonly-banner {
    /* FLOAT over the canvas top (like the word-count pill floats over the grid),
       so the translucent bg actually shows the dark desk through it — in normal
       flow there's nothing behind it to be translucent against. */
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 7;            /* above the canvas/cards */
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.45rem 0.9rem;
    background: var(--edet-glass, color-mix(in srgb, var(--bg) 55%, transparent));   /* SAME cloudy glass as all other chrome */
    backdrop-filter: var(--edet-blur);
    -webkit-backdrop-filter: var(--edet-blur);
    border-bottom: none;   /* match the borderless header + toolbar — one continuous frosted top zone */
    font-family: var(--font-mono);
    font-size: var(--text-xs);
}
.dr-readonly-txt { flex: 1 1 12rem; color: var(--fg-muted); }
.dr-readonly-btn {
    flex: 0 0 auto;
    height: 26px;
    padding: 0 0.7rem;
    background: var(--btn-bg);
    border: 1px solid var(--btn-border);
    border-radius: 6px;
    color: var(--fg);
    font: inherit;
    font-size: var(--text-xs);
    cursor: pointer;
}
.dr-readonly-btn:hover { color: var(--accent); border-color: var(--accent); background: var(--btn-bg-hover); }
.dr-rb-merge { color: var(--accent); border-color: var(--accent); }
