LOGIC

VAULT

BOOKS

Look Closer. Feel Deeper

Enter the Vault


About Logic Vault BooksLogic Vault Books creates interactive activity books for curious minds who want more from their quiet time.Some books pull you into clues, tension, and hidden truths.
Others slow the noise down with bold, calming pages for focus and relaxation.
Each experience is designed to make you notice more, feel more involved, and finish with the quiet satisfaction of completing something with purpose.Not ordinary puzzles.Not ordinary coloring pages.A different kind of quiet escape.For curious minds who want quiet time to feel more focused, more creative, and a little unexpected.Look Closer. Feel Deeper.

© Logic Vault Books. All rights reserved.
Official author contact: [email protected]

Privacy Policy

Last updated: May 2026

Logic Vault Books respects your privacy.

When you join the Vault List, we collect your email address so we can send you bonus clues, early previews, free case file updates, and news about future puzzle books.

We may use trusted third-party tools, such as email marketing platforms, analytics tools, and advertising platforms, to operate our website, manage our email list, understand site performance, and improve our marketing.

We do not sell your personal information.

You can unsubscribe from our emails at any time by using the unsubscribe link included in our emails.

Our website may contain links to external websites, including Amazon, TikTok, Pinterest, and other platforms. We are not responsible for the privacy practices of those external websites.

If you have any questions, contact us at:
[email protected]

document.getElementById("openPrivacy").addEventListener("click", function () { document.getElementById("privacyModal").style.display = "block"; }); document.getElementById("closePrivacy").addEventListener("click", function () { document.getElementById("privacyModal").style.display = "none"; }); document.getElementById("privacyModal").addEventListener("click", function (e) { if (e.target === this) { this.style.display = "none"; } });

Mystery Puzzle Books

Murder Mystery Word Search
Volume 1

4-Layer Investigation Preview

Monochrome Coloring Books

Monochrome Coloring Book
For Adults

Monochrome Coloring Book Preview

Want to color them again your way?
Join the coloring list for free printable pages, future bonus designs, and creative extras.

Want to try the investigation first?

Solve one free mini case before opening the full investigation.

CONFIDENTIAL
Sealed Evidence Note
Left by Detective Adam
This note was not left for everyone.

It was left for the person who found the first case.

If you are reading this, then Case File #00 is already waiting for you. Solve it, claim your badge, and decide if you are ready to open the full investigation.
— Detective Adam
Case File #00 · Personal evidence access

SEE HOW ONE CASE UNFOLDS

One case. Four steps. One hidden truth.
Every page moves the investigation forward.

1. Read the briefing

2. Learn the method

3. Reveal the truth

4. Crack the case

Try a Mini Case

Search. Deduce. Journal. Reveal.
Maximum 16 characters. This name will appear on your badge after you solve the case.
The truth is not something you just find,
sometimes it finds drag clue
Victim EMPTY
Method EMPTY
Find the listed words. Some answers are hidden inside the grid.
Case Cleared
Badge issued to Detective.
DETECTIVE
Victim: MAYOR
Method: POISON
Missing clue: YOU

