initial commit of mobile app
This commit is contained in:
@@ -0,0 +1,324 @@
|
||||
/**
|
||||
* MobileApp Shared Base Styles
|
||||
*
|
||||
* Common styles for all mobile PWAs including:
|
||||
* - Dark mode support
|
||||
* - PWA-specific optimizations
|
||||
* - Common animations
|
||||
* - Utility classes
|
||||
*/
|
||||
|
||||
/* ==================== ROOT & DARK MODE ==================== */
|
||||
|
||||
:root {
|
||||
--color-primary: #005384;
|
||||
--color-secondary: #fac41b;
|
||||
--color-success: #22c55e;
|
||||
--color-danger: #ef4444;
|
||||
--color-warning: #f59e0b;
|
||||
}
|
||||
|
||||
/* Dark mode is toggled by adding 'dark' class to <html> */
|
||||
.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
|
||||
/* ==================== PWA OPTIMIZATIONS ==================== */
|
||||
|
||||
html, body {
|
||||
/* Prevents rubber-band scroll on iOS and pull-to-refresh on Android */
|
||||
overscroll-behavior: none;
|
||||
/* Prevent text selection on double tap */
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
/* Smooth font rendering */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
/* Prevent zoom on input focus (iOS) */
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
/* Allow text selection in inputs and textareas */
|
||||
input, textarea, [contenteditable] {
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
/* Safe area insets for notched devices */
|
||||
.safe-area-top {
|
||||
padding-top: env(safe-area-inset-top);
|
||||
}
|
||||
|
||||
.safe-area-bottom {
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
|
||||
/* ==================== ANIMATIONS ==================== */
|
||||
|
||||
/* Slide transition for panels */
|
||||
.slide-enter-active,
|
||||
.slide-leave-active {
|
||||
transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.slide-enter-from,
|
||||
.slide-leave-to {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
/* Slide up transition for modals */
|
||||
.slide-up-enter-active,
|
||||
.slide-up-leave-active {
|
||||
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.slide-up-enter-from,
|
||||
.slide-up-leave-to {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
/* Slide down transition for top sheets */
|
||||
.slide-down-enter-active,
|
||||
.slide-down-leave-active {
|
||||
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.slide-down-enter-from,
|
||||
.slide-down-leave-to {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
/* Fade transition */
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Overlay transition */
|
||||
.overlay-enter-active,
|
||||
.overlay-leave-active {
|
||||
transition: opacity 0.35s ease;
|
||||
}
|
||||
|
||||
.overlay-enter-from,
|
||||
.overlay-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Scale in transition */
|
||||
.scale-enter-active,
|
||||
.scale-leave-active {
|
||||
transition: transform 0.2s ease, opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.scale-enter-from,
|
||||
.scale-leave-to {
|
||||
transform: scale(0.95);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Spinner animation */
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.spin {
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
/* Pulse animation for loading states */
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
.pulse {
|
||||
animation: pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Network background animations */
|
||||
@keyframes node-glow {
|
||||
0%, 100% {
|
||||
transform: scale(1);
|
||||
opacity: 0.8;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.4);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes node-glow-slow {
|
||||
0%, 100% {
|
||||
transform: scale(1);
|
||||
opacity: 0.7;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.3);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes line-pulse {
|
||||
0%, 100% { opacity: 0.3; }
|
||||
50% { opacity: 0.6; }
|
||||
}
|
||||
|
||||
@keyframes line-flow {
|
||||
0% { stroke-dashoffset: 1000; }
|
||||
100% { stroke-dashoffset: 0; }
|
||||
}
|
||||
|
||||
.network-node {
|
||||
animation: node-glow 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.network-node-slow {
|
||||
animation: node-glow-slow 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.network-lines {
|
||||
animation: line-pulse 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.network-line-flow {
|
||||
stroke-dasharray: 20 30;
|
||||
animation: line-flow 8s linear infinite;
|
||||
}
|
||||
|
||||
|
||||
/* ==================== PANEL EFFECTS ==================== */
|
||||
|
||||
/* Background blur effect when panel is open */
|
||||
.panel-open {
|
||||
transform: scale(0.95);
|
||||
filter: blur(4px);
|
||||
opacity: 0.7;
|
||||
transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
filter 0.35s,
|
||||
opacity 0.35s;
|
||||
}
|
||||
|
||||
.list-container {
|
||||
transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
filter 0.35s,
|
||||
opacity 0.35s;
|
||||
}
|
||||
|
||||
|
||||
/* ==================== OVERLAY ==================== */
|
||||
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
transition: opacity 0.35s ease;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
|
||||
/* ==================== TOAST NOTIFICATIONS ==================== */
|
||||
|
||||
.toast-container {
|
||||
position: fixed;
|
||||
bottom: calc(1rem + env(safe-area-inset-bottom));
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.toast {
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
pointer-events: auto;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.toast-success {
|
||||
background-color: var(--color-success);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.toast-error {
|
||||
background-color: var(--color-danger);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.toast-warning {
|
||||
background-color: var(--color-warning);
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
/* ==================== FORM ELEMENTS ==================== */
|
||||
|
||||
/* Prevent iOS zoom on input focus */
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"],
|
||||
input[type="number"],
|
||||
input[type="tel"],
|
||||
input[type="search"],
|
||||
textarea,
|
||||
select {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
/* Remove tap highlight on mobile */
|
||||
button, a, input, select, textarea {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
/* Better focus styles for accessibility */
|
||||
button:focus-visible,
|
||||
input:focus-visible,
|
||||
select:focus-visible,
|
||||
textarea:focus-visible {
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
|
||||
/* ==================== UTILITIES ==================== */
|
||||
|
||||
/* Hide scrollbar but allow scrolling */
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Loading overlay */
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
/* Numeric keypad input */
|
||||
.numeric-input {
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
Reference in New Issue
Block a user