Rune Casting Layout & Meaning Logger

Rune Casting Layout & Meaning Logger

Rune Casting Logger

Structure and record your runic divination layouts and interpretations.

Define the context of your reading: the layout being used, the central query, and the date.

Session Context

Log each rune drawn in your cast, noting its position in the layout and your personal interpretation.

Rune Matrix

Pos # Rune Drawn Layout Position Meaning Key Interpretation Personal Reflection Action

Review the final consolidated reading sheet and export for archival or long-term study.

${rune.interpretation}

Reflection: ${rune.reflection}

`; }); html += ``; P.innerHTML = html; } // --- Tab Switching --- function rclr_showTab(targetId, element) { if (!tabButtons) return; // Guard against call before DOMContentLoaded finishes tabButtons.forEach(btn => btn.classList.remove('rclr-active')); document.querySelectorAll('.rclr-tab-content').forEach(content => content.classList.remove('active')); if (element) { element.classList.add('rclr-active'); } document.getElementById(targetId).classList.add('active'); if (targetId === 'review') { rclr_renderReview(); } } window.rclr_showTab = rclr_showTab; // --- PDF Export --- function rclr_downloadPDF() { if (typeof jspdf === 'undefined' || typeof jspdf.plugin.autotable === 'undefined') { alert('Error: PDF library not fully loaded for export.'); return; } rclr_renderReview(); // Ensure latest data is used const S = RCLR_STATE.setup; if (RCLR_STATE.runes.length === 0) { alert('Please log at least one rune before generating the PDF.'); return; } const { jsPDF } = jspdf; const doc = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); doc.setFont('sans-serif', 'normal'); const margin = 40; const pageWidth = doc.internal.pageSize.getWidth(); let yPos = margin; // --- Header --- doc.setFontSize(20); doc.setFont('sans-serif', 'bold'); doc.setTextColor('#7c2d12'); // Deep Brown doc.text(`${S.layoutType} Reading Log`, pageWidth / 2, yPos, { align: 'center' }); yPos += 30; // --- Setup Data --- doc.setFontSize(10); doc.setFont('sans-serif', 'normal'); const setupData = [ ['Date:', rclr_formatDate(S.castingDate), 'Reader:', S.readerName], ['Layout:', S.layoutType, 'Subject:', S.subjectName || 'Self'], ['Query:', S.centralQuery, '', ''] ]; doc.autoTable({ body: setupData, startY: yPos, theme: 'plain', styles: { fontSize: 9, cellPadding: 4 }, columnStyles: { 0: { fontStyle: 'bold', textColor: '#7c2d12' }, 2: { fontStyle: 'bold', textColor: '#7c2d12' } }, didDrawPage: function(data) { yPos = data.cursor.y; } }); yPos = doc.lastAutoTable.finalY + 20; // --- Rune Log Table --- if (yPos > doc.internal.pageSize.getHeight() - 80) { doc.addPage(); yPos = margin; } doc.setFontSize(14); doc.text("Rune Log & Interpretation:", margin, yPos); yPos += 15; const tableHeaders = ['Pos', 'Rune', 'Layout Meaning', 'Key Interpretation', 'Reflection']; const tableBody = RCLR_STATE.runes.map(r => [ r.position.toString(), r.name, r.layoutMeaning, r.interpretation, r.reflection ]); doc.autoTable({ head: [tableHeaders], body: tableBody, startY: yPos, theme: 'grid', styles: { fontSize: 8, cellPadding: 4, overflow: 'linebreak' }, headStyles: { fillColor: [245, 158, 11], textColor: 255, fontStyle: 'bold' }, // Amber alternateRowStyles: { fillColor: [255, 250, 240] }, columnStyles: { 0: { cellWidth: 30, halign: 'center' }, 4: { cellWidth: 150 } // Reflection gets more space }, didDrawPage: function(data) { yPos = data.cursor.y; } }); doc.save(`Rune_Reading_${S.layoutType.replace(/\s/g, '_')}.pdf`); } // --- Initialization --- document.addEventListener('DOMContentLoaded', () => { // FIX: Assign tabButtons inside DOMContentLoaded to ensure elements exist tabButtons = document.querySelectorAll('.rclr-tab-btn'); // 1. Set default date document.getElementById('castingDate').value = RCLR_STATE.setup.castingDate; // 2. Attach listeners document.getElementById('setup-next-btn').addEventListener('click', () => rclr_showTab('matrix', document.querySelector('.rclr-tab-btn[data-tab="matrix"]'))); document.getElementById('matrix-next-btn').addEventListener('click', () => rclr_showTab('review', document.querySelector('.rclr-tab-btn[data-tab="review"]'))); document.getElementById('rclr-add-rune-btn').addEventListener('click', rclr_addRune); document.getElementById('rclr-download-pdf').addEventListener('click', rclr_downloadPDF); tabButtons.forEach(btn => { btn.addEventListener('click', (e) => rclr_showTab(e.target.dataset.tab, e.target)); }); // 3. Initial population rclr_renderMatrixTable(); });
Scroll to Top