.
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 12 Jan 2026 17:53:35 +0000 (17:53 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 12 Jan 2026 17:53:35 +0000 (17:53 +0000)
developer/document/style/RT_TOC.js [new file with mode: 0644]
developer/document/style/article_generic.js
developer/document/style/do_style.js
developer/document/style/page.js
developer/document/style/page_css.js [new file with mode: 0644]
developer/document/style/page_each_H1.js [deleted file]
developer/document/style/paginate_by_element.js [new file with mode: 0644]
developer/document/style/theme_RT.js
developer/document/style/toc.js [deleted file]
developer/document/style/utility.js

diff --git a/developer/document/style/RT_TOC.js b/developer/document/style/RT_TOC.js
new file mode 100644 (file)
index 0000000..dc1c5f5
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+  Processes existing <RT-TOC> tags.
+  Populates each with headings found below it that are exactly one level deeper.
+  Stops scanning if a heading of the same or higher level is encountered.
+*/
+window.StyleRT = window.StyleRT || {};
+
+window.StyleRT.RT_TOC = function() {
+  const debug = window.StyleRT.debug;
+  const toc_tags = document.querySelectorAll('rt-toc');
+
+  toc_tags.forEach((container, toc_index) => {
+    container.style.display = 'block';
+    
+    // 1. Determine the context level of this TOC
+    // We look backward to find the most recent heading (H1-H6)
+    let context_level = 0; // Default to 0 (looking for H1s)
+    let prev = container.previousElementSibling;
+    
+    while (prev) {
+      const match = prev.tagName.match(/^H([1-6])$/);
+      if (match) {
+        context_level = parseInt(match[1]);
+        break;
+      }
+      prev = prev.previousElementSibling;
+    }
+
+    const target_level = context_level + 1;
+    const stop_at_or_above = context_level; 
+    
+    if (debug) debug.log('RT_TOC', `TOC #${toc_index} context: H${context_level}. Targeting: H${target_level}`);
+
+    // 2. Setup Internal Structure
+    container.innerHTML = ''; // Clear any placeholder content
+    const title = document.createElement('h1');
+    title.textContent = context_level === 0 ? 'Table of Contents' : 'Section Contents';
+    title.style.textAlign = 'center';
+    container.appendChild(title);
+
+    const list = document.createElement('ul');
+    list.style.listStyle = 'none';
+    list.style.paddingLeft = '0';
+    container.appendChild(list);
+
+    // 3. Scan Forward for headings
+    let next_el = container.nextElementSibling;
+    while (next_el) {
+      const match = next_el.tagName.match(/^H([1-6])$/);
+      if (match) {
+        const found_level = parseInt(match[1]);
+
+        // STOP condition: We hit a heading at our level or higher
+        // (e.g., if we are under an H1 looking for H2s, we stop at the next H1)
+        if (context_level !== 0 && found_level <= stop_at_or_above) {
+          break;
+        }
+
+        // COLLECT condition: Heading is exactly one level deeper
+        if (found_level === target_level) {
+          if (!next_el.id) next_el.id = `toc-ref-${toc_index}-${found_level}-${list.children.length}`;
+
+          const li = document.createElement('li');
+          li.style.marginBottom = '0.5rem';
+
+          const a = document.createElement('a');
+          a.href = `#${next_el.id}`;
+          a.textContent = next_el.textContent;
+          a.style.textDecoration = 'none';
+          a.style.color = 'inherit';
+          a.style.display = 'block';
+
+          // Hover effects
+          a.onmouseover = () => a.style.color = 'hsl(42, 100%, 50%)';
+          a.onmouseout = () => a.style.color = 'inherit';
+
+          li.appendChild(a);
+          list.appendChild(li);
+        }
+      }
+      next_el = next_el.nextElementSibling;
+    }
+  });
+};
index f49feda..93000aa 100644 (file)
@@ -1,6 +1,6 @@
 /*
-  Sets basic document theme colors.
-  No layout enforcement (leaves flow to default HTML block behavior).
+  Sets basic document theme colors and dimensions.
+  Sets width immediately so layout-based pagination is accurate.
 */
 window.StyleRT = window.StyleRT || {};
 
@@ -10,12 +10,23 @@ window.StyleRT.article_generic = function() {
 
   const body = document.body;
   
-  // Basic Theme Colors (Required for RT_code physics)
-  body.style.backgroundColor = theme.background || '#000';
-  body.style.color = theme.foreground || '#ddd';
+  // 1. Basic Theme Colors
+  body.style.backgroundColor = theme.background || 'hsl(0, 0%, 0%)';
+  body.style.color = theme.foreground || 'hsl(42, 100%, 80%)';
   body.style.fontFamily = '"Noto Sans JP", sans-serif';
   
-  // Reset margins to prevent browser defaults from interfering with your page.js
+  // 2. Global Flow Reset
+  body.style.display = 'block'; 
   body.style.margin = '0';
   body.style.padding = '0';
+
+  // 3. Dimensions
+  // We apply the width to the body now so that getBoundingClientRect() 
+  // in the paginator reflects the final text wrapping.
+  body.style.maxWidth = '50rem';
+  body.style.margin = '0 auto'; // Center the content area
+  
+  // We store the target page height on the RT object for the paginator to find.
+  // This avoids assigning a height to the body itself (which would clip content).
+  RT.page_height = 1056; 
 };
index ffd2da7..9fce950 100644 (file)
@@ -1,89 +1,90 @@
 /*
   Master Loader & Orchestrator for StyleRT.
-  
-  PIPELINE DEPENDENCY CHAIN:
-  1. PHYSICS (Utility, Theme) -> Required by everything.
-  2. GLOBAL (Article)         -> Sets background for contrast checks.
-  3. SEMANTICS (Code, Math)   -> Expands text size; must run before pagination.
-  4. STRUCTURE (H1, TOC)      -> Creates .page containers.
-  5. STYLING (Page)           -> Applies borders/margins to .page containers.
-  6. REVEAL                   -> Shows the result.
+  Loads utility.js first to ensure infrastructure (RT.debug) exists.
 */
 
 window.StyleRT = window.StyleRT || {};
 
 window.StyleRT.do_style = function() {
+  const RT = window.StyleRT;
   
-  // 1. Manifest
   const modules = [
-    'style/utility.js',         
     'style/theme_RT.js',        
     'style/RT_term.js',         
     'style/RT_math.js',         
     'style/RT_code.js',         
     'style/article_generic.js', 
-    'style/page_each_H1.js',    
-    'style/toc.js',             
-    'style/page.js',            
+    'style/RT_TOC.js',          
+    'style/paginate_by_element.js', 
+    //    'style/page.js',
+    'style/page_css.js',            
     'style/body_visibility_visible.js' 
   ];
 
-  // 2. Loader
+  // 1. Bootloader: Get the utility/logger in place first
+  const utility = document.createElement('script');
+  utility.src = 'style/utility.js';
+  
+  utility.onload = () => {
+    // Infrastructure ready; begin module sequence
+    load_next(0);
+  };
+
+  utility.onerror = () => {
+    console.error("StyleRT: Critical failure - utility.js missing.");
+  };
+
+  document.head.appendChild(utility);
+
+  // 2. The Chain Loader
   const load_next = (index) => {
     if (index >= modules.length) {
-      run_pipeline();
+      run_style();
       return;
     }
+    
     const src = modules[index];
+
+    // Accessing the property live so it doesn't matter if it was set late
+    if (RT.debug) RT.debug.log('style', `Loading: ${src}`);
+
     const script = document.createElement('script');
     script.src = src;
     script.onload = () => load_next(index + 1);
-    script.onerror = () => { console.error(`StyleRT: Failed ${src}`); load_next(index + 1); };
+    script.onerror = () => { 
+      console.error(`StyleRT: Failed load on ${src}`); 
+      load_next(index + 1); 
+    };
     document.head.appendChild(script);
   };
 
-  // 3. Execution Pipeline
-  const run_pipeline = () => {
-    const RT = window.StyleRT;
-    const debug = RT.debug;
+  // 3. Phase 1: Semantics
+  const run_style = () => {
+    RT.debug.log('style', 'Starting Phase 1: Setup & Semantics');
 
-    debug.log('pipeline', 'Starting execution...');
-
-    // PHASE 1: GLOBAL SETUP
-    if(RT.article_generic) {
-      debug.log('pipeline', 'Phase 1: Global Setup (article_generic)');
-      RT.article_generic();
-    }
-
-    // PHASE 2: SEMANTICS (In-place modification)
-    debug.log('pipeline', 'Phase 2: Semantics (Term, Math, Code)');
+    if(RT.article_generic) RT.article_generic();
     if(RT.RT_term) RT.RT_term();
     if(RT.RT_math) RT.RT_math();
     if(RT.RT_code) RT.RT_code();
 
-    // PHASE 3: STRUCTURE (DOM Surgery)
-    debug.log('pipeline', 'Phase 3: Structure (Pagination & TOC)');
-    
-    // A. Content Pagination (Breaks body into pages)
-    if(RT.page_each_H1) RT.page_each_H1();
-    
-    // B. TOC Generation (Creates the TOC Page)
-    // Must run AFTER H1s are processed (or scan them), but definitely creates a .page
-    if(RT.toc) RT.toc();
-
-    // PHASE 4: STYLING (The Frame)
-    // Must run LAST, after all .page elements (Content + TOC) exist.
-    if(RT.page) {
-      debug.log('pipeline', 'Phase 4: Styling (Applying Page Borders)');
-      RT.page();
+    // Hand off to MathJax task queue
+    if (window.MathJax && MathJax.Hub && MathJax.Hub.Queue) {
+      RT.debug.log('style', 'MathJax detected. Queueing layout tasks...');
+      MathJax.Hub.Queue(["Typeset", MathJax.Hub], continue_style);
+    } else {
+      continue_style();
     }
+  };
 
-    // PHASE 5: REVEAL
-    debug.log('pipeline', 'Phase 5: Reveal');
+  // 4. Phase 2: Layout
+  const continue_style = () => {
+    RT.debug.log('style', 'Starting Phase 2: Layout & Reveal');
+    
+    if(RT.RT_TOC) RT.RT_TOC();
+    if(RT.paginate_by_element) RT.paginate_by_element();
+    if(RT.page) RT.page();
     if(RT.body_visibility_visible) RT.body_visibility_visible();
     
-    debug.log('pipeline', 'Execution complete.');
+    RT.debug.log('style', 'Style execution complete.');
   };
-
-  load_next(0);
 };
index 6eb5e61..91f6ff1 100644 (file)
@@ -1,40 +1,49 @@
 /*
-  Defines the appearance of a "Page" container.
-  Restores the Original "Gold Glow" Scheme.
+  Defines the appearance of the <RT-PAGE> container via a CSS block.
+  Uses high-contrast offsets to ensure the drop shadow is visible.
 */
 window.StyleRT = window.StyleRT || {};
 
 window.StyleRT.page = function() {
   const RT = window.StyleRT;
+  const style_id = 'rt-page-styles';
   
-  // Fetch Theme
-  const theme = RT.active_theme ? RT.active_theme() : {};
-  // Use the bright accent for the glow
-  const glowColor = theme.accent || 'gold'; 
+  if (!document.getElementById(style_id)) {
+    const style_el = document.createElement('style');
+    style_el.id = style_id;
+    style_el.textContent = `
+      html, body {
+        background-color: #1a1a1a !important; 
+        margin: 0;
+        padding: 0;
+      }
 
-  document.querySelectorAll('.page').forEach(el => {
-    // A. Dimensions (The "Web" Look)
-    el.style.width = '1200px'; 
-    el.style.maxWidth = '95vw'; // Responsive safety
-    el.style.height = 'auto';   // Hug content
-    el.style.minHeight = '200px'; // Minimum sanity check
-    el.style.boxSizing = 'border-box';
-    
-    // B. The "Original" Visuals
-    // 1. Background: Likely darker/transparent to let the theme breathe
-    el.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; 
-    
-    // 2. Border: Thin accent line
-    el.style.border = `1px solid ${glowColor}`;
-    
-    // 3. Shadow: The "Gold Drop Shadow" you missed
-    // Format: offset-x | offset-y | blur-radius | color
-    el.style.boxShadow = `0 0 15px ${glowColor}`; 
-    
-    el.style.margin = '0 auto'; 
-    
-    // C. Typography Base
-    el.style.padding = '2rem 4rem'; // Standard comfortable web reading padding
-    el.style.lineHeight = '1.6';
-  });
+      rt-page {
+        display: block;
+        max-width: 50rem;
+        width: 100%;
+        
+        /* Increased vertical margin to prevent shadow clipping */
+        margin: 4rem auto 6rem auto; 
+        padding: 3rem;
+        box-sizing: border-box;
+        background-color: hsl(0, 0%, 0%);
+        border: 1px solid hsl(42, 100%, 50%);
+        
+        /* 1. The Offset Drop Shadow (Bottom-Right)
+           2. The Ambient Glow (Centered)
+        */
+        box-shadow: 15px 15px 30px rgba(0, 0, 0, 0.9), 
+                    0 0 15px hsl(42, 100%, 15%);
+        
+        height: auto;
+        
+        /* Ensure the shadow isn't cut off by the container's edges */
+        overflow: visible; 
+      }
+    `;
+    document.head.appendChild(style_el);
+  }
+
+  if (RT.debug) RT.debug.log('style', 'CSS block updated with 15px shadow offset.');
 };
diff --git a/developer/document/style/page_css.js b/developer/document/style/page_css.js
new file mode 100644 (file)
index 0000000..0383b05
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+  Defines the appearance of the <RT-PAGE> container.
+  Uses the high-performance 'filter: drop-shadow' discovered in testing.
+*/
+window.StyleRT = window.StyleRT || {};
+
+window.StyleRT.page = function() {
+  const RT = window.StyleRT;
+  const style_id = 'rt-page-styles';
+  
+  if (!document.getElementById(style_id)) {
+    const style_el = document.createElement('style');
+    style_el.id = style_id;
+    style_el.textContent = `
+      rt-page {
+        display: block;
+        max-width: 50rem;
+        width: 100%;
+        margin: 4rem auto 6rem auto;
+        padding: 3rem;
+        box-sizing: border-box;
+        background-color: hsl(0, 0%, 0%);
+        border: 1px solid hsl(42, 100%, 50%);
+        
+        /* Using the discovered Gold Leaf HSL */
+        filter: drop-shadow(8px 12px 40px hsl(40, 96%, 47%));
+        
+        height: auto;
+      }
+    `;
+    document.head.appendChild(style_el);
+  }
+
+  if (RT.debug) RT.debug.log('style', 'CSS block updated with Gold Leaf drop-shadow filter.');
+};
diff --git a/developer/document/style/page_each_H1.js b/developer/document/style/page_each_H1.js
deleted file mode 100644 (file)
index ac19e83..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-  Wraps child elements into pages based on H1 headers.
-*/
-function page_each_H1(){
-  const body = document.body;
-  const elements = Array.from(body.children);
-  const pages = [];
-  let current_page_elements = [];
-
-  elements.forEach(el => {
-    if ( el.tagName === 'SCRIPT' || el.tagName === 'STYLE' ){
-      return;
-    }
-
-    if (el.tagName === 'H1'){
-      if (current_page_elements.length > 0){
-        pages.push(current_page_elements);
-      }
-      current_page_elements = [el];
-    } else {
-      current_page_elements.push(el);
-    }
-  });
-
-  if (current_page_elements.length > 0){
-    pages.push(current_page_elements);
-  }
-
-  const scripts = Array.from(document.querySelectorAll('script'));
-  body.innerHTML = '';
-
-  pages.forEach(element_list => {
-    const page_div = document.createElement('div');
-    page_div.className = 'page';
-    element_list.forEach(el => page_div.appendChild(el));
-    body.appendChild(page_div);
-  });
-
-  scripts.forEach(s => body.appendChild(s));
-}
-
-window.StyleRT = window.StyleRT || {};
-window.StyleRT.page_each_H1 = page_each_H1;
diff --git a/developer/document/style/paginate_by_element.js b/developer/document/style/paginate_by_element.js
new file mode 100644 (file)
index 0000000..0da6ef3
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+  Layout Paginator: paginate_by_element
+  Measures heights and groups elements.
+  Logic: Headings must stay with the element immediately following them.
+*/
+window.StyleRT = window.StyleRT || {};
+
+window.StyleRT.paginate_by_element = function() {
+  const RT = window.StyleRT;
+  const body = document.body;
+  const limit = RT.page_height || 1000; 
+
+  const elements = Array.from(body.children).filter(el => 
+    el.tagName !== 'SCRIPT' && el.tagName !== 'STYLE' && el.tagName !== 'RT-PAGE'
+  );
+
+  const pages = [];
+  let current_batch = [];
+  let current_h = 0;
+
+  const get_el_height = (el) => {
+    const rect = el.getBoundingClientRect();
+    const style = window.getComputedStyle(el);
+    const margin = parseFloat(style.marginTop) + parseFloat(style.marginBottom);
+    return rect.height + margin;
+  };
+
+  for (let i = 0; i < elements.length; i++) {
+    const el = elements[i];
+    const h = get_el_height(el);
+    const is_heading = /H[1-6]/.test(el.tagName);
+
+    // Lookahead: If this is a heading, check the next element too
+    let total_required_h = h;
+    if (is_heading && i + 1 < elements.length) {
+      total_required_h += get_el_height(elements[i + 1]);
+    }
+
+    // If the element (or heading + next) exceeds limit, start new page
+    if (current_h + total_required_h > limit && current_batch.length > 0) {
+      pages.push(current_batch);
+      current_batch = [];
+      current_h = 0;
+    }
+
+    current_batch.push(el);
+    current_h += h;
+  }
+
+  if (current_batch.length > 0) pages.push(current_batch);
+
+  // Rebuild DOM
+  const assets = Array.from(document.querySelectorAll('script, style'));
+  body.innerHTML = '';
+  pages.forEach(list => {
+    const page_el = document.createElement('rt-page');
+    list.forEach(item => page_el.appendChild(item));
+    body.appendChild(page_el);
+  });
+  assets.forEach(a => body.appendChild(a));
+
+  if (RT.debug) RT.debug.log('layout', `Pagination complete: ${pages.length} pages.`);
+};
index 937ceba..63fcec5 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Provides the color palette for the RT theme.
+  Provides the color palette and layout layout for the RT theme.
   Registers itself as the active system theme upon load.
 */
 function theme_RT(){
@@ -11,7 +11,7 @@ function theme_RT(){
     foreground: 'hsl(42, 100%, 80%)',
     accent: 'hsl(42, 100%, 50%)',
     faded: 'hsl(42, 100%, 20%)',
-    highlight: 'hsl(42, 100%, 90%)'
+    highlight: 'hsl(42, 100%, 90%)',
   };
 }
 
diff --git a/developer/document/style/toc.js b/developer/document/style/toc.js
deleted file mode 100644 (file)
index 220afa6..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-  Generates a Table of Contents.
-  Inserts it at the very top of the document body.
-*/
-window.StyleRT = window.StyleRT || {};
-
-window.StyleRT.toc = function() {
-  const RT = window.StyleRT;
-  // Use 'pipeline' token if available, otherwise silent
-  const debug = RT.debug ? RT.debug.log.bind(RT.debug) : () => {};
-
-  debug('pipeline', 'Generating TOC...');
-
-  // 1. Create Container (reusing 'page' class so it picks up your gold style)
-  const container = document.createElement('div');
-  container.className = 'page';
-  container.id = 'rt-toc';
-
-  // 2. Title
-  const title = document.createElement('h1');
-  title.textContent = 'Table of Contents';
-  title.style.textAlign = 'center';
-  container.appendChild(title);
-
-  // 3. Build List
-  const list = document.createElement('ul');
-  document.querySelectorAll('h1').forEach((header, i) => {
-    if (header === title) return;
-    if (!header.id) header.id = `section-${i}`;
-
-    const li = document.createElement('li');
-    const a = document.createElement('a');
-    a.href = `#${header.id}`;
-    a.textContent = header.textContent;
-    a.style.textDecoration = 'none';
-    a.style.color = 'inherit';
-    
-    li.appendChild(a);
-    list.appendChild(li);
-  });
-  
-  container.appendChild(list);
-
-  // 4. Insert at Top (Prepend)
-  document.body.insertBefore(container, document.body.firstChild);
-};
index 4bf452f..8cba0e6 100644 (file)
@@ -10,8 +10,8 @@ window.StyleRT = window.StyleRT || {};
 
 // --- DEBUG SYSTEM ---
 window.StyleRT.debug = {
-  // Add tokens here to enable specific logs: 'RT_code', 'physics', 'pipeline', 'layout'
-  active_tokens: new Set(['pipeline', 'layout']),
+  // Add tokens here to enable specific logs: 'RT_code', 'layout', 'style', 'layout'
+  active_tokens: new Set(['style', 'layout']),
 
   log: function(token, message) {
     if (this.active_tokens.has(token)) {
@@ -36,7 +36,7 @@ window.StyleRT.utility = {
   // --- FONT PHYSICS ---
   measure_ink_ratio: function(target_font, ref_font = null) {
     const debug = window.StyleRT.debug;
-    debug.log('physics', `Measuring ink ratio for ${target_font}`);
+    debug.log('layout', `Measuring ink ratio for ${target_font}`);
 
     const canvas = document.createElement('canvas');
     const ctx = canvas.getContext('2d');
@@ -59,7 +59,7 @@ window.StyleRT.utility = {
     const target_m = get_metrics(target_font);
     
     const ratio = ref_m.ascent / target_m.ascent;
-    debug.log('physics', `Ink Ratio calculated: ${ratio.toFixed(3)}`);
+    debug.log('layout', `Ink Ratio calculated: ${ratio.toFixed(3)}`);
 
     return { 
       ratio: ratio,
@@ -77,7 +77,7 @@ window.StyleRT.utility = {
       if (numbers && numbers.length >= 3) {
         const lightness = parseInt(numbers[2]);
         const is_light = lightness > 50;
-        debug.log('color_physics', `HSL ${color_string} -> Lightness ${lightness}% -> ${is_light ? 'LIGHT' : 'DARK'}`);
+        debug.log('color_layout', `HSL ${color_string} -> Lightness ${lightness}% -> ${is_light ? 'LIGHT' : 'DARK'}`);
         return is_light;
       }
     }
@@ -85,7 +85,7 @@ window.StyleRT.utility = {
     // 2. RGB Check
     const rgb = color_string.match(/\d+/g);
     if (!rgb) {
-      debug.warn('color_physics', `Failed to parse color: "${color_string}". Defaulting to Light.`);
+      debug.warn('color_layout', `Failed to parse color: "${color_string}". Defaulting to Light.`);
       return true; 
     }
 
@@ -95,7 +95,7 @@ window.StyleRT.utility = {
     const luma = (r * 299 + g * 587 + b * 114) / 1000;
     const is_light = luma > 128;
     
-    debug.log('color_physics', `RGB (${r},${g},${b}) -> Luma ${luma.toFixed(1)} -> ${is_light ? 'LIGHT' : 'DARK'}`);
+    debug.log('color_layout', `RGB (${r},${g},${b}) -> Luma ${luma.toFixed(1)} -> ${is_light ? 'LIGHT' : 'DARK'}`);
     return is_light;
   },