--- /dev/null
+// Core/loader.js
+
+window.RT = window.RT || {};
+window.RT.Element = [];
+window.RT.Module = window.RT.Module || new Set();
+
+
+
+// 2. Establish the Debug System
+window.RT.debug = {
+ active_tokens: new Set([
+ 'scroll'
+ ]),
+
+ log: function(token, message) {
+ if (this.active_tokens.has(token)) {
+ console.log(`[RT:${token}]`, message);
+ }
+ },
+
+ warn: function(token, message) {
+ if (this.active_tokens.has(token)) {
+ console.warn(`[RT:${token}]`, message);
+ }
+ },
+
+ error: function(token, message) {
+ console.error(`[RT:${token}] CRITICAL:`, message);
+ },
+
+ enable: function(token) { this.active_tokens.add(token); console.log(`Enabled: ${token}`); },
+ disable: function(token) { this.active_tokens.delete(token); console.log(`Disabled: ${token}`); }
+};
+
+// 3. Establish the Utilities
+window.RT.utility = {
+
+ string: {
+ to_roman: function(num) {
+ if (num < 1) return num.toString();
+ const lookup = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1};
+ let roman = '';
+ for (let i in lookup) {
+ while (num >= lookup[i]) {
+ roman += i;
+ num -= lookup[i];
+ }
+ }
+ return roman;
+ },
+
+ strip_common_indent: function(text, tag_indent = '') {
+ const raw_lines = text.split('\n');
+ const content_lines = raw_lines.filter(line => line.trim().length > 0);
+ let common_indent = '';
+
+ if (content_lines.length > 0) {
+ const first_match = content_lines[0].match(/^\s*/);
+ common_indent = first_match ? first_match[0] : '';
+
+ for (let i = 1; i < content_lines.length; i++) {
+ const line = content_lines[i];
+ let j = 0;
+ while (j < common_indent.length && j < line.length && common_indent[j] === line[j]) {
+ j++;
+ }
+ common_indent = common_indent.substring(0, j);
+ if (common_indent.length === 0) break;
+ }
+ }
+
+ let final_string = '';
+ if (common_indent.length > 0 && common_indent.startsWith(tag_indent)) {
+ const cleaned_lines = raw_lines.map(line => {
+ return line.startsWith(common_indent) ? line.replace(common_indent, '') : line;
+ });
+
+ if (cleaned_lines.length > 0 && cleaned_lines[0].length === 0) {
+ cleaned_lines.shift();
+ }
+ if (cleaned_lines.length > 0 && cleaned_lines[cleaned_lines.length - 1].trim().length === 0) {
+ cleaned_lines.pop();
+ }
+ final_string = cleaned_lines.join('\n');
+ } else {
+ final_string = text.trim();
+ }
+
+ return final_string;
+ }
+ },
+
+ dom: {
+ measure_outer_height: function(el) {
+ const wasInDOM = el.parentNode !== null;
+ if (!wasInDOM) document.body.appendChild(el);
+ const rect = el.getBoundingClientRect();
+ const style = window.getComputedStyle(el);
+ const margin = parseFloat(style.marginTop) + parseFloat(style.marginBottom);
+ if (!wasInDOM) el.remove();
+ return (rect.height || 0) + (margin || 0);
+ },
+
+ is_block_content: function(element) {
+ return element.textContent.trim().includes('\n');
+ }
+ },
+
+ font: {
+ measure_ink_ratio: function(target_font, ref_font = null) {
+ const debug = window.RT.debug;
+ debug.log('layout', `Measuring ink ratio for ${target_font}`);
+
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+
+ if (!ref_font) {
+ const bodyStyle = window.getComputedStyle(document.body);
+ ref_font = bodyStyle.fontFamily;
+ }
+
+ const get_metrics = (font) => {
+ ctx.font = '100px ' + font;
+ const metrics = ctx.measureText('M');
+ return {
+ ascent: metrics.actualBoundingBoxAscent,
+ descent: metrics.actualBoundingBoxDescent
+ };
+ };
+
+ const ref_m = get_metrics(ref_font);
+ const target_m = get_metrics(target_font);
+
+ const ratio = ref_m.ascent / target_m.ascent;
+
+ return {
+ ratio: ratio,
+ baseline_diff: ref_m.descent - target_m.descent
+ };
+ }
+ },
+
+ color: {
+ extract_l: function(color_string) {
+ const str = String(color_string).trim();
+
+ if (!str.startsWith('oklch')) {
+ console.error(`[RT:color] Invalid format: Expected oklch color string, received '${str}'`);
+ return 0;
+ }
+
+ const match = str.match(/oklch\(\s*([\d.]+%?)/);
+ if (!match) {
+ console.error(`[RT:color] Parsing error: Could not extract lightness from '${str}'`);
+ return 0;
+ }
+
+ const l_value = match[1];
+ return l_value.includes('%') ? parseFloat(l_value) / 100 : parseFloat(l_value);
+ },
+
+ is_high_contrast: function(bg_color, text_color) {
+ const bg_l = this.extract_l(bg_color);
+ const text_l = this.extract_l(text_color);
+ return Math.abs(text_l - bg_l) >= 0.7;
+ },
+
+ is_readable: function(bg_color, text_color) {
+ const bg_l = this.extract_l(bg_color);
+ const text_l = this.extract_l(text_color);
+ return Math.abs(text_l - bg_l) >= 0.5;
+ },
+
+ is_light: function(color_string) {
+ return this.extract_l(color_string) > 0.75;
+ },
+
+ is_gray: function(color_string) {
+ const l = this.extract_l(color_string);
+ return l >= 0.25 && l <= 0.75;
+ },
+
+ is_dark: function(color_string) {
+ return this.extract_l(color_string) < 0.25;
+ }
+ }
+
+};
+
+window.RT.theme_preference = function(author_pref, default_color = "#FF00FF") {
+ const reader_pref = localStorage.getItem('RT-Style·theme_preference');
+ const theme_to_load = reader_pref ? reader_pref : author_pref;
+
+ window.RT.theme('load', theme_to_load, default_color);
+};
+
+
+window.RT.load = function(module_path) {
+ if (window.RT.Module.has(module_path)) {
+ return;
+ }
+ window.RT.Module.add(module_path);
+
+ let resolved_path = window.RT.dirpr_library + '/' + module_path;
+ if (!resolved_path.endsWith('.js')) {
+ resolved_path = resolved_path + '.js';
+ }
+
+ document.write('<script src="' + resolved_path + '"></script>');
+};
+
+window.RT.load('Core/stage_manager');
+window.RT.load('Core/theme_make');
+window.RT.load('Theme/manifest.js')
+++ /dev/null
-// block_visibility_during_layout.js
-
-// 1. Hide the document immediately upon execution in the <head>
-document.documentElement.style.visibility = "hidden";
-
-// 2. Define the restoration function
-const restore_visibility = function() {
- document.documentElement.style.visibility = "";
- document.removeEventListener("RT_layout_complete", restore_visibility);
- window.removeEventListener("load", restore_visibility);
-};
-
-// 3. Listen for a specific completion signal from the layout engine
-document.addEventListener("RT_layout_complete", restore_visibility);
-
-// 4. Structural Safety Net: If the layout engine fails or is never loaded,
-// restore visibility on the final window 'load' event so the page doesn't remain blank.
-window.addEventListener("load", restore_visibility);
-
+++ /dev/null
-window.RT = window.RT || {};
-
-window.RT.document_loaded = function(layout_callback) {
- const debug = window.RT.debug || { log: function(){} };
- debug.log('lifecycle', 'Processing registered elements.');
-
- if (window.RT.theme) {
- window.RT.theme();
- }
-
- if (window.RT.Element && Array.isArray(window.RT.Element)) {
- window.RT.Element.forEach(function(element_fn) {
- if (typeof element_fn === 'function') {
- element_fn();
- }
- });
- }
-
- if (window.MathJax && MathJax.Hub && MathJax.Hub.Queue) {
- MathJax.Hub.Queue(["Typeset", MathJax.Hub], layout_callback);
- } else {
- layout_callback();
- }
-};
+++ /dev/null
-// Core/loader.js
-
-window.RT = window.RT || {};
-window.RT.Element = [];
-window.RT.Module = window.RT.Module || new Set();
-
-// 1. Establish the Generic Theme Dictionary
-// e.g. RT.theme( 'read', 'content_main')
-window.RT.theme = (function() {
- const dictionary = {
- meta: {
- is_dark: false,
- name: ""
- },
- surface: {
- 0: "", 1: "", 2: "", 3: "",
- input: "", code: "", select: ""
- },
- content: {
- main: "", muted: "", subtle: "", inverse: ""
- },
- brand: {
- primary: "", secondary: "", tertiary: "", link: ""
- },
- border: {
- faint: "", regular: "", strong: ""
- },
- state: {
- success: "", warning: "", error: "", info: ""
- },
- syntax: {
- keyword: "", string: "", func: "", comment: ""
- },
- page: {
- width: "", min_height: "", padding: "", margin: "",
- bg_color: "", border_color: "", text_color: "", shadow: ""
- }
- };
-
- function resolve_path(path_array) {
- let current = dictionary;
- for (let i = 0; i < path_array.length - 1; i++) {
- const step = path_array[i];
- if (current[step] === undefined) return null;
- current = current[step];
- }
- return { container: current, key: path_array[path_array.length - 1] };
- }
-
- function check_completion(obj, path_string) {
- for (const key in obj) {
- if (typeof obj[key] === 'object' && obj[key] !== null) {
- if (!check_completion(obj[key], path_string + key + '.')) {
- return false;
- }
- } else {
- if (obj[key] === "") {
- window.RT.debug.error('theme', 'is_defined check failed at missing key: ' + path_string + key);
- return false;
- }
- }
- }
- return true;
- }
-
- return function(command, ...args) {
-
- // e.g. RT.theme('read','page','width')
- if (command === 'read') {
- const target = resolve_path(args);
- if (target && target.container.hasOwnProperty(target.key)) {
- return target.container[target.key];
- }
- window.RT.debug.error('theme', 'Read attempt on unknown path: ' + args.join('.'));
- return null;
- }
-
- if (command === 'write') {
- if (args.length < 2) {
- window.RT.debug.error('theme', 'Write command expects a path and a value.');
- return;
- }
- const value = args.pop();
- const target = resolve_path(args);
-
- if (target && target.container.hasOwnProperty(target.key)) {
- target.container[target.key] = value;
- } else {
- window.RT.debug.error('theme', 'Write attempt on unknown path rejected: ' + args.join('.'));
- }
- return;
- }
-
- if (command === 'is_defined') {
- if (args.length === 0) {
- return check_completion(dictionary, '');
- }
-
- for (let i = 0; i < args.length; i++) {
- const path_array = args[i];
- if (!Array.isArray(path_array)) {
- window.RT.debug.error('theme', 'is_defined arguments must be path arrays. Received: ' + path_array);
- return false;
- }
- const target = resolve_path(path_array);
- if (!target || !target.container.hasOwnProperty(target.key) || target.container[target.key] === "") {
- window.RT.debug.error('theme', 'is_defined check failed at: ' + path_array.join('.'));
- return false;
- }
- }
- return true;
- }
-
- window.RT.debug.error('theme', 'Invalid command passed to theme dictionary: ' + command);
- };
-})();
-
-
-// 2. Establish the Debug System
-window.RT.debug = {
- active_tokens: new Set([
- 'scroll'
- ]),
-
- log: function(token, message) {
- if (this.active_tokens.has(token)) {
- console.log(`[RT:${token}]`, message);
- }
- },
-
- warn: function(token, message) {
- if (this.active_tokens.has(token)) {
- console.warn(`[RT:${token}]`, message);
- }
- },
-
- error: function(token, message) {
- console.error(`[RT:${token}] CRITICAL:`, message);
- },
-
- enable: function(token) { this.active_tokens.add(token); console.log(`Enabled: ${token}`); },
- disable: function(token) { this.active_tokens.delete(token); console.log(`Disabled: ${token}`); }
-};
-
-// 3. Establish the Utilities
-window.RT.utility = {
-
- string: {
- to_roman: function(num) {
- if (num < 1) return num.toString();
- const lookup = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1};
- let roman = '';
- for (let i in lookup) {
- while (num >= lookup[i]) {
- roman += i;
- num -= lookup[i];
- }
- }
- return roman;
- },
-
- strip_common_indent: function(text, tag_indent = '') {
- const raw_lines = text.split('\n');
- const content_lines = raw_lines.filter(line => line.trim().length > 0);
- let common_indent = '';
-
- if (content_lines.length > 0) {
- const first_match = content_lines[0].match(/^\s*/);
- common_indent = first_match ? first_match[0] : '';
-
- for (let i = 1; i < content_lines.length; i++) {
- const line = content_lines[i];
- let j = 0;
- while (j < common_indent.length && j < line.length && common_indent[j] === line[j]) {
- j++;
- }
- common_indent = common_indent.substring(0, j);
- if (common_indent.length === 0) break;
- }
- }
-
- let final_string = '';
- if (common_indent.length > 0 && common_indent.startsWith(tag_indent)) {
- const cleaned_lines = raw_lines.map(line => {
- return line.startsWith(common_indent) ? line.replace(common_indent, '') : line;
- });
-
- if (cleaned_lines.length > 0 && cleaned_lines[0].length === 0) {
- cleaned_lines.shift();
- }
- if (cleaned_lines.length > 0 && cleaned_lines[cleaned_lines.length - 1].trim().length === 0) {
- cleaned_lines.pop();
- }
- final_string = cleaned_lines.join('\n');
- } else {
- final_string = text.trim();
- }
-
- return final_string;
- }
- },
-
- dom: {
- measure_outer_height: function(el) {
- const wasInDOM = el.parentNode !== null;
- if (!wasInDOM) document.body.appendChild(el);
- const rect = el.getBoundingClientRect();
- const style = window.getComputedStyle(el);
- const margin = parseFloat(style.marginTop) + parseFloat(style.marginBottom);
- if (!wasInDOM) el.remove();
- return (rect.height || 0) + (margin || 0);
- },
-
- is_block_content: function(element) {
- return element.textContent.trim().includes('\n');
- }
- },
-
- font: {
- measure_ink_ratio: function(target_font, ref_font = null) {
- const debug = window.RT.debug;
- debug.log('layout', `Measuring ink ratio for ${target_font}`);
-
- const canvas = document.createElement('canvas');
- const ctx = canvas.getContext('2d');
-
- if (!ref_font) {
- const bodyStyle = window.getComputedStyle(document.body);
- ref_font = bodyStyle.fontFamily;
- }
-
- const get_metrics = (font) => {
- ctx.font = '100px ' + font;
- const metrics = ctx.measureText('M');
- return {
- ascent: metrics.actualBoundingBoxAscent,
- descent: metrics.actualBoundingBoxDescent
- };
- };
-
- const ref_m = get_metrics(ref_font);
- const target_m = get_metrics(target_font);
-
- const ratio = ref_m.ascent / target_m.ascent;
-
- return {
- ratio: ratio,
- baseline_diff: ref_m.descent - target_m.descent
- };
- }
- },
-
- color: {
- extract_l: function(color_string) {
- const str = String(color_string).trim();
-
- if (!str.startsWith('oklch')) {
- console.error(`[RT:color] Invalid format: Expected oklch color string, received '${str}'`);
- return 0;
- }
-
- const match = str.match(/oklch\(\s*([\d.]+%?)/);
- if (!match) {
- console.error(`[RT:color] Parsing error: Could not extract lightness from '${str}'`);
- return 0;
- }
-
- const l_value = match[1];
- return l_value.includes('%') ? parseFloat(l_value) / 100 : parseFloat(l_value);
- },
-
- is_high_contrast: function(bg_color, text_color) {
- const bg_l = this.extract_l(bg_color);
- const text_l = this.extract_l(text_color);
- return Math.abs(text_l - bg_l) >= 0.7;
- },
-
- is_readable: function(bg_color, text_color) {
- const bg_l = this.extract_l(bg_color);
- const text_l = this.extract_l(text_color);
- return Math.abs(text_l - bg_l) >= 0.5;
- },
-
- is_light: function(color_string) {
- return this.extract_l(color_string) > 0.75;
- },
-
- is_gray: function(color_string) {
- const l = this.extract_l(color_string);
- return l >= 0.25 && l <= 0.75;
- },
-
- is_dark: function(color_string) {
- return this.extract_l(color_string) < 0.25;
- }
- }
-
-};
-
-window.RT.load = function(module_path) {
- if (window.RT.Module.has(module_path)) {
- return;
- }
- window.RT.Module.add(module_path);
-
- let resolved_path = window.RT.dirpr_library + '/' + module_path;
- if (!resolved_path.endsWith('.js')) {
- resolved_path = resolved_path + '.js';
- }
-
- document.write('<script src="' + resolved_path + '"></script>');
-};
--- /dev/null
+// Core/document_loaded.js
+
+window.RT = window.RT || {};
+window.RT.Element = window.RT.Element || [];
+window.RT.Module = window.RT.Module || new Set();
+
+(function(){
+ const debug = window.RT.debug || { log: function(){} };
+
+ let target_y = 0;
+ let is_reload = false;
+ let is_layout_locked = false;
+ let scroll_timer;
+
+ function lock_layout() {
+ is_layout_locked = true;
+ document.documentElement.style.visibility = "hidden";
+ }
+
+ function unlock_layout() {
+ if (!is_layout_locked) return;
+ is_layout_locked = false;
+
+ document.documentElement.style.visibility = "";
+ window.removeEventListener("load", unlock_layout);
+ document.dispatchEvent(new Event("RT_layout_complete"));
+ }
+
+ function configure_history(){
+ if ('scrollRestoration' in history) {
+ history.scrollRestoration = 'manual';
+ }
+ }
+
+ function capture_scroll_target(){
+ const raw_target = sessionStorage.getItem('RT_saved_y');
+ target_y = raw_target !== null ? parseInt(raw_target ,10) : 0;
+
+ if (window.performance) {
+ const nav_entries = performance.getEntriesByType("navigation");
+ if (nav_entries.length > 0) {
+ is_reload = (nav_entries[0].type === "reload");
+ } else if (performance.navigation) {
+ is_reload = (performance.navigation.type === 1);
+ }
+ }
+ }
+
+ function enforce_scroll(target ,use_hash ,attempts){
+ if (attempts > 15) {
+ unlock_layout();
+ return;
+ }
+
+ if (use_hash) {
+ const hash_target = document.getElementById(window.location.hash.substring(1));
+ if (hash_target) {
+ hash_target.scrollIntoView();
+ }
+ } else {
+ window.scrollTo(0 ,target);
+ }
+
+ let is_successful = use_hash ? true : (Math.abs(window.scrollY - target) < 5 || target === 0);
+ if (is_successful && document.body.scrollHeight > 1000) {
+ setTimeout(() => {
+ if (!use_hash && Math.abs(window.scrollY - target) >= 5) {
+ enforce_scroll(target ,use_hash ,attempts + 1);
+ } else {
+ unlock_layout();
+ }
+ }, 100);
+ } else {
+ setTimeout(() => enforce_scroll(target ,use_hash ,attempts + 1) ,50);
+ }
+ }
+
+ function bind_window_events(){
+ window.addEventListener('scroll' ,() => {
+ if (is_layout_locked) return;
+ clearTimeout(scroll_timer);
+ scroll_timer = setTimeout(() => {
+ sessionStorage.setItem('RT_saved_y' ,window.scrollY);
+ }, 200);
+ }, { passive: true });
+
+ window.addEventListener('beforeunload' ,() => {
+ lock_layout();
+ });
+ }
+
+ function execute_pagination_and_scroll(){
+ debug.log('scroll' ,`Pagination layout starting.`);
+ if(window.RT.paginate_by_element) window.RT.paginate_by_element();
+ if(window.RT.page) window.RT.page();
+
+ let final_target = target_y;
+ let use_hash = false;
+ if (window.location.hash && !is_reload) {
+ const hash_target = document.getElementById(window.location.hash.substring(1));
+ if (hash_target) {
+ use_hash = true;
+ }
+ }
+
+ enforce_scroll(final_target ,use_hash ,0);
+ }
+
+ function process_elements_and_layout() {
+ debug.log('lifecycle', 'Processing registered elements.');
+
+ if (window.RT.theme) {
+ window.RT.theme();
+ }
+
+ if (window.RT.Element && Array.isArray(window.RT.Element)) {
+ while (window.RT.Element.length > 0) {
+ const element_fn = window.RT.Element.shift();
+ if (typeof element_fn === 'function') {
+ element_fn();
+ }
+ }
+ }
+
+ if (window.MathJax && MathJax.Hub && MathJax.Hub.Queue) {
+ MathJax.Hub.Queue(["Typeset", MathJax.Hub], execute_pagination_and_scroll);
+ } else {
+ execute_pagination_and_scroll();
+ }
+ }
+
+ // Initial Execution
+ lock_layout();
+ configure_history();
+ capture_scroll_target();
+ bind_window_events();
+
+ document.addEventListener('DOMContentLoaded', process_elements_and_layout);
+
+ // Structural Safety Net: restore visibility on load if layout engine hangs
+ window.addEventListener("load", unlock_layout);
+
+})();
--- /dev/null
+// 1. Establish the Generic Theme Dictionary
+// e.g. RT.theme( 'read', 'content_main')
+// Establish the global theme library
+window.RT.theme_library = window.RT.theme_library || {};
+
+window.RT.theme = (function() {
+ const dictionary = {
+ meta: { is_dark: false, name: "" },
+ surface: { 0: "", 1: "", 2: "", 3: "", input: "", code: "", select: "" },
+ content: { main: "", muted: "", subtle: "", inverse: "" },
+ brand: { primary: "", secondary: "", tertiary: "", link: "" },
+ border: { faint: "", regular: "", strong: "" },
+ state: { success: "", warning: "", error: "", info: "" },
+ syntax: { keyword: "", string: "", func: "", comment: "" },
+ page: { width: "", min_height: "", padding: "", margin: "", bg_color: "", border_color: "", text_color: "", shadow: "" }
+ };
+
+ function resolve_path(path_array) {
+ let current = dictionary;
+ for (let i = 0; i < path_array.length - 1; i++) {
+ const step = path_array[i];
+ if (current[step] === undefined) return null;
+ current = current[step];
+ }
+ return { container: current, key: path_array[path_array.length - 1] };
+ }
+
+ function apply_and_validate_theme(new_theme, fallback_color) {
+ const debug = window.RT.debug || { error: function(){} };
+
+ // Pass 1: Walk the structure of the active dictionary
+ function walk_current(curr, source, path) {
+ for (const key in curr) {
+ const current_path = path ? path + "." + key : key;
+ if (typeof curr[key] === 'object' && curr[key] !== null) {
+ walk_current(curr[key], source[key] || {}, current_path);
+ } else {
+ if (source[key] !== undefined && source[key] !== "") {
+ curr[key] = source[key];
+ } else {
+ debug.error('theme', `Missing key in loaded theme: ${current_path}. Assigning fallback.`);
+ curr[key] = fallback_color;
+ }
+ }
+ }
+ }
+
+ // Pass 2: Walk the structure of the incoming theme dictionary
+ function walk_new(source, curr, path) {
+ for (const key in source) {
+ const current_path = path ? path + "." + key : key;
+ if (typeof source[key] === 'object' && source[key] !== null) {
+ if (curr[key] === undefined) {
+ debug.error('theme', `Unexpected structure in loaded theme: ${current_path} is an object.`);
+ } else {
+ walk_new(source[key], curr[key] || {}, current_path);
+ }
+ } else {
+ if (curr[key] === undefined) {
+ debug.error('theme', `Unexpected key in loaded theme: ${current_path}.`);
+ }
+ }
+ }
+ }
+
+ walk_current(dictionary, new_theme, "");
+ walk_new(new_theme, dictionary, "");
+ }
+
+ return function(command, ...args) {
+ if (command === 'read') {
+ const target = resolve_path(args);
+ return (target && target.container.hasOwnProperty(target.key)) ? target.container[target.key] : null;
+ }
+
+ if (command === 'write') {
+ if (args.length < 2) return;
+ const value = args.pop();
+ const target = resolve_path(args);
+ if (target && target.container.hasOwnProperty(target.key)) {
+ target.container[target.key] = value;
+ }
+ return;
+ }
+
+ if (command === 'load') {
+ const theme_name = args[0];
+ const fallback = args[1] || "#FF00FF";
+
+ if (!window.RT.theme_library.hasOwnProperty(theme_name)) {
+ window.RT.debug.error('theme', `Load aborted: Theme '${theme_name}' is not in the theme_library.`);
+ return false;
+ }
+
+ apply_and_validate_theme(window.RT.theme_library[theme_name], fallback);
+ return true;
+ }
+
+ window.RT.debug.error('theme', 'Invalid command passed to theme dictionary: ' + command);
+ };
+})();
window.RT = window.RT || {};
(function() {
- // We are the style library, so ...
window.RT.dirpr_library = "..";
-
- // 1. Inject the loader script
- document.write('<script src="' + window.RT.dirpr_library + '/Core/loader.js"><\/script>');
+ document.write('<script src="' + window.RT.dirpr_library + '/Core/RT-Style_make.js"><\/script>');
// 2. Inject a secondary script block for the core dependencies
document.write(
'<script>' +
- 'window.RT.load("Core/utility");' +
- 'window.RT.load("Core/block_visibility_during_layout");' +
- 'window.RT.load("Theme");' +
'window.RT.load("Element/theme_selector");' +
'<\/script>'
);
+++ /dev/null
-// for documents in RT-style/Manuscript/document
-window.RT = window.RT || {};
-
-(function() {
- // We are the style library, so ...
- window.RT.dirpr_library = "..";
-
- // 1. Inject the loader script
- document.write('<script src="' + window.RT.dirpr_library + '/Core/loader.js"><\/script>');
-
- // 2. Inject a secondary script block for the core dependencies
- document.write(
- '<script>' +
- 'window.RT.load("Core/utility");' +
- 'window.RT.load("Core/block_visibility_during_layout");' +
- 'window.RT.load("Theme");' +
- 'window.RT.load("Element/theme_selector");' +
- '<\/script>'
- );
-})();
<head>
<meta charset="UTF-8">
<title>RT Style System: Reference Manual</title>
-
<script src="RT-Style_locator.js"></script>
<script>
+ window.RT.theme_preference('golden_wheat');
window.RT.load('Layout/article_tech_ref');
</script>
-
</head>
<body>
<RT·theme-selector></RT·theme-selector>
-
<RT·article>
<RT·title
+// Element/theme_selector.js
+
window.RT = window.RT || {};
+window.RT.Element = window.RT.Element || [];
-window.RT.theme_selector = function(){
- document.querySelectorAll('rt·theme-selector').forEach( (el) => {
- let current_theme = localStorage.getItem('RT_theme_preference');
- if(!current_theme){
- current_theme = 'dark_gold';
- }
+window.RT.Element.push(function build_theme_selector() {
+ document.querySelectorAll('rt·theme-selector').forEach((el) => {
+
+ const active_theme = window.RT.theme('read', 'meta', 'name');
+ const available_themes = Object.keys(window.RT.theme_library || {});
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.color = 'white';
container.style.fontFamily = 'sans-serif';
- container.innerHTML = `
- <b>Theme Selection</b><br>
- <label>
- <input type="radio" name="RT·theme" value="dark_gold" ${current_theme === 'dark_gold' ? 'checked' : ''}> Dark Gold
- </label><br>
- <label>
- <input type="radio" name="RT·theme" value="light_gold" ${current_theme === 'light_gold' ? 'checked' : ''}> Light Gold
- </label>
- `;
+ let html_content = `<b>Theme Selection</b><br>`;
+
+ if (available_themes.length === 0) {
+ html_content += `<small>No themes found in library.</small>`;
+ } else {
+ available_themes.forEach(theme_name => {
+ const is_checked = active_theme === theme_name ? 'checked' : '';
+ html_content += `
+ <label>
+ <input type="radio" name="RT·theme" value="${theme_name}" ${is_checked}> ${theme_name}
+ </label><br>
+ `;
+ });
+ }
+
+ container.innerHTML = html_content;
- container.addEventListener( 'change' ,(e) => {
+ container.addEventListener('change', (e) => {
if(e.target.name === 'RT·theme') {
- localStorage.setItem('RT_theme_preference' ,e.target.value);
- location.reload();
+ localStorage.setItem('RT-Style·theme_preference', e.target.value);
+ // Reloading applies the new preference via theme_preference() in the <head>
+ location.reload();
}
});
el.replaceWith(container);
});
-};
+});
(function(){
const RT = window.RT = window.RT || {};
- const debug = RT.debug || { log: function(){} };
- let target_y = 0;
- let is_reload = false;
- let is_layout_locked = true;
- let scroll_timer;
-
- function configure_history(){
- if ('scrollRestoration' in history) {
- history.scrollRestoration = 'manual';
- }
- }
-
- function capture_scroll_target(){
- const raw_target = sessionStorage.getItem('RT_saved_y');
- target_y = raw_target !== null ? parseInt(raw_target ,10) : 0;
-
- if (window.performance) {
- const nav_entries = performance.getEntriesByType("navigation");
- if (nav_entries.length > 0) {
- is_reload = (nav_entries[0].type === "reload");
- } else if (performance.navigation) {
- is_reload = (performance.navigation.type === 1);
- }
- }
- }
-
- function load_elements(){
- // The specific elements requested by the layout
- RT.load('Element/counter');
- RT.load('Element/chapter');
- RT.load('Element/endnote');
- RT.load('Element/math');
- RT.load('Element/code');
- RT.load('Element/term');
- RT.load('Element/TOC');
- RT.load('Element/title');
- RT.load('Element/symbol');
- RT.load('Element/constraint');
- RT.load('Element/crossref');
-
- RT.load('Layout/paginate_by_element');
- RT.load('Layout/page_fixed_glow');
- }
-
- function apply_style_rule(selector ,rules){
- document.querySelectorAll(selector).forEach( (el) => {
- for (let prop in rules) {
- if (typeof rules[prop] === 'string' && rules[prop].indexOf('!important') !== -1) {
- const kebab_prop = prop.replace(/[A-Z]/g ,m => "-" + m.toLowerCase());
- const value = rules[prop].replace(' !important' ,'');
- el.style.setProperty(kebab_prop ,value ,'important');
- } else {
- el.style[prop] = rules[prop];
+ // 1. The Explicit Element Roster
+ const required_elements = [
+ 'counter',
+ 'chapter',
+ 'endnote',
+ 'math',
+ 'code',
+ 'term',
+ 'TOC',
+ 'title',
+ 'symbol',
+ 'constraint',
+ 'crossref'
+ ];
+
+ // Trigger file loading immediately
+ required_elements.forEach(name => RT.load('Element/' + name));
+
+ // 2. The Extracted Styling Function
+ function apply_article_styles() {
+ const t = function(...path) { return window.RT.theme('read', ...path); };
+
+ const surface_0 = t('surface', '0');
+ const surface_code = t('surface', 'code');
+ const content_main = t('content', 'main');
+ const brand_primary = t('brand', 'primary');
+ const brand_secondary = t('brand', 'secondary');
+ const brand_tertiary = t('brand', 'tertiary');
+ const is_dark = t('meta', 'is_dark');
+
+ const font_weight = is_dark === false ? "600" : "400";
+
+ const apply = function(selector, rules) {
+ document.querySelectorAll(selector).forEach(el => {
+ for (let p in rules) {
+ if (typeof rules[p] === 'string' && rules[p].includes('!important')) {
+ el.style.setProperty(p.replace(/[A-Z]/g, m => "-" + m.toLowerCase()), rules[p].replace(' !important', ''), 'important');
+ } else {
+ el.style[p] = rules[p];
+ }
}
- }
- });
- }
-
- function apply_style(){
- // Note: This will be updated to read from window.RT.theme('read', ...)
- // in the next iteration.
- RT.config = RT.config || {};
- RT.config.article = {
- font_family: "'Noto Sans JP', Arial, sans-serif"
- ,line_height: "1.8"
- ,font_size: "16px"
- ,font_weight: "400"
- ,max_width: "46.875rem"
- ,margin: "0 auto"
+ });
};
-
- if( RT.config.theme && RT.config.theme.meta_is_dark === false ){
- RT.config.article.font_weight = "600";
- }
- window.RT.config.page = window.RT.config.page || {};
- window.RT.config.page.height_limit = 900;
-
- const conf = RT.config.article;
-
- apply_style_rule('body, html, RT·article' ,{ overflowAnchor: "none !important" });
- apply_style_rule('RT·article', {
+ // Apply base geometry
+ apply('body, html, RT·article', { overflowAnchor: "none !important" });
+ apply('RT·article', {
display: "block",
- fontFamily: conf.font_family,
- fontSize: conf.font_size,
- lineHeight: conf.line_height,
- fontWeight: conf.font_weight,
- maxWidth: conf.max_width + " !important",
- margin: conf.margin,
- backgroundColor: RT.config.theme.surface_0,
- color: RT.config.theme.content_main,
+ fontFamily: "'Noto Sans JP', Arial, sans-serif",
+ fontSize: "16px",
+ lineHeight: "1.8",
+ fontWeight: font_weight,
+ maxWidth: "46.875rem !important",
+ margin: "0 auto",
+ backgroundColor: surface_0,
+ color: content_main,
boxSizing: "border-box !important"
});
- apply_style_rule('RT·article:not(:has(RT·page))' ,{ padding: "3rem !important" });
- apply_style_rule('RT·article:has(RT·page)' ,{ padding: "0 !important" });
- apply_style_rule('RT·article RT·page' ,{
- position: "relative",
- display: "block",
- padding: "3rem",
- margin: "1.25rem auto",
- backgroundColor: RT.config.theme.surface_0,
- boxShadow: `0 0 0.625rem ${RT.config.theme.brand_primary}`
+ apply('RT·article:not(:has(RT·page))', { padding: "3rem !important" });
+ apply('RT·article:has(RT·page)', { padding: "0 !important" });
+ apply('RT·article RT·page', {
+ position: "relative", display: "block", padding: "3rem",
+ margin: "1.25rem auto", backgroundColor: surface_0,
+ boxShadow: `0 0 0.625rem ${brand_primary}`
});
- apply_style_rule('RT·article h1' ,{ fontSize: "1.5rem", textAlign: "center", color: RT.config.theme.brand_primary, fontWeight: "500", marginTop: "1.5rem", lineHeight: "1.15" });
- apply_style_rule('RT·article h2' ,{ fontSize: "1.25rem", color: RT.config.theme.brand_secondary, textAlign: "left", marginTop: "2rem", marginLeft: "0" });
- apply_style_rule('RT·article h3' ,{ fontSize: "1.125rem", color: RT.config.theme.brand_tertiary, textAlign: "left", marginTop: "1.5rem", marginLeft: "4ch" });
- apply_style_rule('RT·article h4' ,{ fontSize: "1.05rem", color: RT.config.theme.content_main, fontWeight: "600", textAlign: "left", marginTop: "1.25rem", marginLeft: "8ch" });
- apply_style_rule('RT·article p, RT·article ul, RT·article ol' ,{ color: RT.config.theme.content_main, textAlign: "justify", marginBottom: "1rem", marginLeft: "0" });
- apply_style_rule('RT·article li' ,{ marginBottom: "0.5rem" });
- apply_style_rule('RT·article RT·code' ,{ fontFamily: "'Courier New', Courier, monospace", backgroundColor: RT.config.theme.surface_code, padding: "0.125rem 0.25rem", color: RT.config.theme.content_main });
- apply_style_rule('RT·article img' ,{ maxWidth: "100%", height: "auto", display: "block", margin: "1.5rem auto" });
+ // Apply specific element scales
+ const element_styles = [
+ [ 'RT·article h1', {
+ fontSize: "1.5rem",
+ textAlign: "center",
+ color: brand_primary,
+ fontWeight: "500",
+ marginTop: "1.5rem",
+ lineHeight: "1.15"
+ }],
+
+ [ 'RT·article h2', {
+ fontSize: "1.25rem",
+ color: brand_secondary,
+ textAlign: "left",
+ marginTop: "2rem",
+ marginLeft: "0"
+ }],
+
+ [ 'RT·article h3', {
+ fontSize: "1.125rem",
+ color: brand_tertiary,
+ textAlign: "left",
+ marginTop: "1.5rem",
+ marginLeft: "4ch"
+ }],
+
+ [ 'RT·article h4', {
+ fontSize: "1.05rem",
+ color: content_main,
+ fontWeight: "600",
+ textAlign: "left",
+ marginTop: "1.25rem",
+ marginLeft: "8ch"
+ }],
+
+ [ 'RT·article p, RT·article ul, RT·article ol', {
+ color: content_main,
+ textAlign: "justify",
+ marginBottom: "1rem",
+ marginLeft: "0"
+ }],
+
+ [ 'RT·article li', {
+ marginBottom: "0.5rem"
+ }],
+
+ [ 'RT·article RT·code', {
+ fontFamily: "'Courier New', Courier, monospace",
+ backgroundColor: surface_code,
+ padding: "0.125rem 0.25rem",
+ color: content_main
+ }],
+
+ [ 'RT·article img', {
+ maxWidth: "100%",
+ height: "auto",
+ display: "block",
+ margin: "1.5rem auto"
+ }]
+ ];
+
+ element_styles.forEach(rule => apply(rule[0], rule[1]));
}
- function execute_pagination_and_scroll(){
- debug.log('scroll' ,`8. Pagination layout starting.`);
- if(RT.paginate_by_element) RT.paginate_by_element();
- if(RT.page) RT.page();
+ // 3. The Core Layout Entry Function
+ function article_tech_ref(){
- let final_target = target_y;
- let use_hash = false;
- if (window.location.hash && !is_reload) {
- const hash_target = document.getElementById(window.location.hash.substring(1));
- if (hash_target) {
- use_hash = true;
- }
- }
-
- enforce_scroll(final_target ,use_hash ,0);
- }
-
- function enforce_scroll(target ,use_hash ,attempts){
- if (attempts > 15) {
- unlock_layout();
- return;
- }
-
- if (use_hash) {
- const hash_target = document.getElementById(window.location.hash.substring(1));
- if (hash_target) {
- hash_target.scrollIntoView();
+ // Execute the extracted style generator first
+ apply_article_styles();
+
+ // Dynamically enqueue the semantic processors
+ required_elements.forEach(name => {
+ if (typeof RT[name] === 'function') {
+ RT.Element.push(RT[name]);
+ } else {
+ RT.debug.warn('layout', 'Required element function missing: RT.' + name);
}
- } else {
- window.scrollTo(0 ,target);
- }
-
- let is_successful = use_hash ? true : (Math.abs(window.scrollY - target) < 5 || target === 0);
- if (is_successful && document.body.scrollHeight > 1000) {
- setTimeout(() => {
- if (!use_hash && Math.abs(window.scrollY - target) >= 5) {
- enforce_scroll(target ,use_hash ,attempts + 1);
- } else {
- unlock_layout();
- }
- }, 100);
- } else {
- setTimeout(() => enforce_scroll(target ,use_hash ,attempts + 1) ,50);
- }
- }
-
- function unlock_layout(){
- if (!is_layout_locked) return;
- is_layout_locked = false;
- document.dispatchEvent(new Event("RT_layout_complete"));
- }
-
- function bind_window_events(){
- window.addEventListener('scroll' ,() => {
- if (is_layout_locked) return;
- clearTimeout(scroll_timer);
- scroll_timer = setTimeout(() => {
- sessionStorage.setItem('RT_saved_y' ,window.scrollY);
- }, 200);
- }, { passive: true });
-
- window.addEventListener('beforeunload' ,() => {
- is_layout_locked = true;
});
}
- // Execution Outline
- configure_history();
- capture_scroll_target();
- load_elements();
- bind_window_events();
-
- document.addEventListener('DOMContentLoaded', () => {
- apply_style();
-
- if (window.RT.document_loaded) {
- window.RT.document_loaded(execute_pagination_and_scroll);
- } else {
- execute_pagination_and_scroll();
- }
- });
+ // 4. Register the layout function immediately upon parsing
+ RT.Element = RT.Element || [];
+ RT.Element.push(article_tech_ref);
})();
document.write(
'<script>' +
- 'window.RT.load("Core/utility");' +
'window.RT.load("Core/block_visibility_during_layout");' +
- 'window.RT.load("Theme");' +
'window.RT.load("Element/theme_selector");' +
'<\/script>'
);
-/*
- Theme: Golden Wheat (Light) - "Spanish Gold Edition"
- Standard: Theme 1.0
- Description: Light Parchment background with Oxblood Red ink.
-*/
-(function(){
- const RT = window.RT = window.RT || {};
-
- RT.theme = function(){
- const dictionary = {
- meta_is_dark: false
- ,meta_name: "Golden Wheat (Yellow)"
-
- // --- SURFACES ---
- ,surface_0: "oklch(0.95 0.02 90)"
- ,surface_1: "oklch(0.92 0.02 90)"
- ,surface_2: "oklch(0.97 0.01 90)"
- ,surface_3: "oklch(0.99 0 0)"
- ,surface_input: "oklch(0.94 0.01 90)"
- ,surface_code: "oklch(0.90 0.02 90)"
- ,surface_select: "oklch(0.85 0.05 25)"
-
- // --- CONTENT ---
- ,content_main: "oklch(0.20 0.02 25)"
- ,content_muted: "oklch(0.35 0.03 25)"
- ,content_subtle: "oklch(0.55 0.02 25)"
- ,content_inverse: "oklch(0.92 0.02 90)"
-
- // --- BRAND & ACTION ---
- ,brand_primary: "oklch(0.40 0.15 25)"
- ,brand_secondary: "oklch(0.45 0.14 25)"
- ,brand_tertiary: "oklch(0.50 0.12 25)"
- ,brand_link: "oklch(0.40 0.16 25)"
-
- // --- BORDERS ---
- ,border_faint: "oklch(0.85 0.02 90)"
- ,border_default: "oklch(0.75 0.03 90)"
- ,border_strong: "oklch(0.50 0.08 25)"
-
- // --- STATE & FEEDBACK ---
- ,state_success: "oklch(0.45 0.10 130)"
- ,state_warning: "oklch(0.55 0.15 45)"
- ,state_error: "oklch(0.45 0.15 25)"
- ,state_info: "oklch(0.50 0.12 240)"
-
- // --- SYNTAX ---
- ,syntax_keyword: "oklch(0.45 0.15 25)"
- ,syntax_string: "oklch(0.40 0.10 130)"
- ,syntax_func: "oklch(0.45 0.12 35)"
- ,syntax_comment: "oklch(0.60 0.02 90)"
- };
-
- // 1. Populate the Dictionary
- for (const [key, value] of Object.entries(dictionary)) {
- window.RT.theme('write', key, value);
- }
-
- // 2. Structural Safety Net
- if (!window.RT.theme('is_defined')) {
- window.RT.debug.error('theme', `Theme '${dictionary.meta_name}' failed structural completeness check. Missing keys detected.`);
- }
-
- // 3. Global Pseudo Elements
- const style_id = 'rt-global-overrides';
- if (!document.getElementById(style_id)) {
- const style = document.createElement('style');
- style.id = style_id;
-
- const [select_bg, select_fg, scroll_bg, scroll_thumb, scroll_hover, content_main] =
- window.RT.theme('read', 'surface_select', 'brand_primary', 'surface_0', 'border_default', 'brand_secondary', 'content_main');
-
- style.textContent = `
- ::selection { background: ${select_bg}; color: ${select_fg}; }
- ::-moz-selection { background: ${select_bg}; color: ${select_fg}; }
-
- ::-webkit-scrollbar { width: 12px; }
- ::-webkit-scrollbar-track { background: ${scroll_bg}; }
- ::-webkit-scrollbar-thumb {
- background: ${scroll_thumb};
- border: 2px solid ${scroll_bg};
- border-radius: 8px;
- }
- ::-webkit-scrollbar-thumb:hover { background: ${scroll_hover}; }
-
- rt-article p, rt-article li {
- text-shadow: 0px 0px 0.5px rgba(0,0,0, 0.2);
- }
-
- .MathJax, .MathJax_Display, .mjx-chtml {
- color: ${content_main} !important;
- fill: ${content_main} !important;
- stroke: ${content_main} !important;
- }
- `;
- document.head.appendChild(style);
+// Theme/golden_wheat.js
+
+window.RT = window.RT || {};
+window.RT.theme_library = window.RT.theme_library || {};
+
+window.RT.theme_library['golden_wheat'] = {
+ meta: {
+ is_dark: false,
+ name: "Golden Wheat (Yellow)"
+ },
+ surface: {
+ 0: "oklch(0.95 0.02 90)",
+ 1: "oklch(0.92 0.02 90)",
+ 2: "oklch(0.97 0.01 90)",
+ 3: "oklch(0.99 0 0)",
+ input: "oklch(0.94 0.01 90)",
+ code: "oklch(0.90 0.02 90)",
+ select: "oklch(0.85 0.05 25)"
+ },
+ content: {
+ main: "oklch(0.20 0.02 25)",
+ muted: "oklch(0.35 0.03 25)",
+ subtle: "oklch(0.55 0.02 25)",
+ inverse: "oklch(0.92 0.02 90)"
+ },
+ brand: {
+ primary: "oklch(0.40 0.15 25)",
+ secondary: "oklch(0.45 0.14 25)",
+ tertiary: "oklch(0.50 0.12 25)",
+ link: "oklch(0.40 0.16 25)"
+ },
+ border: {
+ faint: "oklch(0.85 0.02 90)",
+ regular: "oklch(0.75 0.03 90)",
+ strong: "oklch(0.50 0.08 25)"
+ },
+ state: {
+ success: "oklch(0.45 0.10 130)",
+ warning: "oklch(0.55 0.15 45)",
+ error: "oklch(0.45 0.15 25)",
+ info: "oklch(0.50 0.12 240)"
+ },
+ syntax: {
+ keyword: "oklch(0.45 0.15 25)",
+ string: "oklch(0.40 0.10 130)",
+ func: "oklch(0.45 0.12 35)",
+ comment: "oklch(0.60 0.02 90)"
+ },
+ custom_css: `
+ rt-article p, rt-article li { text-shadow: 0px 0px 0.5px rgba(0,0,0, 0.2); }
+ .MathJax, .MathJax_Display, .mjx-chtml {
+ color: oklch(0.20 0.02 25) !important;
+ fill: oklch(0.20 0.02 25) !important;
+ stroke: oklch(0.20 0.02 25) !important;
}
- };
-})();
+ `
+};
-/*
- Theme: Inverse Wheat (Dark)
- Standard: Theme 1.0
- Description: High contrast Amber on Deep Charcoal.
-*/
-(function(){
- const RT = window.RT = window.RT || {};
-
- RT.theme = function(){
- const dictionary = {
- meta_is_dark: true
- ,meta_name: "Inverse Wheat"
-
- // --- SURFACES ---
- ,surface_0: "oklch(0.15 0 0)"
- ,surface_1: "oklch(0.18 0 0)"
- ,surface_2: "oklch(0.21 0 0)"
- ,surface_3: "oklch(0.24 0 0)"
- ,surface_input: "oklch(0.19 0 0)"
- ,surface_code: "oklch(0.17 0 0)"
- ,surface_select: "oklch(0.30 0.05 80)"
-
- // --- CONTENT ---
- ,content_main: "oklch(0.85 0.05 90)"
- ,content_muted: "oklch(0.70 0.03 90)"
- ,content_subtle: "oklch(0.50 0.02 90)"
- ,content_inverse: "oklch(0.15 0 0)"
-
- // --- BRAND & ACTION ---
- ,brand_primary: "oklch(0.75 0.15 80)"
- ,brand_secondary: "oklch(0.65 0.12 70)"
- ,brand_tertiary: "oklch(0.60 0.10 60)"
- ,brand_link: "oklch(0.75 0.15 85)"
-
- // --- BORDERS ---
- ,border_faint: "oklch(0.25 0.01 90)"
- ,border_default: "oklch(0.35 0.02 90)"
- ,border_strong: "oklch(0.45 0.03 90)"
-
- // --- STATE & FEEDBACK ---
- ,state_success: "oklch(0.60 0.12 130)"
- ,state_warning: "oklch(0.65 0.15 50)"
- ,state_error: "oklch(0.55 0.15 25)"
- ,state_info: "oklch(0.60 0.10 240)"
-
- // --- SYNTAX ---
- ,syntax_keyword: "oklch(0.70 0.15 50)"
- ,syntax_string: "oklch(0.75 0.10 130)"
- ,syntax_func: "oklch(0.80 0.12 85)"
- ,syntax_comment: "oklch(0.55 0.02 90)"
- };
-
- // 1. Populate the Dictionary
- for (const [key, value] of Object.entries(dictionary)) {
- window.RT.theme('write', key, value);
- }
-
- // 2. Structural Safety Net
- if (!window.RT.theme('is_defined')) {
- window.RT.debug.error('theme', `Theme '${dictionary.meta_name}' failed structural completeness check. Missing keys detected.`);
- }
-
- // 3. Global Pseudo Elements
- const style_id = 'rt-global-overrides';
- if (!document.getElementById(style_id)) {
- const style = document.createElement('style');
- style.id = style_id;
-
- const [select_bg, select_fg, scroll_bg, scroll_thumb, scroll_hover] =
- window.RT.theme('read', 'surface_select', 'brand_primary', 'surface_0', 'border_default', 'brand_secondary');
-
- style.textContent = `
- ::selection { background: ${select_bg}; color: ${select_fg}; }
- ::-moz-selection { background: ${select_bg}; color: ${select_fg}; }
-
- ::-webkit-scrollbar { width: 12px; }
- ::-webkit-scrollbar-track { background: ${scroll_bg}; }
- ::-webkit-scrollbar-thumb {
- background: ${scroll_thumb};
- border: 2px solid ${scroll_bg};
- border-radius: 8px;
- }
- ::-webkit-scrollbar-thumb:hover { background: ${scroll_hover}; }
-
- img.rt-diagram { filter: invert(1) hue-rotate(180deg); }
- `;
- document.head.appendChild(style);
- }
- };
-})();
+// Theme/inverse_wheat.js
+
+window.RT = window.RT || {};
+window.RT.theme_library = window.RT.theme_library || {};
+
+window.RT.theme_library['inverse_wheat'] = {
+ meta: {
+ is_dark: true,
+ name: "Inverse Wheat"
+ },
+ surface: {
+ 0: "oklch(0.15 0 0)",
+ 1: "oklch(0.18 0 0)",
+ 2: "oklch(0.21 0 0)",
+ 3: "oklch(0.24 0 0)",
+ input: "oklch(0.19 0 0)",
+ code: "oklch(0.17 0 0)",
+ select: "oklch(0.30 0.05 80)"
+ },
+ content: {
+ main: "oklch(0.85 0.05 90)",
+ muted: "oklch(0.70 0.03 90)",
+ subtle: "oklch(0.50 0.02 90)",
+ inverse: "oklch(0.15 0 0)"
+ },
+ brand: {
+ primary: "oklch(0.75 0.15 80)",
+ secondary: "oklch(0.65 0.12 70)",
+ tertiary: "oklch(0.60 0.10 60)",
+ link: "oklch(0.75 0.15 85)"
+ },
+ border: {
+ faint: "oklch(0.25 0.01 90)",
+ regular: "oklch(0.35 0.02 90)",
+ strong: "oklch(0.45 0.03 90)"
+ },
+ state: {
+ success: "oklch(0.60 0.12 130)",
+ warning: "oklch(0.65 0.15 50)",
+ error: "oklch(0.55 0.15 25)",
+ info: "oklch(0.60 0.10 240)"
+ },
+ syntax: {
+ keyword: "oklch(0.70 0.15 50)",
+ string: "oklch(0.75 0.10 130)",
+ func: "oklch(0.80 0.12 85)",
+ comment: "oklch(0.55 0.02 90)"
+ },
+ custom_css: `
+ img.rt-diagram { filter: invert(1) hue-rotate(180deg); }
+ `
+};
--- /dev/null
+// Theme/manifest.js
+
+window.RT = window.RT || {};
+
+(function() {
+ const themes = [
+ 'inverse_wheat',
+ 'golden_wheat',
+ 'wheat'
+ ];
+
+ themes.forEach(theme_name => {
+ window.RT.load('Theme/' + theme_name);
+ });
+})();
+
-/*
- Theme: Classic Wheat (Light)
- Standard: Theme 1.0
- Description: Warm paper tones with Burnt Orange accents.
-*/
-(function(){
- const RT = window.RT = window.RT || {};
-
- RT.theme_light = function(){
- const dictionary = {
- meta_is_dark: false
- ,meta_name: "Classic Wheat"
-
- // --- SURFACES ---
- ,surface_0: "oklch(0.95 0.02 80)"
- ,surface_1: "oklch(0.92 0.02 80)"
- ,surface_2: "oklch(0.97 0.01 80)"
- ,surface_3: "oklch(0.99 0 0)"
- ,surface_input: "oklch(0.96 0.01 80)"
- ,surface_code: "oklch(0.92 0.01 80)"
- ,surface_select: "oklch(0.88 0.06 80)"
-
- // --- CONTENT ---
- ,content_main: "oklch(0.25 0.02 60)"
- ,content_muted: "oklch(0.45 0.03 60)"
- ,content_subtle: "oklch(0.65 0.02 60)"
- ,content_inverse: "oklch(0.94 0.02 80)"
-
- // --- BRAND & ACTION ---
- ,brand_primary: "oklch(0.50 0.15 50)"
- ,brand_secondary: "oklch(0.55 0.12 60)"
- ,brand_tertiary: "oklch(0.60 0.10 45)"
- ,brand_link: "oklch(0.50 0.16 50)"
-
- // --- BORDERS ---
- ,border_faint: "oklch(0.85 0.02 80)"
- ,border_default: "oklch(0.75 0.02 80)"
- ,border_strong: "oklch(0.55 0.04 80)"
-
- // --- STATE & FEEDBACK ---
- ,state_success: "oklch(0.50 0.10 130)"
- ,state_warning: "oklch(0.60 0.15 50)"
- ,state_error: "oklch(0.50 0.15 25)"
- ,state_info: "oklch(0.55 0.10 240)"
-
- // --- SYNTAX ---
- ,syntax_keyword: "oklch(0.50 0.14 50)"
- ,syntax_string: "oklch(0.45 0.10 130)"
- ,syntax_func: "oklch(0.50 0.10 320)"
- ,syntax_comment: "oklch(0.65 0.02 80)"
- };
-
- // 1. Populate the Dictionary
- for (const [key, value] of Object.entries(dictionary)) {
- window.RT.theme('write', key, value);
- }
-
- // 2. Structural Safety Net
- if (!window.RT.theme('is_defined')) {
- window.RT.debug.error('theme', `Theme '${dictionary.meta_name}' failed structural completeness check. Missing keys detected.`);
- }
-
- // 3. Global Pseudo Elements
- const style_id = 'rt-global-overrides';
- if (!document.getElementById(style_id)) {
- const style = document.createElement('style');
- style.id = style_id;
-
- const [select_bg, select_fg, scroll_bg, scroll_thumb, scroll_hover] =
- window.RT.theme('read', 'surface_select', 'brand_primary', 'surface_0', 'border_default', 'brand_secondary');
-
- style.textContent = `
- ::selection { background: ${select_bg}; color: ${select_fg}; }
- ::-moz-selection { background: ${select_bg}; color: ${select_fg}; }
-
- ::-webkit-scrollbar { width: 12px; }
- ::-webkit-scrollbar-track { background: ${scroll_bg}; }
- ::-webkit-scrollbar-thumb {
- background: ${scroll_thumb};
- border: 2px solid ${scroll_bg};
- border-radius: 8px;
- }
- ::-webkit-scrollbar-thumb:hover { background: ${scroll_hover}; }
- `;
- document.head.appendChild(style);
- }
- };
-})();
+// Theme/wheat.js
+
+window.RT = window.RT || {};
+window.RT.theme_library = window.RT.theme_library || {};
+
+window.RT.theme_library['wheat'] = {
+ meta: {
+ is_dark: false,
+ name: "Classic Wheat"
+ },
+ surface: {
+ 0: "oklch(0.95 0.02 80)",
+ 1: "oklch(0.92 0.02 80)",
+ 2: "oklch(0.97 0.01 80)",
+ 3: "oklch(0.99 0 0)",
+ input: "oklch(0.96 0.01 80)",
+ code: "oklch(0.92 0.01 80)",
+ select: "oklch(0.88 0.06 80)"
+ },
+ content: {
+ main: "oklch(0.25 0.02 60)",
+ muted: "oklch(0.45 0.03 60)",
+ subtle: "oklch(0.65 0.02 60)",
+ inverse: "oklch(0.94 0.02 80)"
+ },
+ brand: {
+ primary: "oklch(0.50 0.15 50)",
+ secondary: "oklch(0.55 0.12 60)",
+ tertiary: "oklch(0.60 0.10 45)",
+ link: "oklch(0.50 0.16 50)"
+ },
+ border: {
+ faint: "oklch(0.85 0.02 80)",
+ regular: "oklch(0.75 0.02 80)",
+ strong: "oklch(0.55 0.04 80)"
+ },
+ state: {
+ success: "oklch(0.50 0.10 130)",
+ warning: "oklch(0.60 0.15 50)",
+ error: "oklch(0.50 0.15 25)",
+ info: "oklch(0.55 0.10 240)"
+ },
+ syntax: {
+ keyword: "oklch(0.50 0.14 50)",
+ string: "oklch(0.45 0.10 130)",
+ func: "oklch(0.50 0.10 320)",
+ comment: "oklch(0.65 0.02 80)"
+ },
+ custom_css: ``
+};