The full investigation continues across 100 case files and one hidden truth.
Open the Full Case on Amazon
(function () { const gridLetters = [ ["F","A","E","N","I","G","H","T","S","Y"], ["M","N","D","S","H","G","H","H","A","Z"], ["U","C","A","S","E","A","A","L","R","B"], ["V","W","V","F","L","D","N","E","O","V"], ["J","Q","S","O","O","P","M","T","O","R"], ["K","Y","C","W","O","A","D","T","M","E"], ["P","K","G","I","Y","C","E","E","X","P"], ["H","M","S","O","U","C","U","R","Q","O"], ["Z","O","R","D","T","R","A","C","E","R"], ["N","G","L","A","S","S","C","G","E","T"] ]; const listedWords = ["CASE","NIGHT","ROOM","LETTER","GLASS","SHADOW","REPORT","YOU","LOCK","TRACE"]; const gridWords = ["CASE","NIGHT","ROOM","LETTER","GLASS","SHADOW","REPORT","LOCK","TRACE"]; const hiddenAnswers = ["MAYOR","POISON"]; const found = new Set(); const foundHidden = new Set(); let cluePlaced = false; let startCell = null; let selected = []; let isDragging = false; const grid = document.getElementById("grid"); const wordsBox = document.getElementById("words"); const status = document.getElementById("status"); const revealBox = document.getElementById("revealBox"); const victimBox = document.getElementById("victimBox"); const methodBox = document.getElementById("methodBox"); const clueDrop = document.getElementById("clueDrop"); const detectiveNameInput = document.getElementById("detectiveName"); const badgeName = document.getElementById("badgeName"); const clearedName = document.getElementById("clearedName"); function cleanDetectiveName(value) { let cleaned = value.replace(/[^a-zA-Z0-9 ]/g, ""); cleaned = cleaned.replace(/\s+/g, " ").trim(); return cleaned.slice(0, 16); } function getDetectiveName() { const cleaned = cleanDetectiveName(detectiveNameInput.value); return cleaned ? cleaned : "Detective"; } detectiveNameInput.addEventListener("input", function () { const cleaned = cleanDetectiveName(this.value); if (this.value !== cleaned) { this.value = cleaned; } }); listedWords.forEach(word => { const span = document.createElement("span"); span.className = "word"; span.id = "word-" + word; span.textContent = word; span.draggable = true; span.addEventListener("dragstart", e => { e.dataTransfer.setData("text/plain", word); }); wordsBox.appendChild(span); }); gridLetters.forEach((row, r) => { row.forEach((letter, c) => { const cell = document.createElement("div"); cell.className = "cell"; cell.textContent = letter; cell.dataset.r = r; cell.dataset.c = c; grid.appendChild(cell); }); }); clueDrop.addEventListener("dragover", e => { e.preventDefault(); }); clueDrop.addEventListener("drop", e => { e.preventDefault(); const word = e.dataTransfer.getData("text/plain"); if (word === "YOU") { clueDrop.textContent = "YOU"; document.getElementById("word-YOU").classList.add("done"); cluePlaced = true; status.textContent = "Missing clue placed: YOU"; checkComplete(); } else { status.textContent = "That word does not fit the missing line."; } }); function clearSelecting() { document.querySelectorAll("#mini-case-game .cell.selecting").forEach(cell => { cell.classList.remove("selecting"); }); selected = []; } function getCell(r, c) { return document.querySelector('#mini-case-game .cell[data-r="' + r + '"][data-c="' + c + '"]'); } function buildStraightSelection(endCell) { if (!startCell || !endCell) return; clearSelecting(); const r1 = Number(startCell.dataset.r); const c1 = Number(startCell.dataset.c); const r2 = Number(endCell.dataset.r); const c2 = Number(endCell.dataset.c); const dr = r2 - r1; const dc = c2 - c1; const absR = Math.abs(dr); const absC = Math.abs(dc); if (!(dr === 0 || dc === 0 || absR === absC)) return; const stepR = dr === 0 ? 0 : dr / absR; const stepC = dc === 0 ? 0 : dc / absC; const length = Math.max(absR, absC); for (let i = 0; i <= length; i++) { const cell = getCell(r1 + stepR * i, c1 + stepC * i); if (cell) { cell.classList.add("selecting"); selected.push(cell); } } } function getSelectedWord() { return selected.map(cell => cell.textContent).join(""); } function markFound(type) { selected.forEach(cell => { cell.classList.remove("selecting"); cell.classList.add(type === "hidden" ? "hidden-found" : "found"); }); } function revealVictim() { victimBox.classList.remove("empty"); victimBox.textContent = "MAYOR"; } function revealMethod() { methodBox.classList.remove("empty"); methodBox.textContent = "POISON"; } function finishSelection() { if (!selected.length) return; const word = getSelectedWord(); const reverse = word.split("").reverse().join(""); if (gridWords.includes(word) && !found.has(word)) { found.add(word); document.getElementById("word-" + word).classList.add("done"); markFound("normal"); status.textContent = "Found: " + word; } else if (gridWords.includes(reverse) && !found.has(reverse)) { found.add(reverse); document.getElementById("word-" + reverse).classList.add("done"); markFound("normal"); status.textContent = "Found: " + reverse; } else if (hiddenAnswers.includes(word) && !foundHidden.has(word)) { foundHidden.add(word); markFound("hidden"); if (word === "MAYOR") { revealVictim(); status.textContent = "Victim discovered."; } if (word === "POISON") { revealMethod(); status.textContent = "Method discovered."; } } else if (hiddenAnswers.includes(reverse) && !foundHidden.has(reverse)) { foundHidden.add(reverse); markFound("hidden"); if (reverse === "MAYOR") { revealVictim(); status.textContent = "Victim discovered."; } if (reverse === "POISON") { revealMethod(); status.textContent = "Method discovered."; } } else { clearSelecting(); } selected = []; startCell = null; checkComplete(); } function checkComplete() { const allGridWordsFound = gridWords.every(w => found.has(w)); const allHiddenFound = hiddenAnswers.every(w => foundHidden.has(w)); if (allGridWordsFound && allHiddenFound && cluePlaced) { const name = getDetectiveName(); const fullName = name.toUpperCase().startsWith("DETECTIVE") ? name : "Detective " + name; badgeName.textContent = name.toUpperCase(); clearedName.textContent = fullName; status.textContent = "Case unlocked."; revealBox.style.display = "block"; } } function cellFromPoint(x, y) { const el = document.elementFromPoint(x, y); return el && el.classList.contains("cell") ? el : null; } grid.addEventListener("mousedown", e => { if (!e.target.classList.contains("cell")) return; clearSelecting(); isDragging = true; startCell = e.target; buildStraightSelection(e.target); }); grid.addEventListener("mouseover", e => { if (!isDragging || !e.target.classList.contains("cell")) return; buildStraightSelection(e.target); }); document.addEventListener("mouseup", () => { if (isDragging) finishSelection(); isDragging = false; }); grid.addEventListener("touchstart", e => { const touch = e.touches[0]; const cell = cellFromPoint(touch.clientX, touch.clientY); if (!cell) return; clearSelecting(); isDragging = true; startCell = cell; buildStraightSelection(cell); e.preventDefault(); }, { passive: false }); grid.addEventListener("touchmove", e => { const touch = e.touches[0]; const cell = cellFromPoint(touch.clientX, touch.clientY); if (cell) buildStraightSelection(cell); e.preventDefault(); }, { passive: false }); grid.addEventListener("touchend", e => { finishSelection(); isDragging = false; e.preventDefault(); }, { passive: false }); })();

Get Case File #00 Free

Download the printable mini investigation.
Solve 4 free cases, uncover hidden clues, preview the full Murder Mystery Word Search experience, and download the official case theme track.

Listen to the Case Theme