1+ <!DOCTYPE html>
2+ < html >
3+
4+ < head >
5+ < title > Papyrus API Documentation</ title >
6+ < meta charset ="utf-8 " />
7+ < meta name ="viewport " content ="width=device-width, initial-scale=1 ">
8+ < link href ="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;700&family=JetBrains+Mono&display=swap "
9+ rel ="stylesheet ">
10+ < link rel ="stylesheet " href ="https://fonts.googleapis.com/icon?family=Material+Icons ">
11+ < style >
12+ : root {
13+ --primary-color : # 673ab7 ;
14+ --bg-color : # ffffff ;
15+ --text-color : # 333333 ;
16+ --sidebar-bg : # fafafa ;
17+ --right-panel-bg : # 263238 ;
18+ }
19+
20+ [data-theme = "dark" ] {
21+ --bg-color : # 1a1a1a ;
22+ --text-color : # e0e0e0 ;
23+ --sidebar-bg : # 252525 ;
24+ --right-panel-bg : # 1e1e1e ;
25+ }
26+
27+ * {
28+ box-sizing : border-box;
29+ }
30+
31+ body {
32+ margin : 0 ;
33+ padding : 0 ;
34+ background-color : var (--bg-color );
35+ transition : background-color 0.3s ease;
36+ }
37+
38+ .toolbar {
39+ position : fixed;
40+ top : 0 ;
41+ left : 0 ;
42+ right : 0 ;
43+ height : 48px ;
44+ background : var (--primary-color );
45+ display : flex;
46+ align-items : center;
47+ justify-content : space-between;
48+ padding : 0 16px ;
49+ z-index : 1000 ;
50+ box-shadow : 0 2px 4px rgba (0 , 0 , 0 , 0.1 );
51+ }
52+
53+ .toolbar-title {
54+ color : white;
55+ font-family : 'Inter' , sans-serif;
56+ font-size : 18px ;
57+ font-weight : 500 ;
58+ display : flex;
59+ align-items : center;
60+ gap : 8px ;
61+ }
62+
63+ .toolbar-title a {
64+ color : white;
65+ text-decoration : none;
66+ }
67+
68+ .toolbar-actions {
69+ display : flex;
70+ gap : 8px ;
71+ }
72+
73+ .theme-toggle {
74+ background : rgba (255 , 255 , 255 , 0.15 );
75+ border : none;
76+ color : white;
77+ padding : 8px 16px ;
78+ border-radius : 4px ;
79+ cursor : pointer;
80+ font-family : 'Inter' , sans-serif;
81+ font-size : 14px ;
82+ display : flex;
83+ align-items : center;
84+ gap : 6px ;
85+ transition : background 0.2s ;
86+ }
87+
88+ .theme-toggle : hover {
89+ background : rgba (255 , 255 , 255 , 0.25 );
90+ }
91+
92+ .back-link {
93+ background : rgba (255 , 255 , 255 , 0.15 );
94+ border : none;
95+ color : white;
96+ padding : 8px 16px ;
97+ border-radius : 4px ;
98+ cursor : pointer;
99+ font-family : 'Inter' , sans-serif;
100+ font-size : 14px ;
101+ text-decoration : none;
102+ display : flex;
103+ align-items : center;
104+ gap : 6px ;
105+ transition : background 0.2s ;
106+ }
107+
108+ .back-link : hover {
109+ background : rgba (255 , 255 , 255 , 0.25 );
110+ }
111+
112+ .redoc-container {
113+ padding-top : 48px ;
114+ }
115+
116+ /* Dark mode overrides for Redoc */
117+ [data-theme = "dark" ] .api-content {
118+ background-color : var (--bg-color );
119+ }
120+ </ style >
121+ </ head >
122+
123+ < body >
124+ < div class ="toolbar ">
125+ < div class ="toolbar-title ">
126+ < span > 📚</ span >
127+ < a href ="./ "> Papyrus API</ a >
128+ </ div >
129+ < div class ="toolbar-actions ">
130+ < button class ="theme-toggle " onclick ="toggleTheme() " title ="Toggle dark/light mode ">
131+ < span class ="material-icons " style ="font-size: 18px; "> dark_mode</ span >
132+ < span id ="theme-label "> Dark</ span >
133+ </ button >
134+ < a href ="./ " class ="back-link ">
135+ < span class ="material-icons " style ="font-size: 18px; "> arrow_back</ span >
136+ Back to Docs
137+ </ a >
138+ </ div >
139+ </ div >
140+
141+ < div class ="redoc-container " id ="redoc-container "> </ div >
142+
143+ < script src ="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js "> </ script >
144+ < script >
145+ const lightTheme = {
146+ colors : {
147+ primary : { main : '#673ab7' } ,
148+ text : { primary : '#333333' } ,
149+ http : {
150+ get : '#4caf50' ,
151+ post : '#2196f3' ,
152+ put : '#ff9800' ,
153+ delete : '#f44336' ,
154+ patch : '#9c27b0'
155+ }
156+ } ,
157+ typography : {
158+ fontFamily : 'Inter, sans-serif' ,
159+ headings : { fontFamily : 'Inter, sans-serif' } ,
160+ code : { fontFamily : 'JetBrains Mono, monospace' }
161+ } ,
162+ sidebar : {
163+ backgroundColor : '#fafafa' ,
164+ textColor : '#333333'
165+ } ,
166+ rightPanel : {
167+ backgroundColor : '#263238'
168+ }
169+ } ;
170+
171+ const darkTheme = {
172+ colors : {
173+ primary : { main : '#9575cd' } ,
174+ text : { primary : '#e0e0e0' } ,
175+ http : {
176+ get : '#66bb6a' ,
177+ post : '#42a5f5' ,
178+ put : '#ffb74d' ,
179+ delete : '#ef5350' ,
180+ patch : '#ab47bc'
181+ }
182+ } ,
183+ typography : {
184+ fontFamily : 'Inter, sans-serif' ,
185+ headings : { fontFamily : 'Inter, sans-serif' } ,
186+ code : { fontFamily : 'JetBrains Mono, monospace' }
187+ } ,
188+ sidebar : {
189+ backgroundColor : '#252525' ,
190+ textColor : '#e0e0e0'
191+ } ,
192+ rightPanel : {
193+ backgroundColor : '#1e1e1e'
194+ }
195+ } ;
196+
197+ function getPreferredTheme ( ) {
198+ const saved = localStorage . getItem ( 'redoc-theme' ) ;
199+ if ( saved ) return saved ;
200+ return window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ? 'dark' : 'light' ;
201+ }
202+
203+ function renderRedoc ( theme ) {
204+ const container = document . getElementById ( 'redoc-container' ) ;
205+ container . innerHTML = '' ;
206+ Redoc . init ( './openapi.yaml' , {
207+ theme : theme === 'dark' ? darkTheme : lightTheme ,
208+ hideDownloadButton : false ,
209+ expandResponses : '200,201' ,
210+ pathInMiddlePanel : true ,
211+ scrollYOffset : 48
212+ } , container ) ;
213+ }
214+
215+ function updateThemeUI ( theme ) {
216+ document . body . setAttribute ( 'data-theme' , theme ) ;
217+ const label = document . getElementById ( 'theme-label' ) ;
218+ const icon = document . querySelector ( '.theme-toggle .material-icons' ) ;
219+ if ( theme === 'dark' ) {
220+ label . textContent = 'Light' ;
221+ icon . textContent = 'light_mode' ;
222+ } else {
223+ label . textContent = 'Dark' ;
224+ icon . textContent = 'dark_mode' ;
225+ }
226+ }
227+
228+ function toggleTheme ( ) {
229+ const current = document . body . getAttribute ( 'data-theme' ) || 'light' ;
230+ const next = current === 'dark' ? 'light' : 'dark' ;
231+ localStorage . setItem ( 'redoc-theme' , next ) ;
232+ updateThemeUI ( next ) ;
233+ renderRedoc ( next ) ;
234+ }
235+
236+ // Initialize
237+ const initialTheme = getPreferredTheme ( ) ;
238+ updateThemeUI ( initialTheme ) ;
239+ renderRedoc ( initialTheme ) ;
240+ </ script >
241+ </ body >
242+
243+ </ html >
0 commit comments