File size: 3,652 Bytes
cdf1899
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import dash
from dash import html
import dash_bootstrap_components as dbc

# Initialize the App
app = dash.Dash(
    __name__,
    use_pages=True,
    external_stylesheets=[dbc.themes.DARKLY, dbc.icons.BOOTSTRAP],
    external_scripts=[
        "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"
    ],
    suppress_callback_exceptions=True
)

server = app.server

# Fixed Sidebar with Nebula Icon
sidebar = html.Div([
    html.Div([
        # Nebula Icon with Gradient and Glow
        html.Div([
            html.I(className="bi bi-hurricane fs-2", style={"color": "#00d2ff"})
        ], style={
            "width": "45px", "height": "45px", 
            "display": "flex", "alignItems": "center", "justifyContent": "center",
            "background": "rgba(255,255,255,0.05)", 
            "borderRadius": "12px",
            "boxShadow": "0 0 20px rgba(0, 210, 255, 0.3)",
            "border": "1px solid rgba(0, 210, 255, 0.2)"
        }, className="nebula-icon-spin"),
        
        html.H3("ASTRO.AI", className="ms-3 mb-0 fw-bold text-white", style={"letterSpacing": "2px"}),
    ], className="d-flex align-items-center mb-5"),
    
    dbc.Nav([
        dbc.NavLink([html.I(className="bi bi-stars me-3"), "Introduction"], href="/", active="exact", className="mb-2 nav-link-custom"),
        dbc.NavLink([html.I(className="bi bi-eye me-3"), "Redshift Phenomenon"], href="/phenomenon", active="exact", className="mb-2 nav-link-custom"),
        dbc.NavLink([html.I(className="bi bi-activity me-3"), "Spectroscopy"], href="/spectroscopy", active="exact", className="mb-2 nav-link-custom"),
        dbc.NavLink([html.I(className="bi bi-camera me-3"), "Photometry"], href="/photometry", active="exact", className="mb-2 nav-link-custom"),       
        dbc.NavLink([html.I(className="bi bi-database me-3"), "Project Data"], href="/data", active="exact", className="mb-2 nav-link-custom"),
        dbc.NavLink([html.I(className="bi bi-graph-up-arrow me-3"), "Data Analysis"], href="/analysis", active="exact", className="mb-2 nav-link-custom"),
        dbc.NavLink([html.I(className="bi bi-cpu-fill me-3"), "Redshift Engine"], href="/prediction", active="exact", className="mb-2 nav-link-custom"),
    ], vertical=True, pills=True),
], className="sidebar-container")

# Professional Styled Copyright Footer Component
footer = html.Footer(
    dbc.Container(
        dbc.Row([
            dbc.Col(
                html.Hr(style={"borderTop": "1px solid rgba(255, 255, 255, 0.1)", "marginBottom": "20px"}),
                width=12
            ),
            dbc.Col(
                html.P(
                    [
                        html.Span("© 2026 ", className="text-muted"),
                        html.Span("Latreche Sara", className="text-info fw-bold", style={"letterSpacing": "1px"}),
                        html.Span(" | All Space-Time Coordinates Reserved.", className="text-muted ms-1")
                    ], 
                    className="small text-center mb-0 pb-3"
                ),
                width=12
            )
        ]),
        fluid=True,
    ),
    style={"marginTop": "auto"} # Automatically pushes footer down if content is short
)

# Main Layout
app.layout = html.Div([
    html.Div(className="bg-glow"), 
    sidebar,
    
    # Content wrapper converted to flex-column to manage page-bottom pinning smoothly
    html.Div([
        dash.page_container,
        footer
    ], className="content-container d-flex flex-column", style={"minHeight": "100vh"})
])

if __name__ == "__main__":
    app.run(debug=True)