frontend: polish app launch and release experience

This commit is contained in:
archipelago
2026-06-11 00:24:40 -04:00
parent c393b96da3
commit 1a3d726eac
140 changed files with 5930 additions and 920 deletions
+210 -19
View File
@@ -80,6 +80,50 @@ select:focus-visible {
border-color: rgba(251, 146, 60, 0.4);
}
/* Card action placement: keep compact header buttons for genuinely wide layouts. */
.responsive-card-actions-top,
.web5-card-actions-top {
display: none;
}
.responsive-card-actions-bottom,
.web5-card-actions-bottom {
display: flex;
}
.responsive-card-actions-bottom-grid,
.web5-card-actions-bottom-grid {
display: grid;
}
.mobile-card-action {
display: inline-flex;
width: 100%;
min-width: 0;
min-height: 44px;
aspect-ratio: auto;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.625rem 1rem;
text-align: center;
white-space: nowrap;
}
@media (min-width: 1800px) {
.responsive-card-actions-top,
.web5-card-actions-top {
display: flex;
}
.responsive-card-actions-bottom,
.responsive-card-actions-bottom-grid,
.web5-card-actions-bottom,
.web5-card-actions-bottom-grid {
display: none;
}
}
/* Mobile touch targets — ensure tappable elements meet 44px minimum */
@media (max-width: 767px) {
button:not(.mode-switcher-btn):not(.sidebar-nav-item):not([class*="w-9"]):not([class*="w-8"]):not([class*="w-7"]):not([class*="w-10"]):not([class*="w-11"]):not([class*="w-12"]) {
@@ -140,7 +184,7 @@ input[type="radio"]:active + * {
[data-controller-container]:focus-visible,
[data-controller-container]:focus {
outline: none;
transform: translateY(-4px) scale(1.01) translateZ(0);
transform: translateY(-4px) scale(1.01);
box-shadow:
0 0 6px 2px rgba(251, 146, 60, 0.35),
0 0 20px rgba(251, 146, 60, 0.15),
@@ -178,16 +222,18 @@ input[type="radio"]:active + * {
border-radius: 1rem;
overflow-x: hidden;
overflow-y: visible;
/* Fix Chromium compositor bug: backdrop-filter + fixed animated overlays
causes cards to render as black rectangles on scroll/tab-switch.
Own layer + isolation prevents stacking context confusion. */
transform: translateZ(0);
isolation: isolate;
}
/* The Apps grid has many backdrop-filter cards inside an animated dashboard
viewport. Chromium/Brave can corrupt those layers into black rectangles,
so keep the translucency but avoid per-card backdrop compositor layers. */
/* Dashboard content lives inside animated perspective/scroll containers.
Chromium/Brave can corrupt backdrop-filter + transformed cards into black
square/rectangle layers, so use translucent fills there instead. */
body.dashboard-active .dashboard-scroll-panel .glass-card,
body.dashboard-active .dashboard-scroll-panel .glass,
body.dashboard-active .dashboard-scroll-panel .mode-switcher,
body.dashboard-active .dashboard-scroll-panel .glass-button,
body.dashboard-active .dashboard-scroll-panel input,
body.dashboard-active .dashboard-scroll-panel textarea,
body.dashboard-active .dashboard-scroll-panel select,
.apps-view .glass-card,
.apps-view .glass,
.apps-view .mode-switcher,
@@ -209,6 +255,84 @@ input[type="radio"]:active + * {
border: 1px solid rgba(255, 255, 255, 0.08);
}
.segmented-select {
display: inline-flex;
gap: 2px;
padding: 3px;
border-radius: 0.5rem;
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.08);
max-width: min(260px, 24vw);
}
.segmented-select-with-discover {
max-width: min(360px, 34vw);
}
.category-tabs-wide {
flex: 0 1 auto;
min-width: 0;
width: max-content;
max-width: 100%;
overflow: visible;
}
.category-tabs-wide .mode-switcher-btn {
flex: 0 0 auto;
}
.category-tabs-probe {
position: absolute;
left: -10000px;
top: -10000px;
visibility: hidden;
pointer-events: none;
width: max-content;
max-width: none;
}
.app-header-search,
.app-header-search-wrap {
flex: 1 1 auto;
min-width: 9rem;
max-width: none;
}
.segmented-select .mode-switcher-btn {
flex: 0 0 auto;
}
.segmented-select-control {
width: clamp(132px, 18vw, 220px);
appearance: none;
-webkit-appearance: none;
background:
linear-gradient(45deg, transparent 50%, rgba(255, 255, 255, 0.68) 50%) right 12px center / 6px 6px no-repeat,
linear-gradient(135deg, rgba(255, 255, 255, 0.68) 50%, transparent 50%) right 8px center / 6px 6px no-repeat,
transparent;
border: 1px solid transparent;
border-radius: 0.375rem;
color: rgba(255, 255, 255, 0.95);
cursor: pointer;
font-size: 0.75rem;
font-weight: 500;
padding-right: 1.75rem;
padding: 0.375rem 1.75rem 0.375rem 0.75rem;
text-align: left;
white-space: nowrap;
}
.segmented-select-control:focus {
outline: none;
border-color: rgba(251, 146, 60, 0.35);
background-color: rgba(251, 146, 60, 0.12);
}
.segmented-select-control option {
background: #111827;
color: #fff;
}
/* Full-width mode switcher variant (sidebar, mobile settings) */
.mode-switcher-full {
display: flex;
@@ -1305,6 +1429,32 @@ html:has(body.video-background-active)::before {
display: none !important;
}
/* Full-screen modal overlays should freeze the page underneath, including
custom Teleport modals that do not go through BaseModal. */
html:has(body .fixed.inset-0:not(.pointer-events-none)),
body:has(.fixed.inset-0:not(.pointer-events-none)) {
overflow: hidden;
}
html.modal-scroll-locked .fixed.inset-0 {
overscroll-behavior: contain;
touch-action: none;
}
html.modal-scroll-locked .fixed.inset-0 .overflow-y-auto,
html.modal-scroll-locked .fixed.inset-0 .overflow-auto,
html.modal-scroll-locked .fixed.inset-0 [style*="overflow-y: auto"],
html.modal-scroll-locked .fixed.inset-0 [style*="overflow: auto"] {
overscroll-behavior: contain;
touch-action: pan-y;
}
html.modal-scroll-locked .dashboard-scroll-panel {
overflow: hidden !important;
overscroll-behavior: none;
touch-action: none;
}
/* Repeating glitch animations - every 5 seconds (subtle) */
@keyframes bg-glitch-shift-repeat {
0%, 82% { transform: translate(0,0); clip-path: inset(0% 0 0 0); opacity: 0; }
@@ -1677,6 +1827,16 @@ html:has(body.video-background-active)::before {
scrollbar-width: none;
}
.marketplace-container {
padding-bottom: 6rem;
}
@media (max-width: 767px) {
.marketplace-container {
padding-bottom: calc(var(--mobile-tab-bar-height, 88px) + var(--safe-area-bottom, env(safe-area-inset-bottom, 0px)) + 2rem);
}
}
.mobile-category-strip::-webkit-scrollbar {
display: none;
}
@@ -2085,11 +2245,9 @@ html:has(body.video-background-active)::before {
@keyframes card-stagger-in {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@@ -2139,14 +2297,27 @@ html:has(body.video-background-active)::before {
height: 60px;
border-radius: 18px;
overflow: visible;
background: rgba(255, 255, 255, 0.08);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
background: rgba(0, 0, 0, 0.72);
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.38);
}
.archy-app-icon {
display: block;
box-sizing: border-box;
object-fit: cover;
background:
radial-gradient(circle at 35% 28%, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0) 42%),
linear-gradient(145deg, rgba(22, 22, 24, 0.96), rgba(0, 0, 0, 0.96));
border: 1px solid rgba(255, 255, 255, 0.18);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.12),
inset 0 -10px 24px rgba(0, 0, 0, 0.34),
0 8px 18px rgba(0, 0, 0, 0.35);
}
.app-icon-img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 18px;
}
@@ -2202,6 +2373,19 @@ html:has(body.video-background-active)::before {
white-space: nowrap;
}
.app-icon-progress-label {
display: -webkit-box;
max-width: 84px;
min-height: 22px;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
color: rgba(255, 255, 255, 0.58);
font-size: 9px;
line-height: 1.2;
text-align: center;
}
/* Page indicator dots */
.app-icon-dots {
display: flex;
@@ -2237,10 +2421,15 @@ html:has(body.video-background-active)::before {
/* Monitoring dashboard */
.monitoring-stat-card {
background: rgba(0, 0, 0, 0.3);
border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(0, 0, 0, 0.58);
border: 1px solid rgba(255, 255, 255, 0.16);
border-radius: 0.75rem;
padding: 1rem;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.34);
}
.monitoring-stat-card-compact {
padding: 0 1rem;
}
.monitoring-chart {
@@ -2370,10 +2559,12 @@ html:has(body.video-background-active)::before {
}
.fleet-sort-btn {
padding: 4px 10px;
padding: 5px 11px;
border-radius: 6px;
font-size: 0.625rem;
font-weight: 500;
font-size: 0.8rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.02em;
color: rgba(255, 255, 255, 0.5);
background: transparent;
border: 1px solid transparent;