8888.cta-arrow { font-size : 14px ; transition : transform 0.2s ; }
8989.cta-btn : hover .cta-arrow { transform : translateX (4px ); }
9090
91- .hero-status { display : flex; gap : 32px ; flex-wrap : wrap; margin-top : 60px ; padding-top : 32px ; border-top : 1px solid var (--border ); opacity : 0 ; animation : fadeIn 0.8s var (--ease ) 1.1s forwards; }
92- .status-item { display : flex; flex-direction : column; gap : 4px ; }
93- .status-val { font-family : var (--mono ); font-size : 22px ; color : var (--amber ); letter-spacing : 1px ; }
94- .status-key { font-family : var (--mono ); font-size : 10px ; color : var (--muted ); letter-spacing : 2px ; text-transform : uppercase; }
91+ /* ── TRIPLE TIME DISPLAY ── */
92+ .triple-time {
93+ display : grid; grid-template-columns : repeat (3 , 1fr );
94+ gap : 1px ; background : var (--border );
95+ border : 1px solid var (--border );
96+ margin-top : 60px ; padding-top : 0 ;
97+ border-top : none;
98+ opacity : 0 ; animation : fadeIn 0.8s var (--ease ) 1.1s forwards;
99+ position : relative;
100+ }
101+ .triple-time ::before {
102+ content : '' ; position : absolute; top : -32px ; left : 0 ; right : 0 ;
103+ height : 1px ; background : var (--border );
104+ }
105+ .time-cell {
106+ background : var (--bg ); padding : 18px 20px ; transition : background 0.2s ;
107+ }
108+ .time-cell : hover { background : var (--surface ); }
109+ .time-sys {
110+ font-family : var (--mono ); font-size : 9px ; letter-spacing : 2px ;
111+ color : var (--amber-d ); text-transform : uppercase; margin-bottom : 6px ;
112+ }
113+ .time-val {
114+ font-family : var (--mono ); font-size : 14px ; color : var (--amber );
115+ letter-spacing : 1px ; line-height : 1.3 ; min-height : 36px ;
116+ display : flex; align-items : center;
117+ }
118+ .time-val .loading { color : var (--dim ); font-size : 11px ; }
95119
96120section { position : relative; z-index : 1 ; padding : 80px 40px ; max-width : 1200px ; margin : 0 auto; }
97121.section-header { display : flex; align-items : center; gap : 16px ; margin-bottom : 48px ; }
144168.work-card-coming { opacity : 0.4 ; pointer-events : none; }
145169.coming-pill { display : inline-block; font-family : var (--mono ); font-size : 9px ; letter-spacing : 2px ; color : var (--muted ); border : 1px solid var (--dim ); padding : 2px 8px ; text-transform : uppercase; margin-top : 12px ; }
146170
147- /* Accent border per domain */
148171.work-card .live-field { border-left : 2px solid var (--cyan ); }
149172.work-card .live-edu { border-left : 2px solid var (--edu ); }
150173
160183.m-mod { background : rgba (240 , 165 , 0 , 0.1 ); color : var (--amber ); border : 1px solid var (--amber-d ); }
161184.m-nascent { background : rgba (64 , 196 , 255 , 0.08 ); color : # 40c4ff ; border : 1px solid # 1a4a5a ; }
162185
186+ /* Stack path link */
187+ .stack-path {
188+ display : flex; align-items : flex-start; gap : 14px ;
189+ padding : 16px 20px ; background : var (--bg );
190+ border : 1px solid var (--border ); text-decoration : none;
191+ transition : border-color 0.2s , background 0.2s ; margin-top : 20px ;
192+ }
193+ .stack-path : hover { border-color : var (--amber ); background : var (--surface ); }
194+ .stack-path-icon { font-size : 18px ; flex-shrink : 0 ; padding-top : 2px ; }
195+ .stack-path-label { font-family : var (--mono ); font-size : 10px ; letter-spacing : 2px ; color : var (--amber ); text-transform : uppercase; margin-bottom : 3px ; }
196+ .stack-path-desc { font-family : var (--sans ); font-size : 13px ; font-weight : 300 ; color : var (--muted ); }
197+
163198.certify-strip { background : var (--surface ); border : 1px solid var (--border ); border-left : 3px solid var (--gold ); padding : 32px 36px ; display : flex; align-items : center; gap : 36px ; flex-wrap : wrap; }
164199.certify-strip svg { flex-shrink : 0 ; }
165200.certify-text h3 { font-family : var (--sans ); font-size : 22px ; font-weight : 700 ; letter-spacing : 2px ; color : var (--gold ); text-transform : uppercase; margin-bottom : 8px ; }
183218 .hero { padding : 80px 20px 60px ; }
184219 section { padding : 60px 20px ; }
185220 footer { padding : 32px 20px ; }
186- .hero-status { gap : 20 px ; }
221+ .triple-time { grid-template-columns : 1 fr ; }
187222 .services-grid { grid-template-columns : 1fr ; }
188223}
189224</ style >
@@ -217,12 +252,21 @@ <h1 class="hero-name">Sheldon K.<em>Salmon</em></h1>
217252 < a href ="/services/ " class ="cta-btn "> < span > Engage Services</ span > < span class ="cta-arrow "> →</ span > </ a >
218253 < a href ="/certify/ " class ="cta-btn "> < span > Verify a Certification</ span > < span class ="cta-arrow "> →</ span > </ a >
219254 </ div >
220- < div class ="hero-status ">
221- < div class ="status-item "> < span class ="status-val "> AION v3.0</ span > < span class ="status-key "> Constitutional Stack</ span > </ div >
222- < div class ="status-item "> < span class ="status-val "> STP v2.0</ span > < span class ="status-key "> Trace Protocol</ span > </ div >
223- < div class ="status-item "> < span class ="status-val "> 17+</ span > < span class ="status-key "> Frameworks Deployed</ span > </ div >
224- < div class ="status-item "> < span class ="status-val "> LEDGER-011</ span > < span class ="status-key "> Current Seal</ span > </ div >
225- < div class ="status-item "> < span class ="status-val "> Mar 2026</ span > < span class ="status-key "> Active Build</ span > </ div >
255+
256+ <!-- TRIPLE TIME DISPLAY -->
257+ < div class ="triple-time " style ="margin-top:60px; ">
258+ < div class ="time-cell ">
259+ < div class ="time-sys "> Gregorian</ div >
260+ < div class ="time-val " id ="tt-gregorian "> —</ div >
261+ </ div >
262+ < div class ="time-cell ">
263+ < div class ="time-sys "> 13 Moon · Dreamspell</ div >
264+ < div class ="time-val " id ="tt-dreamspell "> —</ div >
265+ </ div >
266+ < div class ="time-cell ">
267+ < div class ="time-sys "> Hebrew Calendar</ div >
268+ < div class ="time-val " id ="tt-hebrew "> —</ div >
269+ </ div >
226270 </ div >
227271</ div >
228272
@@ -395,9 +439,18 @@ <h2 class="section-title">The AION Stack</h2>
395439 < tr > < td class ="fw-name "> EIGHT LAWS</ td > < td class ="fw-version "> v1.0</ td > < td class ="fw-function "> Sovereignty Stack — Laws 1-8 active · Law 9 dark by design</ td > < td > < span class ="convergence-badge m-mod "> CONSTITUTIONAL</ span > </ td > </ tr >
396440 </ tbody >
397441 </ table >
398- < div style ="margin-top:16px; font-family:var(--mono); font-size:10px; color:var(--muted); letter-spacing:1px; ">
442+ < div style ="margin-top:16px; font-family:var(--mono); font-size:10px; color:var(--muted); letter-spacing:1px; margin-bottom:4px; ">
399443 M-STRONG: validated · M-MODERATE: tested · M-NASCENT: specified, building · CONSTITUTIONAL: foundational
400444 </ div >
445+
446+ <!-- Stack path -->
447+ < a href ="/stack/ " class ="stack-path ">
448+ < span class ="stack-path-icon "> ◈</ span >
449+ < div >
450+ < div class ="stack-path-label "> Full Stack Documentation →</ div >
451+ < div class ="stack-path-desc "> All 17 frameworks. Version history. Convergence records. FCL entries. Protocol I registrations. The complete AION Constitutional Stack in one place.</ div >
452+ </ div >
453+ </ a >
401454</ section >
402455
403456<!-- CERTIFICATION -->
@@ -445,6 +498,7 @@ <h3>Sovereign Trace Protocol</h3>
445498 < ul class ="footer-links ">
446499 < li > < a href ="/simulators/ "> Simulators</ a > </ li >
447500 < li > < a href ="/services/ "> Services</ a > </ li >
501+ < li > < a href ="/stack/ "> Stack</ a > </ li >
448502 < li > < a href ="/certify/ "> Certify</ a > </ li >
449503 < li > < a href ="/about/ "> About</ a > </ li >
450504 < li > < a href ="https://github.com/AionSystem " target ="_blank " rel ="noopener "> GitHub ↗</ a > </ li >
@@ -453,6 +507,7 @@ <h3>Sovereign Trace Protocol</h3>
453507</ footer >
454508
455509< script >
510+ /* ── CANVAS ─────────────────────────────── */
456511const canvas = document . getElementById ( 'hero-canvas' ) ;
457512const ctx = canvas . getContext ( '2d' ) ;
458513let W , H , particles = [ ] , signals = [ ] , t = 0 ;
@@ -508,6 +563,115 @@ <h3>Sovereign Trace Protocol</h3>
508563
509564window . addEventListener ( 'resize' , resize ) ;
510565init ( ) ; loop ( ) ;
566+
567+ /* ── TRIPLE TIME DISPLAY ─────────────────── */
568+ ( function ( ) {
569+ // 13 Moon anchor dates (month, day) → moon number and name
570+ const MOONS = [
571+ { num :1 , name :'Magnetic' , m :7 , d :26 } ,
572+ { num :2 , name :'Lunar' , m :8 , d :23 } ,
573+ { num :3 , name :'Electric' , m :9 , d :20 } ,
574+ { num :4 , name :'Self-Existing' , m :10 , d :18 } ,
575+ { num :5 , name :'Overtone' , m :11 , d :15 } ,
576+ { num :6 , name :'Rhythmic' , m :12 , d :13 } ,
577+ { num :7 , name :'Resonant' , m :1 , d :10 } ,
578+ { num :8 , name :'Galactic' , m :2 , d :7 } ,
579+ { num :9 , name :'Solar' , m :3 , d :7 } ,
580+ { num :10 , name :'Planetary' , m :4 , d :4 } ,
581+ { num :11 , name :'Spectral' , m :5 , d :2 } ,
582+ { num :12 , name :'Crystal' , m :5 , d :30 } ,
583+ { num :13 , name :'Cosmic' , m :6 , d :27 }
584+ ] ;
585+
586+ function dreamspell ( date ) {
587+ const year = date . getFullYear ( ) ;
588+ const month = date . getMonth ( ) + 1 ;
589+ const day = date . getDate ( ) ;
590+
591+ // Build sorted list of moon start dates for this Dreamspell year
592+ // The year runs Jul 26 – Jul 24 next year
593+ // Determine which Dreamspell year we're in
594+ const isAfterJul26 = ( month > 7 ) || ( month === 7 && day >= 26 ) ;
595+ const dsYear = isAfterJul26 ? year : year - 1 ;
596+
597+ const anchors = MOONS . map ( m => {
598+ let y = dsYear ;
599+ // Moons 7–13 (Jan–Jul) are in the next calendar year
600+ if ( m . num >= 7 ) y = dsYear + 1 ;
601+ return { ...m , date : new Date ( y , m . m - 1 , m . d ) } ;
602+ } ) ;
603+
604+ // Day Out of Time: Jul 25
605+ const dot = new Date ( dsYear + 1 , 6 , 25 ) ;
606+ const dotMs = dot . getTime ( ) ;
607+ const dateMs = date . getTime ( ) ;
608+ if ( Math . abs ( dateMs - dotMs ) < 86400000 / 2 ) {
609+ return { moonNum : 0 , moonName : 'Day Out of Time' , dayOfMoon : 0 } ;
610+ }
611+
612+ // Find which moon we're in
613+ for ( let i = anchors . length - 1 ; i >= 0 ; i -- ) {
614+ if ( dateMs >= anchors [ i ] . date . getTime ( ) ) {
615+ const dayOfMoon = Math . floor ( ( dateMs - anchors [ i ] . date . getTime ( ) ) / 86400000 ) + 1 ;
616+ if ( dayOfMoon <= 28 ) {
617+ return { moonNum : anchors [ i ] . num , moonName : anchors [ i ] . name , dayOfMoon } ;
618+ }
619+ }
620+ }
621+ return null ;
622+ }
623+
624+ function renderGregorian ( date ) {
625+ const months = [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' , 'August' , 'September' , 'October' , 'November' , 'December' ] ;
626+ const days = [ 'Sunday' , 'Monday' , 'Tuesday' , 'Wednesday' , 'Thursday' , 'Friday' , 'Saturday' ] ;
627+ const el = document . getElementById ( 'tt-gregorian' ) ;
628+ el . classList . remove ( 'loading' ) ;
629+ el . textContent = `${ days [ date . getDay ( ) ] } , ${ months [ date . getMonth ( ) ] } ${ date . getDate ( ) } , ${ date . getFullYear ( ) } ` ;
630+ }
631+
632+ function renderDreamspell ( date ) {
633+ const el = document . getElementById ( 'tt-dreamspell' ) ;
634+ const ds = dreamspell ( date ) ;
635+ el . classList . remove ( 'loading' ) ;
636+ if ( ! ds ) { el . textContent = '—' ; return ; }
637+ if ( ds . moonNum === 0 ) { el . textContent = 'Day Out of Time' ; return ; }
638+ el . textContent = `Day ${ ds . dayOfMoon } , ${ ds . moonName } Moon ${ ds . moonNum } /13` ;
639+ }
640+
641+ async function renderHebrew ( date ) {
642+ const el = document . getElementById ( 'tt-hebrew' ) ;
643+ const d = date . getDate ( ) ;
644+ const m = date . getMonth ( ) + 1 ;
645+ const y = date . getFullYear ( ) ;
646+ try {
647+ const res = await fetch ( `https://www.hebcal.com/converter?gd=${ d } &gm=${ m } &gy=${ y } &g2h=1` ) ;
648+ const text = await res . text ( ) ;
649+ // Parse JSON response
650+ const data = JSON . parse ( text ) ;
651+ if ( data && data . hebrew ) {
652+ el . classList . remove ( 'loading' ) ;
653+ el . textContent = data . hebrew ;
654+ } else {
655+ el . textContent = 'FETCH FAILED' ;
656+ }
657+ } catch ( e ) {
658+ el . classList . remove ( 'loading' ) ;
659+ el . textContent = 'FETCH FAILED' ;
660+ }
661+ }
662+
663+ // Set loading state
664+ [ 'tt-gregorian' , 'tt-dreamspell' , 'tt-hebrew' ] . forEach ( id => {
665+ const el = document . getElementById ( id ) ;
666+ el . classList . add ( 'loading' ) ;
667+ el . textContent = '· · ·' ;
668+ } ) ;
669+
670+ const now = new Date ( ) ;
671+ renderGregorian ( now ) ;
672+ renderDreamspell ( now ) ;
673+ renderHebrew ( now ) ;
674+ } ) ( ) ;
511675</ script >
512676
513677</ body >
0 commit comments