diff --git a/package.json b/package.json
index 7d0268c..b6559af 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "the-fold-within",
- "version": "3.0.0",
+ "version": "3.1.0",
"dependencies": {
"pdf-parse": "^1.1.1"
}
-}
\ No newline at end of file
+}
diff --git a/public/app.js b/public/app.js
index 5eea0f3..829d184 100755
--- a/public/app.js
+++ b/public/app.js
@@ -167,9 +167,8 @@ function renderSubNav(parent) {
async function handleHash() {
els.viewer.innerHTML = "";
const rel = location.hash.replace(/^#\//, "");
- const parts = rel.split("/").filter(Boolean); // e.g., ["about", "Mark"]
+ const parts = rel.split("/").filter(Boolean);
- // Determine current depth parent for subnav
const currentParentPath = parts.slice(0, -1).join("/") || parts[0] || null;
if (currentParentPath !== currentParent) {
@@ -177,7 +176,6 @@ async function handleHash() {
renderSubNav(currentParent);
}
- // Sync sidebar section to top-level
const topSection = parts[0] || null;
if (topSection && indexData.sections.includes(topSection)) {
els.sectionSelect.value = topSection;
@@ -186,7 +184,6 @@ async function handleHash() {
if (!rel) return renderDefault();
- // CASE: Trailing slash → render index at *current* level
if (rel.endsWith('/')) {
const currentPath = parts.join("/");
@@ -202,34 +199,12 @@ async function handleHash() {
const html = marked.parse(src || `# ${currentPath.split("/").pop()}\n\nNo content yet.`);
els.viewer.innerHTML = `${html}`;
} else {
- const iframe = document.createElement("iframe");
- iframe.src = "/" + indexFile.path;
- iframe.loading = "eager";
- iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms");
- els.viewer.appendChild(iframe);
-
- iframe.onload = () => {
- try {
- const doc = iframe.contentDocument;
- const body = doc.body;
- const hasContent = body && body.innerText.trim().length > 50;
- if (!hasContent) {
- doc.body.innerHTML = `
-
-
${currentPath.split("/").pop()}
-
No content yet.
-
- `;
- doc.body.style.background = "#0b0b0b";
- }
- } catch (e) {}
- };
+ renderIframe("/" + indexFile.path);
}
} catch (e) {
els.viewer.innerHTML = `${currentPath.split("/").pop()}
No content yet.
`;
}
} else {
- // No index → show children or fallback
if (topSection) {
els.sectionSelect.value = topSection;
renderList();
@@ -239,14 +214,13 @@ async function handleHash() {
}
}
}
- // CASE: Direct file
else {
const file = indexData.flat.find(f => f.path === rel);
if (!file) {
els.viewer.innerHTML = "404
Not found.
";
return;
}
- file.ext === ".md" ? await renderMarkdown(file.path) : renderIframe(file.path);
+ file.ext === ".md" ? await renderMarkdown(file.path) : renderIframe("/" + file.path);
}
}
@@ -255,11 +229,17 @@ async function renderMarkdown(rel) {
els.viewer.innerHTML = `${marked.parse(src || "# Untitled")}`;
}
-function renderIframe(rel) {
+function renderIframe(src) {
const iframe = document.createElement("iframe");
- iframe.src = "/" + rel;
+ iframe.src = src;
iframe.loading = "eager";
- iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms");
+ iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms allow-popups");
+ iframe.style.width = "100vw";
+ iframe.style.height = "calc(100vh - var(--topbar-h) - var(--subnav-h))";
+ iframe.style.border = "none";
+ iframe.style.borderRadius = "0";
+ iframe.style.margin = "0";
+
els.viewer.appendChild(iframe);
iframe.onload = () => {
@@ -267,11 +247,29 @@ function renderIframe(rel) {
const doc = iframe.contentDocument;
const style = doc.createElement("style");
style.textContent = `
- html,body{background:#0b0b0b;color:#e6e3d7;font-family:Inter,sans-serif;margin:0;padding:2rem;}
- *{max-width:720px;margin:auto;}
- img, video, iframe {max-width:100%;height:auto;}
+ html, body {
+ background: transparent;
+ color: inherit;
+ font-family: inherit;
+ margin: 0;
+ padding: 3rem 4vw;
+ }
+ * { max-width: 100%; }
+ img, video, iframe { max-width: 100%; height: auto; }
`;
doc.head.appendChild(style);
+
+ const body = doc.body;
+ const hasContent = body && body.innerText.trim().length > 50;
+ if (!hasContent) {
+ doc.body.innerHTML = `
+
+
${src.split("/").pop().replace(/\..*$/, "")}
+
No content yet.
+
+ `;
+ doc.body.style.background = "transparent";
+ }
} catch (e) {}
};
}
@@ -287,4 +285,4 @@ function renderDefault() {
}
}
-init();
\ No newline at end of file
+init();
diff --git a/public/styles.css b/public/styles.css
index 4ca4c03..667e7aa 100755
--- a/public/styles.css
+++ b/public/styles.css
@@ -172,7 +172,7 @@ body.sidebar-open #sidebar { transform: translateX(0); }
margin-top: calc(var(--topbar-h) + var(--subnav-h)); margin-left: 0;
transition: margin-left var(--transition), margin-top var(--transition);
min-height: calc(100vh - var(--topbar-h) - var(--subnav-h));
- padding: 2rem 1rem;
+ padding: 0;
}
@media (min-width: 1024px) {
@@ -180,8 +180,22 @@ body.sidebar-open #sidebar { transform: translateX(0); }
.content { margin-left: 300px; }
}
+/* BREATHING HORIZON: Full-Field Viewer */
+.viewer {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ transition: background 1s ease;
+}
+
+.viewer:hover {
+ background: radial-gradient(circle at center, #111 0%, #0b0b0b 80%);
+}
+
.viewer > * {
- max-width: 720px; margin: auto; padding: 2rem 1rem;
+ width: 100%;
+ margin: 0;
+ padding: 3rem 4vw;
animation: fadeIn .4s ease-out;
}
@@ -191,7 +205,11 @@ body.sidebar-open #sidebar { transform: translateX(0); }
}
.viewer iframe {
- width: 100%; height: calc(100vh - var(--topbar-h) - var(--subnav-h) - 80px);
- border: 0; border-radius: var(--radius); background: transparent;
+ flex: 1;
+ width: 100vw;
+ min-height: 100vh;
+ border: none;
+ border-radius: 0;
+ margin: 0;
display: block;
-}
\ No newline at end of file
+}