1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+ < head >
4+ < meta charset ="UTF-8 ">
5+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6+ < title > Files Index</ title >
7+ < style >
8+ * {
9+ margin : 0 ;
10+ padding : 0 ;
11+ box-sizing : border-box;
12+ }
13+
14+ body {
15+ font-family : 'Segoe UI' , Tahoma, Geneva, Verdana, sans-serif;
16+ background : linear-gradient (135deg , # 8B4513, # CD853F, # FF8C00 );
17+ color : # 333 ;
18+ min-height : 100vh ;
19+ padding : 20px ;
20+ }
21+
22+ .container {
23+ max-width : 900px ;
24+ margin : 0 auto;
25+ background : white;
26+ border-radius : 15px ;
27+ box-shadow : 0 25px 50px rgba (0 , 0 , 0 , 0.15 );
28+ overflow : hidden;
29+ }
30+
31+ .header {
32+ background : linear-gradient (135deg , # D2691E, # FF8C00, # 8B4513 );
33+ color : white;
34+ padding : 40px ;
35+ text-align : center;
36+ }
37+
38+ .header h1 {
39+ font-size : 2.8em ;
40+ margin-bottom : 10px ;
41+ font-weight : 200 ;
42+ text-shadow : 0 2px 4px rgba (0 , 0 , 0 , 0.3 );
43+ }
44+
45+ .header p {
46+ font-size : 1.2em ;
47+ opacity : 0.9 ;
48+ }
49+
50+ .search-box {
51+ padding : 20px ;
52+ background : linear-gradient (135deg , # FFEFD5, # F5DEB3 );
53+ border-bottom : 1px solid # DEB887 ;
54+ }
55+
56+ .search-input {
57+ width : 100% ;
58+ padding : 12px 20px ;
59+ border : 2px solid # D2691E ;
60+ border-radius : 25px ;
61+ font-size : 16px ;
62+ outline : none;
63+ transition : all 0.3s ease;
64+ background : rgba (255 , 255 , 255 , 0.9 );
65+ }
66+
67+ .search-input : focus {
68+ border-color : # FF8C00 ;
69+ box-shadow : 0 0 0 3px rgba (255 , 140 , 0 , 0.2 );
70+ }
71+
72+ .file-grid {
73+ padding : 30px ;
74+ display : grid;
75+ grid-template-columns : repeat (auto-fit, minmax (300px , 1fr ));
76+ gap : 20px ;
77+ }
78+
79+ .file-card {
80+ background : linear-gradient (135deg , # FFF8DC, # FFEFD5 );
81+ border-radius : 12px ;
82+ padding : 20px ;
83+ text-decoration : none;
84+ color : # 5D4037 ;
85+ transition : all 0.3s ease;
86+ border : 2px solid transparent;
87+ position : relative;
88+ overflow : hidden;
89+ }
90+
91+ .file-card ::before {
92+ content : '' ;
93+ position : absolute;
94+ top : 0 ;
95+ left : 0 ;
96+ right : 0 ;
97+ height : 4px ;
98+ background : linear-gradient (90deg , # D2691E, # FF8C00, # 8B4513 );
99+ }
100+
101+ .file-card : hover {
102+ transform : translateY (-5px );
103+ box-shadow : 0 15px 30px rgba (139 , 69 , 19 , 0.2 );
104+ border-color : # FF8C00 ;
105+ background : linear-gradient (135deg , # FFFAF0, # FFF8DC );
106+ }
107+
108+ .file-header {
109+ display : flex;
110+ align-items : center;
111+ margin-bottom : 15px ;
112+ }
113+
114+ .file-icon {
115+ width : 40px ;
116+ height : 40px ;
117+ background : linear-gradient (135deg , # D2691E, # FF8C00 );
118+ border-radius : 8px ;
119+ display : flex;
120+ align-items : center;
121+ justify-content : center;
122+ color : white;
123+ font-weight : bold;
124+ font-size : 16px ;
125+ margin-right : 15px ;
126+ box-shadow : 0 3px 10px rgba (139 , 69 , 19 , 0.3 );
127+ }
128+
129+ .file-name {
130+ font-size : 1.3em ;
131+ font-weight : 600 ;
132+ color : # 8B4513 ;
133+ }
134+
135+ .file-info {
136+ color : # A0522D ;
137+ font-size : 0.9em ;
138+ line-height : 1.5 ;
139+ }
140+
141+ .no-files {
142+ text-align : center;
143+ padding : 60px ;
144+ color : # 8B4513 ;
145+ font-size : 1.1em ;
146+ }
147+
148+ .stats {
149+ background : linear-gradient (135deg , # F4A460, # DEB887 );
150+ padding : 20px ;
151+ text-align : center;
152+ color : # 8B4513 ;
153+ border-top : 1px solid # D2B48C ;
154+ font-weight : 500 ;
155+ }
156+
157+ @media (max-width : 600px ) {
158+ .file-grid {
159+ grid-template-columns : 1fr ;
160+ }
161+
162+ .header h1 {
163+ font-size : 2.2em ;
164+ }
165+ }
166+ </ style >
167+ </ head >
168+ < body >
169+ < div class ="container ">
170+ < div class ="header ">
171+ < h1 > 🌐 OCANNL Directory</ h1 >
172+ < p > Slides, articles, and documentation</ p >
173+ </ div >
174+
175+ < div class ="search-box ">
176+ < input type ="text " class ="search-input " id ="searchInput " placeholder ="🔍 Search HTML files... ">
177+ </ div >
178+
179+ < div class ="file-grid " id ="fileGrid ">
180+ <!-- Files will be populated by JavaScript -->
181+ </ div >
182+
183+ < div class ="stats " id ="stats ">
184+ Scanning directory...
185+ </ div >
186+ </ div >
187+
188+ < script >
189+ // Configuration: Add your HTML files here
190+ const htmlFiles = [
191+ {
192+ name : 'basics_backprop_training_codegen.html' ,
193+ title : 'Introduction to OCANNL' ,
194+ description : 'Introduction to OCANNL: Supervised Learning, backpropagation, training loop, code generation'
195+ } ,
196+ {
197+ name : 'RL-REINFORCE.html' ,
198+ title : 'Introduction to Reinforcement Learning' ,
199+ description : 'Introduction to Reinforcement Learning, the REINFORCE and GRPO algorithms'
200+ } ,
201+ {
202+ name : '../../dev/neural_nets_lib/Ocannl/index.html' ,
203+ title : 'OCANNL Frontend API Documentation' ,
204+ description : 'OCANNL Frontend API Documentation: Train, Tensor, Operation, Nn_blocks'
205+ } ,
206+ ] ;
207+
208+ let filteredFiles = htmlFiles ;
209+
210+ function getFileIcon ( filename ) {
211+ const name = filename . toLowerCase ( ) ;
212+ if ( name . includes ( 'home' ) || name . includes ( 'index' ) ) return '🏠' ;
213+ if ( name . includes ( 'about' ) ) return '👥' ;
214+ if ( name . includes ( 'contact' ) ) return '📞' ;
215+ if ( name . includes ( 'blog' ) ) return '📝' ;
216+ if ( name . includes ( 'portfolio' ) || name . includes ( 'gallery' ) ) return '🎨' ;
217+ if ( name . includes ( 'service' ) ) return '⚙️' ;
218+ if ( name . includes ( 'introduction' ) || name . includes ( 'basics' ) ) return '🚀' ;
219+ if ( name . includes ( 'rl-' ) ) return '🧠' ;
220+ return '📄' ;
221+ }
222+
223+ function renderFiles ( files ) {
224+ const fileGrid = document . getElementById ( 'fileGrid' ) ;
225+
226+ if ( files . length === 0 ) {
227+ fileGrid . innerHTML = `
228+ <div class="no-files">
229+ <h3>No files found</h3>
230+ <p>Try adjusting your search criteria</p>
231+ </div>
232+ ` ;
233+ return ;
234+ }
235+
236+ fileGrid . innerHTML = files . map ( file => `
237+ <a href="${ file . name } " class="file-card">
238+ <div class="file-header">
239+ <div class="file-icon">${ getFileIcon ( file . name ) } </div>
240+ <div class="file-name">${ file . title } </div>
241+ </div>
242+ <div class="file-info">
243+ ${ file . description }
244+ </div>
245+ </a>
246+ ` ) . join ( '' ) ;
247+ }
248+
249+ function updateStats ( ) {
250+ const stats = document . getElementById ( 'stats' ) ;
251+ stats . textContent = `Generated on ${ new Date ( ) . toLocaleDateString ( ) } • ${ filteredFiles . length } file(s) found` ;
252+ }
253+
254+ function searchFiles ( query ) {
255+ const lowercaseQuery = query . toLowerCase ( ) ;
256+ filteredFiles = htmlFiles . filter ( file =>
257+ file . name . toLowerCase ( ) . includes ( lowercaseQuery ) ||
258+ file . title . toLowerCase ( ) . includes ( lowercaseQuery ) ||
259+ file . description . toLowerCase ( ) . includes ( lowercaseQuery )
260+ ) ;
261+ renderFiles ( filteredFiles ) ;
262+ updateStats ( ) ;
263+ }
264+
265+ // Initialize
266+ document . addEventListener ( 'DOMContentLoaded' , function ( ) {
267+ renderFiles ( htmlFiles ) ;
268+ updateStats ( ) ;
269+
270+ // Search functionality
271+ const searchInput = document . getElementById ( 'searchInput' ) ;
272+ searchInput . addEventListener ( 'input' , function ( e ) {
273+ searchFiles ( e . target . value ) ;
274+ } ) ;
275+ } ) ;
276+ </ script >
277+ </ body >
278+ </ html >
0 commit comments