@import "tailwindcss"; :root { --default-page-background-image: url("/assets/images/home-Checkups-List.svg"); --safe-top: env(safe-area-inset-top, 0px); --safe-bottom: env(safe-area-inset-bottom, 0px); --safe-left: env(safe-area-inset-left, 0px); --safe-right: env(safe-area-inset-right, 0px); /* ─── Semantic Tokens (Light) ─── */ --semantic-neutral-bg: #f1f5f9; --semantic-neutral-text: #475569; --semantic-neutral-border: #cbd5e1; --semantic-neutral-icon: #64748b; --semantic-info-bg: #eff6ff; --semantic-info-text: #1d4ed8; --semantic-info-border: #bfdbfe; --semantic-info-icon: #2563eb; --semantic-success-bg: #ecfdf5; --semantic-success-text: #047857; --semantic-success-border: #a7f3d0; --semantic-success-icon: #059669; --semantic-warning-bg: #fffbeb; --semantic-warning-text: #b45309; --semantic-warning-border: #fde68a; --semantic-warning-icon: #d97706; --semantic-danger-bg: #fef2f2; --semantic-danger-text: #b91c1c; --semantic-danger-border: #fecaca; --semantic-danger-icon: #dc2626; --semantic-ai-bg: #f5f3ff; --semantic-ai-text: #6d28d9; --semantic-ai-border: #ddd6fe; --semantic-ai-icon: #7c3aed; } .dark { --semantic-neutral-bg: #1e293b; --semantic-neutral-text: #e2e8f0; --semantic-neutral-border: #475569; --semantic-neutral-icon: #cbd5e1; --semantic-info-bg: #172554; --semantic-info-text: #bfdbfe; --semantic-info-border: #1d4ed8; --semantic-info-icon: #93c5fd; --semantic-success-bg: #052e2b; --semantic-success-text: #a7f3d0; --semantic-success-border: #047857; --semantic-success-icon: #6ee7b7; --semantic-warning-bg: #451a03; --semantic-warning-text: #fde68a; --semantic-warning-border: #b45309; --semantic-warning-icon: #fcd34d; --semantic-danger-bg: #450a0a; --semantic-danger-text: #fecaca; --semantic-danger-border: #b91c1c; --semantic-danger-icon: #fca5a5; --semantic-ai-bg: #2e1065; --semantic-ai-text: #ddd6fe; --semantic-ai-border: #7c3aed; --semantic-ai-icon: #c4b5fd; } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --font-sans: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; --font-mono: var(--font-geist-mono); --font-arabic: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; --font-ryling: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; --font-faminela: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; --color-semantic-neutral-bg: var(--semantic-neutral-bg); --color-semantic-neutral-text: var(--semantic-neutral-text); --color-semantic-neutral-border: var(--semantic-neutral-border); --color-semantic-neutral-icon: var(--semantic-neutral-icon); --color-semantic-info-bg: var(--semantic-info-bg); --color-semantic-info-text: var(--semantic-info-text); --color-semantic-info-border: var(--semantic-info-border); --color-semantic-info-icon: var(--semantic-info-icon); --color-semantic-success-bg: var(--semantic-success-bg); --color-semantic-success-text: var(--semantic-success-text); --color-semantic-success-border: var(--semantic-success-border); --color-semantic-success-icon: var(--semantic-success-icon); --color-semantic-warning-bg: var(--semantic-warning-bg); --color-semantic-warning-text: var(--semantic-warning-text); --color-semantic-warning-border: var(--semantic-warning-border); --color-semantic-warning-icon: var(--semantic-warning-icon); --color-semantic-danger-bg: var(--semantic-danger-bg); --color-semantic-danger-text: var(--semantic-danger-text); --color-semantic-danger-border: var(--semantic-danger-border); --color-semantic-danger-icon: var(--semantic-danger-icon); --color-semantic-ai-bg: var(--semantic-ai-bg); --color-semantic-ai-text: var(--semantic-ai-text); --color-semantic-ai-border: var(--semantic-ai-border); --color-semantic-ai-icon: var(--semantic-ai-icon); } /* Typography Configuration - Centralized Design System Scale */ @utility group-10 { font-size: 10px; } @utility group-12 { font-size: 12px; } @utility group-14 { font-size: 14px; } @utility group-16 { font-size: 16px; } .group-10 { font-size: 10px; } .group-12 { font-size: 12px; } .group-14 { font-size: 14px; } .group-16 { font-size: 16px; } html { width: 100%; height: 100%; overflow: hidden; overscroll-behavior: none; -webkit-tap-highlight-color: transparent; } * { -webkit-tap-highlight-color: transparent; } button, input, select, textarea, a, label, [role="button"] { touch-action: manipulation; } button, [role="button"] { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; } input, textarea { -webkit-user-select: text; user-select: text; } body { width: 100%; height: 100%; margin: 0; display: flex; justify-content: center; overflow: hidden; color: var(--foreground); font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; overscroll-behavior: none; } html:lang(ar) body, :lang(ar) { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; } .font-arabic, .font-ryling { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; } .font-faminela:lang(ar), .font-ryling:lang(ar), [dir="rtl"] .font-faminela, [dir="rtl"] .font-ryling, [dir="rtl"].font-faminela, [dir="rtl"].font-ryling, .font-faminela { font-family: var(--font-faminela-local), "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; } .app-shell { width: 100%; height: 100%; height: 100dvh; padding-inline: 17px; padding-bottom: var(--safe-bottom, 0px); box-sizing: border-box; overflow-x: hidden; overflow-y: auto; background-color: var(--background); background-image: var(--default-page-background-image); background-position: top; background-repeat: no-repeat; background-size: cover; overscroll-behavior: none; touch-action: pan-y; -webkit-overflow-scrolling: touch; } @media (min-width: 640px) { .app-shell { width: 375px; } } body[data-page-background="none"] .app-shell { background-image: none; } .app-shell:has(.page-background-none) { background-image: none; } body[data-page-background="custom"] .app-shell { background-image: var(--page-background-image); } .app-shell:has(.page-background-custom) { background-image: var(--page-background-image); } body.dropdown-open .app-shell, body.section-overlay-open .app-shell { overflow-y: hidden; } /* ── Section Overlay Slide-in Panel (Exact Flutter Najm Matching: 350ms in, 200ms out, easeInOut) ── */ .section-overlay { position: fixed; inset-block: 0; inset-inline: 0; margin-inline: auto; width: 100%; height: 100%; height: 100dvh; z-index: 50; overflow-x: hidden; overflow-y: auto; overscroll-behavior: none; touch-action: pan-y; -webkit-overflow-scrolling: touch; padding-inline: 17px; padding-bottom: var(--safe-bottom, 0px); box-sizing: border-box; background-color: var(--background); background-image: var(--default-page-background-image); background-position: top; background-repeat: no-repeat; background-size: cover; transform: translate3d(100%, 0, 0); box-shadow: -18px 0 50px rgba(0, 0, 0, 0.18); transition: transform 350ms cubic-bezier(0.42, 0, 0.58, 1); will-change: transform; backface-visibility: hidden; -webkit-backface-visibility: hidden; contain: paint layout; } @media (min-width: 640px) { .section-overlay { width: 375px; } } /* RTL: slide in from left instead of right */ [dir="rtl"] .section-overlay, .section-overlay[data-dir="rtl"], [dir="rtl"] .section-overlay[data-state="closed"], [dir="rtl"] .section-overlay[data-state="closing"], .section-overlay[data-dir="rtl"][data-state="closed"], .section-overlay[data-dir="rtl"][data-state="closing"] { transform: translate3d(-100%, 0, 0); box-shadow: 18px 0 50px rgba(0, 0, 0, 0.18); } .section-overlay[data-state="open"] { transform: translate3d(0, 0, 0) !important; } .section-overlay[data-state="closing"] { transition: transform 200ms cubic-bezier(0.42, 0, 0.58, 1) !important; } @media (prefers-reduced-motion: reduce) { .section-overlay { transition: none !important; } } .question-detail-header { max-height: 120px; overflow: hidden; transition: transform 300ms ease-in-out, opacity 220ms ease-out, max-height 300ms ease-in-out, margin 300ms ease-in-out; } .question-progress, .question-snap-content { transition: transform 300ms ease-in-out, opacity 220ms ease-out, max-height 300ms ease-in-out, padding 300ms ease-in-out, margin 300ms ease-in-out; } .question-snap-content { transform: translate3d( 0, calc(var(--question-lift-y, 0px) * -1), 0 ); transition: transform 200ms cubic-bezier(0.16, 1, 0.3, 1); will-change: transform; } .page-background-none, .page-background-custom, .page-background-default { display: none; } .question-slider-range { height: 18px; width: 100%; cursor: pointer; appearance: none; border-radius: 999px; outline: none; background: transparent; } .question-slider-range::-webkit-slider-runnable-track { height: 10px; border-radius: 999px; } .question-slider-range::-webkit-slider-thumb { width: 18px; height: 18px; margin-top: -4px; appearance: none; border: 0; border-radius: 999px; background: #ffffff; box-shadow: 0 3px 8px rgba(0, 0, 0, 0.12), 0 0 2px rgba(0, 0, 0, 0.15); } .question-slider-range::-moz-range-track { height: 10px; border-radius: 999px; background: transparent; } .question-slider-range::-moz-range-progress { height: 10px; border-radius: 999px; background: #f2465f; } .question-slider-range::-moz-range-thumb { width: 18px; height: 18px; border: 0; border-radius: 999px; background: #ffffff; box-shadow: 0 3px 8px rgba(0, 0, 0, 0.12), 0 0 2px rgba(0, 0, 0, 0.15); } /* 3 Dots Bouncing Line Circle Loader for Buttons */ @keyframes button-dot-bounce { 0%, 80%, 100% { transform: translateY(0) scale(0.7); opacity: 0.4; } 40% { transform: translateY(-4px) scale(1.15); opacity: 1; } } .animate-dots-slide-1 { animation: button-dot-bounce 0.9s cubic-bezier(0.4, 0, 0.6, 1) infinite; animation-delay: 0s; } .animate-dots-slide-2 { animation: button-dot-bounce 0.9s cubic-bezier(0.4, 0, 0.6, 1) infinite; animation-delay: 0.15s; } .animate-dots-slide-3 { animation: button-dot-bounce 0.9s cubic-bezier(0.4, 0, 0.6, 1) infinite; animation-delay: 0.3s; } /* ─── Flutter AppShimmer-style skeleton ─── Mirrors najm's AppShimmer (shimmer 3.0.0): - 1500ms linear sweep, no easing curve - one soft band travels -100% -> +100% on a composited transform (no background-position repaint, so it stays smooth inside the Flutter webview instead of flickering) - gradient stops mirror Shimmer.fromColors: base .0 / base .35 / highlight .5 / base .65 / base 1.0 - light mode colors are derived from a white scaffold the same way AppShimmer lerps scaffold bg toward black (base +5%, band peaks +10%) */ @keyframes skeleton-sweep { from { transform: translateX(-100%); } to { transform: translateX(100%); } } .shimmer-bg { position: relative; overflow: hidden; isolation: isolate; background-color: rgba(0, 0, 0, 0.05); } .shimmer-bg::before { content: ""; position: absolute; inset: 0; z-index: 1; transform: translateX(-100%); background: linear-gradient( 100deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 35%, rgba(0, 0, 0, 0.05) 50%, rgba(0, 0, 0, 0) 65%, rgba(0, 0, 0, 0) 100% ); pointer-events: none; will-change: transform; animation: skeleton-sweep 1.5s linear infinite; } .dark .shimmer-bg { background-color: rgba(255, 255, 255, 0.08); } .dark .shimmer-bg::before { background: linear-gradient( 100deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 35%, rgba(255, 255, 255, 0.09) 50%, rgba(255, 255, 255, 0) 65%, rgba(255, 255, 255, 0) 100% ); } /* Light band variant for skeleton blocks sitting on dark surfaces (e.g. the blue required-steps card on questions-list). */ .shimmer-white-bg { position: relative; overflow: hidden; isolation: isolate; background-color: rgba(255, 255, 255, 0.12); } .shimmer-white-bg::before { content: ""; position: absolute; inset: 0; z-index: 1; transform: translateX(-100%); background: linear-gradient( 100deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 35%, rgba(255, 255, 255, 0.13) 50%, rgba(255, 255, 255, 0) 65%, rgba(255, 255, 255, 0) 100% ); pointer-events: none; will-change: transform; animation: skeleton-sweep 1.5s linear infinite; } /* span elements using these classes directly (inline in JSX) need a formatted box for the absolutely-positioned sweep layer to align. */ span.shimmer-bg, span.shimmer-white-bg { display: inline-block; }