88< link rel ="preconnect " href ="https://fonts.googleapis.com ">
99< link href ="https://fonts.googleapis.com/css2?family=Crimson+Pro:ital,wght@0,300;0,400;0,600;1,300;1,400&family=JetBrains+Mono:wght@300;400;500;700&family=Syne:wght@400;600;700;800&display=swap " rel ="stylesheet ">
1010< style >
11+ /* Your existing CSS - kept identical to your working version */
1112: root {
1213 --bg : # 07070d ; --bg2 : # 0d0d18 ; --bg3 : # 12121f ; --bg4 : # 171726 ;
1314 --border : rgba (212 , 174 , 60 , 0.18 ); --border2 : rgba (212 , 174 , 60 , 0.08 );
3031html {font-size : 15px ;scroll-behavior : smooth;}
3132body {background : var (--bg );color : var (--text );font-family : var (--mono );min-height : 100vh ;overflow-x : hidden;}
3233# bg-canvas {position : fixed;top : 0 ;left : 0 ;width : 100% ;height : 100% ;pointer-events : none;z-index : 0 ;opacity : 0.3 ;}
33-
3434.status-bar {background : linear-gradient (135deg , rgba (64 , 196 , 255 , 0.06 ), rgba (212 , 174 , 60 , 0.04 ));border-bottom : 1px solid var (--border );padding : 8px 24px ;display : flex;align-items : center;gap : 8px ;font-size : 0.68rem ;color : var (--text-dim );flex-wrap : wrap;position : relative;z-index : 2 ;}
3535.status-bar .dot {width : 6px ;height : 6px ;border-radius : 50% ;background : var (--frozen );box-shadow : 0 0 6px var (--frozen );animation : pulse-dot 2s infinite;}
3636@keyframes pulse-dot{0% , 100%{opacity : 1 ;}50% {opacity : 0.4 ;}}
272272
273273< script >
274274// ============================================================
275- // STP SEAL TOOL v3.0 – Full Calendar + Backend Integration
275+ // STP SEAL TOOL v3.0 – Backend Connected
276276// ============================================================
277277
278- const BACKEND_URL = '/api/tools' ;
278+ // Try multiple possible endpoint paths (your tools.js handles both /api/stp-seal and /api/tools)
279+ const BACKEND_PATHS = [ '/api/tools' , '/api/stp-seal' ] ;
280+ let currentPathIndex = 0 ;
279281
280282let CURRENT_ENTRY = null ;
281283let sessionLedger = [ ] ;
282284
283- // ========== FULL CALENDAR FUNCTIONS (Local) ==========
285+ // ========== FULL CALENDAR FUNCTIONS (Local fallback ) ==========
284286const GREGORIAN_MONTHS = [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' , 'August' , 'September' , 'October' , 'November' , 'December' ] ;
285287const MOON_NAMES = [ 'Magnetic' , 'Lunar' , 'Electric' , 'Self-Existing' , 'Overtone' , 'Rhythmic' , 'Resonant' , 'Galactic' , 'Solar' , 'Planetary' , 'Spectral' , 'Crystal' , 'Cosmic' ] ;
286288
287- // Hebrew calendar constants
288289const HEBREW_EPOCH_JD = 347998 ;
289290const COMMON_MONTHS = [ 'Tishri' , 'Cheshvan' , 'Kislev' , 'Tevet' , 'Shevat' , 'Adar' , 'Nisan' , 'Iyar' , 'Sivan' , 'Tammuz' , 'Av' , 'Elul' ] ;
290291const LEAP_MONTHS = [ 'Tishri' , 'Cheshvan' , 'Kislev' , 'Tevet' , 'Shevat' , 'Adar I' , 'Adar II' , 'Nisan' , 'Iyar' , 'Sivan' , 'Tammuz' , 'Av' , 'Elul' ] ;
396397 statusCard . className = 'ledger-status-card pending' ;
397398 statusCard . innerHTML = '<div class="lsc-icon">⟳</div><div class="lsc-body"><div class="lsc-label">Creating Ledger Entry…</div><div class="lsc-sub">Contacting backend</div></div>' ;
398399
399- try {
400- const response = await fetch ( BACKEND_URL , {
401- method : 'POST' ,
402- headers : { 'Content-Type' : 'application/json' } ,
403- body : JSON . stringify ( { entry : content , type : template , sessionId : crypto . randomUUID ( ) , userId : author || null } )
404- } ) ;
405-
406- const data = await response . json ( ) ;
407-
408- if ( ! response . ok || ! data . success ) {
409- throw new Error ( data . error || data . message || 'Backend error' ) ;
400+ let lastError = null ;
401+
402+ for ( let i = 0 ; i < BACKEND_PATHS . length ; i ++ ) {
403+ const endpoint = BACKEND_PATHS [ i ] ;
404+ try {
405+ const response = await fetch ( endpoint , {
406+ method : 'POST' ,
407+ headers : { 'Content-Type' : 'application/json' } ,
408+ body : JSON . stringify ( { entry : content , type : template , sessionId : crypto . randomUUID ( ) , userId : author || null } )
409+ } ) ;
410+
411+ const data = await response . json ( ) ;
412+
413+ if ( response . ok && data . success ) {
414+ // Success! Use this endpoint
415+ handleSealSuccess ( data , content , author , template ) ;
416+ return ;
417+ } else {
418+ lastError = data . error || data . message || `HTTP ${ response . status } ` ;
419+ }
420+ } catch ( err ) {
421+ lastError = err . message ;
410422 }
423+ }
424+
425+ // All endpoints failed
426+ document . getElementById ( 'seal-error' ) . textContent = `Backend error: ${ lastError } ` ;
427+ document . getElementById ( 'seal-error' ) . classList . add ( 'active' ) ;
428+ document . getElementById ( 'seal-result' ) . classList . remove ( 'active' ) ;
429+ document . getElementById ( 'seal-placeholder' ) . style . display = 'block' ;
430+ btn . disabled = false ;
431+ btn . textContent = '🔒 GENERATE SEAL + ENTER LEDGER' ;
432+ }
411433
412- const now = new Date ( ) ;
413- const y = now . getUTCFullYear ( ) , m = now . getUTCMonth ( ) + 1 , d = now . getUTCDate ( ) ;
414-
415- CURRENT_ENTRY = {
416- ledger_id : `STP-${ data . template_name || template } -${ gregorianStringFull ( y , m , d ) . replace ( / [ , \s ] + / g, '-' ) } -${ data . seal . substring ( 0 , 6 ) . toUpperCase ( ) } ` ,
417- template : template ,
418- template_name : data . template_name ,
419- content : content ,
420- author : author || null ,
421- content_hash : `sha256:${ data . seal } ` ,
422- seal : {
423- gregorian : data . gregorian || gregorianStringFull ( y , m , d ) ,
424- hebrew : data . hebrew || hebrewString ( y , m , d ) ,
425- dreamspell : data . dreamspell || dreamspellString ( y , m , d ) ,
426- unix_utc : data . unix_utc || Math . floor ( now . getTime ( ) / 1000 ) ,
427- seal_method : 'SHA-256-SubtleCrypto-FROZEN-2.0'
428- } ,
429- github_issue_url : data . issue_url || null ,
430- ledger_file : data . ledger_file || null ,
431- frozen : 'FROZEN-2.0' ,
432- sealed_at : now . toISOString ( )
433- } ;
434-
435- document . getElementById ( 'result-ledger-id' ) . textContent = CURRENT_ENTRY . ledger_id ;
436- document . getElementById ( 'result-gregorian' ) . textContent = CURRENT_ENTRY . seal . gregorian ;
437- document . getElementById ( 'result-hebrew' ) . textContent = CURRENT_ENTRY . seal . hebrew ;
438- document . getElementById ( 'result-dreamspell' ) . textContent = CURRENT_ENTRY . seal . dreamspell ;
439- document . getElementById ( 'result-hash-display' ) . textContent = data . seal ;
440- document . getElementById ( 'result-json' ) . innerHTML = syntaxHighlight ( JSON . stringify ( CURRENT_ENTRY , null , 2 ) ) ;
441-
442- if ( data . issue_url ) {
443- statusCard . className = 'ledger-status-card' ;
444- statusCard . innerHTML = `<div class="lsc-icon">✓</div><div class="lsc-body"><div class="lsc-label">Ledger Entry Created</div><div class="lsc-sub">GitHub issue sealed</div><a href="${ data . issue_url } " target="_blank" class="lsc-link">View GitHub Issue ↗</a></div>` ;
445- } else if ( data . github_error ) {
446- statusCard . className = 'ledger-status-card failed' ;
447- statusCard . innerHTML = `<div class="lsc-icon">⚠</div><div class="lsc-body"><div class="lsc-label">Ledger Failed</div><div class="lsc-sub">${ data . github_error } </div></div>` ;
448- } else {
449- statusCard . className = 'ledger-status-card pending' ;
450- statusCard . innerHTML = `<div class="lsc-icon">⟳</div><div class="lsc-body"><div class="lsc-label">Ledger Pending</div><div class="lsc-sub">Seal recorded locally</div></div>` ;
451- }
434+ function handleSealSuccess ( data , content , author , template ) {
435+ const now = new Date ( ) ;
436+ const y = now . getUTCFullYear ( ) , m = now . getUTCMonth ( ) + 1 , d = now . getUTCDate ( ) ;
437+
438+ CURRENT_ENTRY = {
439+ ledger_id : `STP-${ data . template_name || template } -${ gregorianStringFull ( y , m , d ) . replace ( / [ , \s ] + / g, '-' ) } -${ data . seal . substring ( 0 , 6 ) . toUpperCase ( ) } ` ,
440+ template : template ,
441+ template_name : data . template_name ,
442+ content : content ,
443+ author : author || null ,
444+ content_hash : `sha256:${ data . seal } ` ,
445+ seal : {
446+ gregorian : data . gregorian || gregorianStringFull ( y , m , d ) ,
447+ hebrew : data . hebrew || hebrewString ( y , m , d ) ,
448+ dreamspell : data . dreamspell || dreamspellString ( y , m , d ) ,
449+ unix_utc : data . unix_utc || Math . floor ( now . getTime ( ) / 1000 ) ,
450+ seal_method : 'SHA-256-SubtleCrypto-FROZEN-2.0'
451+ } ,
452+ github_issue_url : data . issue_url || null ,
453+ ledger_file : data . ledger_file || null ,
454+ frozen : 'FROZEN-2.0' ,
455+ sealed_at : now . toISOString ( )
456+ } ;
457+
458+ document . getElementById ( 'result-ledger-id' ) . textContent = CURRENT_ENTRY . ledger_id ;
459+ document . getElementById ( 'result-gregorian' ) . textContent = CURRENT_ENTRY . seal . gregorian ;
460+ document . getElementById ( 'result-hebrew' ) . textContent = CURRENT_ENTRY . seal . hebrew ;
461+ document . getElementById ( 'result-dreamspell' ) . textContent = CURRENT_ENTRY . seal . dreamspell ;
462+ document . getElementById ( 'result-hash-display' ) . textContent = data . seal ;
463+ document . getElementById ( 'result-json' ) . innerHTML = syntaxHighlight ( JSON . stringify ( CURRENT_ENTRY , null , 2 ) ) ;
452464
453- sessionLedger . unshift ( CURRENT_ENTRY ) ;
454- if ( sessionLedger . length > 50 ) sessionLedger . pop ( ) ;
455- localStorage . setItem ( 'stp-session-ledger' , JSON . stringify ( sessionLedger ) ) ;
456- renderLedger ( ) ;
457- document . getElementById ( 'reset-btn' ) . classList . add ( 'visible' ) ;
458-
459- } catch ( err ) {
460- console . error ( 'Seal error:' , err ) ;
461- document . getElementById ( 'seal-error' ) . textContent = err . message ;
462- document . getElementById ( 'seal-error' ) . classList . add ( 'active' ) ;
463- document . getElementById ( 'seal-result' ) . classList . remove ( 'active' ) ;
464- document . getElementById ( 'seal-placeholder' ) . style . display = 'block' ;
465- } finally {
466- btn . disabled = false ;
467- btn . textContent = '🔒 GENERATE SEAL + ENTER LEDGER' ;
465+ const statusCard = document . getElementById ( 'ledger-status-card' ) ;
466+ if ( data . issue_url ) {
467+ statusCard . className = 'ledger-status-card' ;
468+ statusCard . innerHTML = `<div class="lsc-icon">✓</div><div class="lsc-body"><div class="lsc-label">Ledger Entry Created</div><div class="lsc-sub">GitHub issue sealed</div><a href="${ data . issue_url } " target="_blank" class="lsc-link">View GitHub Issue ↗</a></div>` ;
469+ } else if ( data . github_error ) {
470+ statusCard . className = 'ledger-status-card failed' ;
471+ statusCard . innerHTML = `<div class="lsc-icon">⚠</div><div class="lsc-body"><div class="lsc-label">Ledger Failed</div><div class="lsc-sub">${ data . github_error } </div></div>` ;
472+ } else {
473+ statusCard . className = 'ledger-status-card pending' ;
474+ statusCard . innerHTML = `<div class="lsc-icon">⟳</div><div class="lsc-body"><div class="lsc-label">Ledger Pending</div><div class="lsc-sub">Seal recorded locally</div></div>` ;
468475 }
476+
477+ sessionLedger . unshift ( CURRENT_ENTRY ) ;
478+ if ( sessionLedger . length > 50 ) sessionLedger . pop ( ) ;
479+ localStorage . setItem ( 'stp-session-ledger' , JSON . stringify ( sessionLedger ) ) ;
480+ renderLedger ( ) ;
481+ document . getElementById ( 'reset-btn' ) . classList . add ( 'visible' ) ;
482+
483+ const btn = document . getElementById ( 'seal-btn' ) ;
484+ btn . disabled = false ;
485+ btn . textContent = '🔒 GENERATE SEAL + ENTER LEDGER' ;
469486}
470487
471488function resetTool ( ) {
606623} ) ( ) ;
607624</ script >
608625</ body >
609- </ html >
626+ </ html >
0 commit comments