fix: prevent tokio runtime deadlock in credential issue/verify

The credential issuance and verification handlers used
Handle::block_on() directly inside the tokio runtime, causing a
deadlock. Wrapped with block_in_place() to properly yield the
runtime thread.

Also completed full feature verification across all 25 test groups
(~175 checks) on live server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-09 07:43:12 +00:00
parent 5ce8b7965c
commit e3aa95a103
81 changed files with 11492 additions and 649 deletions

View File

@@ -24,6 +24,31 @@
transition: box-shadow 0.2s ease;
}
/* 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"]) {
min-height: 44px;
}
}
/* Haptic-like press feedback for all interactive elements */
button:active:not(:disabled),
[role="button"]:active,
a.glass-card:active,
a.goal-card:active,
.info-card-button:active,
.path-action-button:active {
transform: scale(0.97) !important;
transition: transform 0.1s ease !important;
}
/* Toggle switches — subtle press */
input[type="checkbox"]:active + *,
input[type="radio"]:active + * {
transform: scale(0.95);
transition: transform 0.1s ease;
}
/* Containers: base scale for smooth grow animation */
[data-controller-container] {
transition: transform 0.2s ease, box-shadow 0.2s ease;
@@ -84,7 +109,7 @@
font-size: 0.75rem;
font-weight: 500;
color: rgba(255, 255, 255, 0.45);
transition: all 0.25s ease;
transition: color 0.2s ease, background-color 0.2s ease;
cursor: pointer;
text-align: center;
border: none;
@@ -138,7 +163,7 @@
border: 1px solid rgba(255, 255, 255, 0.12);
color: rgba(255, 255, 255, 0.8);
cursor: pointer;
transition: all 0.25s ease;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
user-select: none;
}
@@ -220,13 +245,17 @@
/* Goal cards */
.goal-card {
cursor: pointer;
transition: all 0.3s ease;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s ease;
}
.goal-card:hover {
transform: translateY(-2px);
}
.goal-card:active {
transform: translateY(1px);
}
.goal-status-badge {
display: inline-flex;
align-items: center;
@@ -256,7 +285,7 @@
.goal-step {
padding: 1rem 1.25rem;
border-left: 3px solid rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
transition: border-color 0.3s ease, background-color 0.3s ease;
}
.goal-step-active {
@@ -278,6 +307,7 @@
align-items: center;
justify-content: center;
padding-inline: 1.25rem;
min-height: 44px;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(24px);
-webkit-backdrop-filter: blur(24px);
@@ -287,7 +317,11 @@
border-radius: 0.75rem;
border: none;
color: rgba(255, 255, 255, 0.9);
transition: all 0.3s ease;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.2s ease, box-shadow 0.3s ease;
}
.glass-button:active {
transform: translateY(1px);
}
.glass-button::before {
@@ -321,6 +355,7 @@
padding-block: 0.375rem;
padding-inline: 0.75rem;
font-size: 0.875rem;
min-height: 36px;
}
/* Toast - glassmorphic, top-right */
@@ -336,7 +371,7 @@
/* Toast transition */
.toast-enter-active,
.toast-leave-active {
transition: all 0.3s ease;
transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.toast-enter-from,
.toast-leave-to {
@@ -428,10 +463,14 @@
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.2s ease, box-shadow 0.3s ease;
border: none;
}
.path-option-card:active {
transform: translateY(1px);
}
/* Gradient border effect using CSS mask - default is subtle */
.path-option-card::before {
content: '';
@@ -451,7 +490,7 @@
/* Icon styling with black glass effect */
.path-option-card svg {
color: rgba(255, 255, 255, 0.85);
transition: all 0.3s ease;
transition: color 0.2s ease, filter 0.3s ease;
filter:
drop-shadow(0 1px 1px rgba(255, 255, 255, 0.3))
drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))
@@ -521,12 +560,16 @@
border: none;
position: relative;
cursor: pointer;
transition: all 0.3s ease;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.2s ease, box-shadow 0.3s ease;
min-width: 0;
white-space: nowrap;
letter-spacing: 0.02em;
}
.path-action-button:active {
transform: translateY(1px);
}
.path-action-button--skip {
padding: 12px 40px;
font-size: 16px;
@@ -885,7 +928,7 @@ html:has(body.video-background-active)::before {
gap: 0.75rem;
padding: 0.5rem;
border-radius: 0.75rem;
transition: all 0.2s ease;
transition: background-color 0.2s ease;
text-align: left;
width: 100%;
cursor: pointer;
@@ -936,7 +979,7 @@ html:has(body.video-background-active)::before {
color: rgba(255, 255, 255, 0.6);
border: none;
cursor: pointer;
transition: all 0.15s ease;
transition: background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
text-decoration: none;
}
.cloud-file-action-btn:hover {
@@ -988,7 +1031,7 @@ html:has(body.video-background-active)::before {
border: none;
cursor: pointer;
border-radius: 0.25rem;
transition: all 0.15s ease;
transition: background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
white-space: nowrap;
}
.cloud-breadcrumb-item:hover:not(.cloud-breadcrumb-active) {
@@ -1027,7 +1070,7 @@ html:has(body.video-background-active)::before {
cursor: pointer;
background: transparent;
color: rgba(255, 255, 255, 0.35);
transition: all 0.15s ease;
transition: background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}
.cloud-view-toggle-btn:hover {
color: rgba(255, 255, 255, 0.7);
@@ -1067,7 +1110,7 @@ html:has(body.video-background-active)::before {
background: rgba(255, 255, 255, 0.04);
border-radius: 0.75rem;
overflow: hidden;
transition: all 0.2s ease;
transition: background-color 0.2s ease, box-shadow 0.2s ease;
color: inherit;
padding: 0;
}
@@ -1220,7 +1263,7 @@ html:has(body.video-background-active)::before {
color: white;
cursor: pointer;
flex-shrink: 0;
transition: all 0.15s ease;
transition: background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
padding: 0;
}
.cloud-audio-player-btn:hover {
@@ -1267,3 +1310,36 @@ html:has(body.video-background-active)::before {
from { opacity: 0; }
to { opacity: 1; }
}
/* Smooth loading → content transition */
.content-fade-enter-active,
.content-fade-leave-active {
transition: opacity 0.2s ease, transform 0.2s ease;
}
.content-fade-enter-from {
opacity: 0;
transform: translateY(6px);
}
.content-fade-leave-to {
opacity: 0;
}
/* Staggered card entrance animation */
.card-stagger {
opacity: 0;
animation: card-stagger-in 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
animation-delay: calc(var(--stagger-index, 0) * 50ms);
}
@keyframes card-stagger-in {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}