38be2f43f1
Introduce a persistent left sidebar, update navigation to support regions, and convert the UI to a flat/no-blur visual style. Key changes: - index.html: add a persistent sidebar markup with nav items, user area and main app layout. - src/core/nav.js: improve candidate scoring to use element bounding centers and overlap penalty; include extra focus roots; add region metadata handling, helpers for resolving default content/sidebar indices, and special-case movements between sidebar and content; respect contract.useNebulaNavigation flag. - src/main.js: manage sidebar visibility for full-screen flows (lock/onboarding), update sidebar active state on view changes, include sidebar as an extraFocusRoot when appropriate, and handle sidebar item activation on accept to navigate views. - src/styles/*: major visual/theme updates to remove blur/glow effects (Zero-Blur policy), add flat sidebar styles, update components to solid borders and simpler focus styling, adjust theme variables (palette, spacing, durations), and redesign the home view layout and controls. Rationale: provide a persistent, keyboard/controller-friendly sidebar for quick navigation while simplifying visuals to a flat, performance-friendly theme and refining focus/navigation behavior across sidebar and content regions.
533 lines
11 KiB
CSS
533 lines
11 KiB
CSS
/* ════════════════════════════════════════════════════════
|
|
HOME VIEW — Sci-fi dashboard layout
|
|
════════════════════════════════════════════════════════ */
|
|
|
|
.home-view {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
padding: 0;
|
|
gap: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ── Top status bar ──────────────────────────────────── */
|
|
.home-topbar {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 16px 24px 12px;
|
|
flex-shrink: 0;
|
|
border-bottom: 1px solid var(--nebula-color-border);
|
|
}
|
|
|
|
.home-time {
|
|
font-size: clamp(36px, 4vw, 52px);
|
|
font-weight: 800;
|
|
letter-spacing: -0.03em;
|
|
color: var(--nebula-color-text);
|
|
line-height: 1;
|
|
}
|
|
|
|
.home-status-icons {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 14px;
|
|
color: var(--nebula-color-muted);
|
|
}
|
|
|
|
.home-status-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
/* ── Body: two columns ────────────────────────────────── */
|
|
.home-body {
|
|
flex: 1;
|
|
display: grid;
|
|
grid-template-columns: 1fr 310px;
|
|
gap: 16px;
|
|
padding: 14px 20px 0;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ── Center column ───────────────────────────────────── */
|
|
.home-center {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ── Category tabs ───────────────────────────────────── */
|
|
.home-tabs {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 20px;
|
|
flex-shrink: 0;
|
|
border-bottom: 1px solid var(--nebula-color-border);
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
.home-tab {
|
|
background: none;
|
|
color: var(--nebula-color-muted);
|
|
font-size: 16px;
|
|
font-weight: 700;
|
|
padding: 0 2px 8px;
|
|
border: none;
|
|
border-bottom: 2px solid transparent;
|
|
border-radius: 0;
|
|
cursor: pointer;
|
|
transition:
|
|
color var(--nebula-duration-fast) var(--nebula-ease-standard),
|
|
border-bottom-color var(--nebula-duration-fast) var(--nebula-ease-standard);
|
|
transform: none;
|
|
}
|
|
|
|
.home-tab.is-active {
|
|
color: var(--nebula-color-text);
|
|
border-bottom-color: var(--nebula-color-accent);
|
|
}
|
|
|
|
.home-tab.is-focused {
|
|
color: var(--nebula-color-accent);
|
|
border-bottom-color: var(--nebula-color-accent);
|
|
transform: none;
|
|
border-radius: 0;
|
|
}
|
|
|
|
.tab-hint {
|
|
margin-left: auto;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: 13px;
|
|
color: var(--nebula-color-muted);
|
|
}
|
|
|
|
/* ── Hero card ───────────────────────────────────────── */
|
|
.hero-card {
|
|
flex: 1;
|
|
position: relative;
|
|
border-radius: var(--nebula-radius-lg);
|
|
overflow: hidden;
|
|
min-height: 0;
|
|
border: 2px solid var(--nebula-color-border);
|
|
transition: border-color var(--nebula-duration-nav) var(--nebula-ease-console);
|
|
transform: none;
|
|
}
|
|
|
|
.hero-card.is-focused {
|
|
border-color: var(--nebula-color-accent);
|
|
transform: none;
|
|
}
|
|
|
|
/* Game art layers */
|
|
.hero-art {
|
|
position: absolute;
|
|
inset: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.hero-art-bg {
|
|
position: absolute;
|
|
inset: 0;
|
|
background:
|
|
linear-gradient(165deg,
|
|
#0d0e00 0%,
|
|
#1a1600 20%,
|
|
#2a2200 40%,
|
|
#3a3000 60%,
|
|
rgba(180, 150, 0, 0.25) 80%,
|
|
rgba(220, 180, 0, 0.15) 100%
|
|
);
|
|
}
|
|
|
|
.hero-art-mid {
|
|
position: absolute;
|
|
inset: 0;
|
|
background:
|
|
radial-gradient(ellipse at 65% 50%, rgba(255, 200, 0, 0.18) 0%, transparent 55%),
|
|
radial-gradient(ellipse at 30% 80%, rgba(0, 80, 180, 0.2) 0%, transparent 45%);
|
|
}
|
|
|
|
/* Stylised "character" area */
|
|
.hero-art-character {
|
|
position: absolute;
|
|
bottom: 0;
|
|
right: 10%;
|
|
width: 42%;
|
|
height: 90%;
|
|
background:
|
|
linear-gradient(180deg,
|
|
transparent 0%,
|
|
rgba(60, 50, 0, 0.4) 30%,
|
|
rgba(100, 90, 0, 0.6) 60%,
|
|
rgba(30, 25, 0, 0.9) 100%
|
|
);
|
|
clip-path: polygon(15% 0%, 85% 0%, 100% 100%, 0% 100%);
|
|
}
|
|
|
|
.hero-title-watermark {
|
|
position: absolute;
|
|
bottom: 110px;
|
|
right: 5%;
|
|
font-size: clamp(32px, 5vw, 64px);
|
|
font-weight: 900;
|
|
color: rgba(255, 220, 0, 0.85);
|
|
letter-spacing: -0.03em;
|
|
line-height: 0.95;
|
|
text-align: right;
|
|
text-transform: uppercase;
|
|
pointer-events: none;
|
|
font-style: italic;
|
|
}
|
|
|
|
/* Controller overlay */
|
|
.hero-ctrl-overlay {
|
|
position: absolute;
|
|
top: 20px;
|
|
left: 20px;
|
|
display: flex;
|
|
gap: 14px;
|
|
align-items: center;
|
|
opacity: 0.55;
|
|
}
|
|
|
|
.ctrl-glyph {
|
|
display: block;
|
|
}
|
|
|
|
.hero-l-badge {
|
|
width: 22px;
|
|
height: 22px;
|
|
border-radius: var(--nebula-radius-sm);
|
|
background: rgba(255, 255, 255, 0.15);
|
|
border: 1px solid rgba(255, 255, 255, 0.25);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 11px;
|
|
font-weight: 800;
|
|
color: rgba(255, 255, 255, 0.7);
|
|
}
|
|
|
|
/* Gradient overlay + info */
|
|
.hero-overlay {
|
|
position: absolute;
|
|
inset: 0;
|
|
background: linear-gradient(
|
|
to top,
|
|
rgba(7, 10, 20, 0.98) 0%,
|
|
rgba(7, 10, 20, 0.7) 36%,
|
|
transparent 65%
|
|
);
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: flex-end;
|
|
padding: 20px 24px;
|
|
}
|
|
|
|
.hero-info {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 14px;
|
|
}
|
|
|
|
.hero-game-title {
|
|
margin: 0;
|
|
font-size: clamp(26px, 3.2vw, 42px);
|
|
font-weight: 800;
|
|
letter-spacing: -0.02em;
|
|
color: #fff;
|
|
line-height: 1.1;
|
|
}
|
|
|
|
.hero-actions {
|
|
display: flex;
|
|
gap: 10px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.hero-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 9px 18px;
|
|
border-radius: var(--nebula-radius-sm);
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
cursor: pointer;
|
|
background: rgba(255, 255, 255, 0.08);
|
|
border: 1.5px solid rgba(255, 255, 255, 0.2);
|
|
color: #fff;
|
|
transition:
|
|
background var(--nebula-duration-fast) var(--nebula-ease-standard),
|
|
border-color var(--nebula-duration-fast) var(--nebula-ease-standard),
|
|
transform var(--nebula-duration-fast) var(--nebula-ease-console);
|
|
transform: none;
|
|
}
|
|
|
|
.hero-btn-primary {
|
|
background: var(--nebula-color-accent);
|
|
border-color: transparent;
|
|
color: #070a14;
|
|
}
|
|
|
|
.hero-btn.is-focused {
|
|
border-color: var(--nebula-color-accent);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.hero-btn-primary.is-focused {
|
|
border-color: #fff;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.hero-dots {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.hero-dot {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: rgba(255, 255, 255, 0.28);
|
|
transition: all var(--nebula-duration-fast) var(--nebula-ease-standard);
|
|
}
|
|
|
|
.hero-dot.is-active {
|
|
width: 22px;
|
|
border-radius: 3px;
|
|
background: var(--nebula-color-accent);
|
|
}
|
|
|
|
/* ── Featured strip ──────────────────────────────────── */
|
|
.featured-strip {
|
|
flex-shrink: 0;
|
|
padding-bottom: 12px;
|
|
}
|
|
|
|
.section-label {
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.12em;
|
|
color: var(--nebula-color-muted);
|
|
margin: 0 0 10px;
|
|
}
|
|
|
|
.featured-row {
|
|
display: flex;
|
|
gap: 10px;
|
|
}
|
|
|
|
.featured-thumb {
|
|
flex: 1;
|
|
height: 68px;
|
|
border-radius: var(--nebula-radius-md);
|
|
background: linear-gradient(135deg, var(--thumb-a, #1a1a2e), var(--thumb-b, #2a1050));
|
|
border: 2px solid var(--nebula-color-border);
|
|
cursor: pointer;
|
|
transition: border-color var(--nebula-duration-fast);
|
|
overflow: hidden;
|
|
padding: 0;
|
|
}
|
|
|
|
.featured-thumb.is-focused {
|
|
border-color: var(--nebula-color-accent);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
/* ── Right panel ─────────────────────────────────────── */
|
|
.home-right-panel {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
overflow: hidden;
|
|
min-height: 0;
|
|
padding-bottom: 12px;
|
|
}
|
|
|
|
.panel-header-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.panel-heading {
|
|
font-size: 15px;
|
|
font-weight: 700;
|
|
color: var(--nebula-color-text);
|
|
margin: 0;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.06em;
|
|
}
|
|
|
|
.panel-heading-sm {
|
|
font-size: 13px;
|
|
font-weight: 700;
|
|
color: var(--nebula-color-text);
|
|
margin: 0 0 8px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.06em;
|
|
}
|
|
|
|
/* ── Quick launch grid ───────────────────────────────── */
|
|
.quick-launch {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.quick-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 8px;
|
|
}
|
|
|
|
.quick-tile {
|
|
position: relative;
|
|
border-radius: var(--nebula-radius-md);
|
|
overflow: hidden;
|
|
background: var(--nebula-color-panel);
|
|
border: 2px solid var(--nebula-color-border);
|
|
cursor: pointer;
|
|
padding: 0;
|
|
text-align: left;
|
|
color: var(--nebula-color-text);
|
|
transition:
|
|
border-color var(--nebula-duration-fast) var(--nebula-ease-console),
|
|
transform var(--nebula-duration-fast) var(--nebula-ease-console);
|
|
transform: translateZ(0);
|
|
}
|
|
|
|
.quick-tile.is-focused {
|
|
border-color: var(--nebula-color-accent);
|
|
transform: scale(1.04) translateZ(0);
|
|
}
|
|
|
|
.quick-tile-art {
|
|
height: 70px;
|
|
background: linear-gradient(135deg, var(--ta, #1a1a2e), var(--tb, #2a2050));
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.tile-badge {
|
|
position: absolute;
|
|
bottom: 4px;
|
|
right: 4px;
|
|
font-size: 12px;
|
|
line-height: 1;
|
|
}
|
|
|
|
.quick-tile-footer {
|
|
padding: 6px 8px 7px;
|
|
}
|
|
|
|
.quick-tile-name {
|
|
margin: 0;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
color: var(--nebula-color-text);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
.quick-tile-meta {
|
|
margin: 3px 0 0;
|
|
font-size: 10px;
|
|
color: var(--nebula-color-muted);
|
|
line-height: 1.3;
|
|
}
|
|
|
|
/* Solid progress bar */
|
|
.quick-tile-bar {
|
|
position: relative;
|
|
padding-left: 0;
|
|
}
|
|
|
|
.quick-tile-bar::before {
|
|
content: "";
|
|
display: block;
|
|
height: 2px;
|
|
background: var(--nebula-color-border);
|
|
border-radius: 1px;
|
|
margin-bottom: 3px;
|
|
}
|
|
|
|
.quick-tile-bar::after {
|
|
content: "";
|
|
display: block;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: var(--pct, 0%);
|
|
height: 2px;
|
|
background: var(--nebula-color-accent);
|
|
border-radius: 1px;
|
|
}
|
|
|
|
/* ── Bottom side panels ──────────────────────────────── */
|
|
.side-bottom-panels {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 10px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.friends-panel,
|
|
.activity-panel {
|
|
background: var(--nebula-color-panel);
|
|
border: 1px solid var(--nebula-color-border);
|
|
border-radius: var(--nebula-radius-md);
|
|
padding: 12px;
|
|
}
|
|
|
|
.friends-avatars {
|
|
display: flex;
|
|
gap: 6px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.friend-avatar {
|
|
width: 28px;
|
|
height: 28px;
|
|
border-radius: 50%;
|
|
background: var(--fc, var(--nebula-color-accent));
|
|
opacity: 0.85;
|
|
border: 1.5px solid rgba(255, 255, 255, 0.12);
|
|
}
|
|
|
|
.activity-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.activity-label {
|
|
font-size: 17px;
|
|
font-weight: 800;
|
|
color: var(--nebula-color-text);
|
|
line-height: 1;
|
|
}
|
|
|
|
.activity-hint {
|
|
margin: 0;
|
|
font-size: 11px;
|
|
color: var(--nebula-color-muted);
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|