Download src/app/polish.css from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 28 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/app/polish.css
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/app/polish.css
-
curl -L -o polish.css https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/app/polish.css
28 kB
| /* ========================================================================== | |
| DocDoe AI β Frontend Polish & Production Excellence | |
| Premium interaction layer for Apple-level UX | |
| ========================================================================== */ | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 1. TOUCH RESPONSIVENESS | |
| Eliminate 300ms tap delay, optimize touch targets, ensure mobile-first feel | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Universal touch optimization - apply to ALL interactive elements */ | |
| button, | |
| a[href], | |
| input[type="button"], | |
| input[type="submit"], | |
| input[type="reset"], | |
| [role="button"], | |
| [role="link"], | |
| [tabindex]:focus, | |
| label, | |
| summary, | |
| -details > summary { | |
| touch-action: manipulation; | |
| -webkit-tap-highlight-color: transparent; | |
| -webkit-user-select: none; | |
| user-select: none; | |
| } | |
| /* Keep 44px touch targets on compact screens without overriding deliberate | |
| desktop control sizes or every Tailwind padding utility in the product. */ | |
| @media (max-width: 768px) and (hover: none) { | |
| button, | |
| [role="button"], | |
| [role="tab"], | |
| a[href] { | |
| min-height: 44px; | |
| min-width: 44px; | |
| } | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 2. ACTIVE & HOVER STATES | |
| Consistent, immediate feedback for all interactive elements | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Base transition for all interactive elements - fast and smooth */ | |
| button, | |
| a[href], | |
| [role="button"], | |
| input[type="button"], | |
| input[type="submit"], | |
| input[type="reset"], | |
| [role="tab"] { | |
| transition: | |
| background-color 0.15s var(--ease-out), | |
| border-color 0.15s var(--ease-out), | |
| color 0.15s var(--ease-out), | |
| transform 0.1s var(--ease-out), | |
| box-shadow 0.15s var(--ease-out), | |
| opacity 0.15s var(--ease-out); | |
| will-change: transform, opacity; | |
| } | |
| /* Active state - subtle scale for physical feel (98% for press) */ | |
| button:active:not(:disabled), | |
| [role="button"]:active:not(:disabled), | |
| a[href]:active, | |
| input[type="button"]:active:not(:disabled), | |
| input[type="submit"]:active:not(:disabled), | |
| input[type="reset"]:active:not(:disabled), | |
| [role="tab"]:active:not(:disabled) { | |
| transform: scale(0.98); | |
| } | |
| /* Hover state - elevate slightly for premium feel */ | |
| button:hover:not(:disabled):not(:active), | |
| [role="button"]:hover:not(:disabled):not(:active), | |
| a[href]:hover:not(:disabled):not(:active), | |
| input[type="button"]:hover:not(:disabled):not(:active), | |
| input[type="submit"]:hover:not(:disabled):not(:active), | |
| input[type="reset"]:hover:not(:disabled):not(:active), | |
| [role="tab"]:hover:not(:disabled):not(:active) { | |
| transform: translateY(-1px); | |
| } | |
| /* Focus visible - consistent focus ring for accessibility */ | |
| button:focus-visible, | |
| a[href]:focus-visible, | |
| [role="button"]:focus-visible, | |
| input:focus-visible, | |
| [role="tab"]:focus-visible { | |
| outline: none; | |
| box-shadow: | |
| 0 0 0 3px rgba(255, 255, 255, 0.12), | |
| 0 0 0 1px rgba(255, 255, 255, 0.28); | |
| } | |
| /* Disabled state - clear and consistent */ | |
| button:disabled, | |
| [role="button"]:disabled, | |
| input:disabled, | |
| [role="tab"]:disabled { | |
| cursor: not-allowed; | |
| opacity: 0.4; | |
| transform: none ; | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 3. TAP FEEDBACK FOR TOUCH DEVICES | |
| Instant visual confirmation on touch | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Tap highlight for touch devices */ | |
| @media (hover: none) { | |
| button:active:not(:disabled), | |
| [role="button"]:active:not(:disabled), | |
| a[href]:active { | |
| background: rgba(255, 255, 255, 0.08) ; | |
| transform: scale(0.96) ; | |
| } | |
| } | |
| /* Touch ripple effect for primary actions */ | |
| .touch-ripple { | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .touch-ripple::after { | |
| content: ""; | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| width: 0; | |
| height: 0; | |
| background: rgba(255, 255, 255, 0.15); | |
| border-radius: 50%; | |
| transform: translate(-50%, -50%); | |
| opacity: 0; | |
| transition: | |
| width 0.3s ease, | |
| height 0.3s ease, | |
| opacity 0.3s ease; | |
| pointer-events: none; | |
| } | |
| .touch-ripple:active::after { | |
| width: 200%; | |
| height: 200%; | |
| opacity: 1; | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 4. LOADING STATES | |
| Smooth, skeleton-based loading for content | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Loading skeleton base */ | |
| .skeleton { | |
| background: linear-gradient( | |
| 90deg, | |
| var(--bg-elevated) 25%, | |
| var(--bg-glass) 50%, | |
| var(--bg-elevated) 75% | |
| ); | |
| background-size: 200% 100%; | |
| animation: skeleton-loading 1.5s infinite; | |
| border-radius: var(--radius-sm); | |
| } | |
| @keyframes skeleton-loading { | |
| 0% { | |
| background-position: 200% 0; | |
| } | |
| 100% { | |
| background-position: -200% 0; | |
| } | |
| } | |
| /* Text skeleton */ | |
| .skeleton-text { | |
| height: 1em; | |
| margin-bottom: 0.5em; | |
| } | |
| .skeleton-text.short { | |
| width: 60%; | |
| } | |
| .skeleton-text.medium { | |
| width: 80%; | |
| } | |
| /* Card skeleton */ | |
| .skeleton-card { | |
| height: 120px; | |
| border: 1px solid var(--border-subtle); | |
| border-radius: var(--radius-md); | |
| } | |
| /* Button skeleton */ | |
| .skeleton-button { | |
| height: 44px; | |
| width: 120px; | |
| border-radius: var(--radius-sm); | |
| } | |
| /* Spinner - consistent across app */ | |
| .spinner { | |
| width: 20px; | |
| height: 20px; | |
| border: 2px solid transparent; | |
| border-top-color: currentColor; | |
| border-radius: 50%; | |
| animation: spinner-rotate 0.8s linear infinite; | |
| display: inline-block; | |
| } | |
| @keyframes spinner-rotate { | |
| to { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| /* Loading overlay for containers */ | |
| .loading-overlay { | |
| position: relative; | |
| } | |
| .loading-overlay::after { | |
| content: ""; | |
| position: absolute; | |
| inset: 0; | |
| background: rgba(0, 0, 0, 0.4); | |
| backdrop-filter: blur(4px); | |
| border-radius: inherit; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .loading-overlay::before { | |
| content: ""; | |
| position: absolute; | |
| inset: 0; | |
| background: inherit; | |
| border-radius: inherit; | |
| z-index: -1; | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 5. SCROLL OPTIMIZATION | |
| Smooth, jank-free scrolling | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Smooth scrolling globally */ | |
| html { | |
| scroll-behavior: smooth; | |
| } | |
| /* Scroll container optimization */ | |
| * { | |
| scrollbar-width: thin; | |
| scrollbar-color: rgba(255, 255, 255, 0.12) transparent; | |
| } | |
| /* Hide scrollbar on mobile for cleaner look */ | |
| @media (max-width: 768px) { | |
| *::-webkit-scrollbar { | |
| display: none; | |
| } | |
| * { | |
| scrollbar-width: none; | |
| } | |
| } | |
| /* Scrollbar styling for desktop */ | |
| ::-webkit-scrollbar { | |
| width: 6px; | |
| height: 6px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: transparent; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: rgba(255, 255, 255, 0.12); | |
| border-radius: 3px; | |
| border: 2px solid transparent; | |
| background-clip: content-box; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: rgba(255, 255, 255, 0.22); | |
| } | |
| /* Prevent scroll jank with contain */ | |
| offscreen, | |
| [content-visibility="auto"] { | |
| contain-intrinsic-size: auto 1000px; | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 6. MOBILE-SPECIFIC OPTIMIZATIONS | |
| Thumb-friendly, compact, efficient | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Mobile touch targets - ensure minimum 44px */ | |
| @media (max-width: 768px) { | |
| button, | |
| [role="button"], | |
| a[href], | |
| [role="tab"], | |
| .touch-target { | |
| min-height: 44px; | |
| min-width: 44px; | |
| } | |
| /* Larger touch targets for primary actions */ | |
| .btn-primary, | |
| .btn-hero, | |
| .btn-secondary { | |
| min-height: 48px; | |
| } | |
| } | |
| /* Mobile card interactions - larger tap area */ | |
| @media (max-width: 768px) { | |
| .card-touch-area { | |
| padding: 4px; | |
| margin: -4px; | |
| border-radius: inherit; | |
| } | |
| /* Mobile card active state */ | |
| .card-touch-area:active { | |
| transform: scale(0.97); | |
| opacity: 0.8; | |
| } | |
| } | |
| /* Mobile form inputs - larger tap areas */ | |
| @media (max-width: 768px) { | |
| input, | |
| textarea, | |
| select { | |
| min-height: 48px; | |
| } | |
| input[type="checkbox"], | |
| input[type="radio"] { | |
| min-width: 44px; | |
| min-height: 44px; | |
| } | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 7. BLUR OPTIMIZATION | |
| Reduce expensive backdrop-filter on mobile | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Disable expensive blur on low-end devices */ | |
| @media (max-width: 768px) and (hover: none) { | |
| *, | |
| *::before, | |
| *::after { | |
| backdrop-filter: none ; | |
| -webkit-backdrop-filter: none ; | |
| } | |
| /* Keep each component's own light or dark surface. A blanket dark | |
| replacement made light navigation, lesson headers, and sticky actions | |
| turn black on touch devices. The existing alpha background remains a | |
| sufficient low-cost fallback after blur is disabled above. */ | |
| } | |
| /* Reduced blur for performance */ | |
| @media (forced-colors: active) { | |
| *, | |
| *::before, | |
| *::after { | |
| backdrop-filter: none ; | |
| -webkit-backdrop-filter: none ; | |
| } | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 8. ANIMATION PERFORMANCE | |
| Optimized for low-end Android devices | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Hardware acceleration for animations */ | |
| .gpu-accel { | |
| transform: translateZ(0); | |
| will-change: transform, opacity; | |
| backface-visibility: hidden; | |
| perspective: 1000px; | |
| } | |
| /* Optimized animations - no heavy effects */ | |
| @keyframes fade-in-fast { | |
| from { | |
| opacity: 0; | |
| } | |
| to { | |
| opacity: 1; | |
| } | |
| } | |
| @keyframes slide-up-fast { | |
| from { | |
| opacity: 0; | |
| transform: translateY(10px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| .animate-fade-in-fast { | |
| animation: fade-in-fast 0.15s var(--ease-out) both; | |
| } | |
| .animate-slide-up-fast { | |
| animation: slide-up-fast 0.2s var(--ease-out) both; | |
| } | |
| /* Reduced motion preference */ | |
| @media (prefers-reduced-motion: reduce) { | |
| *, | |
| *::before, | |
| *::after { | |
| animation-duration: 0.01ms ; | |
| animation-iteration-count: 1 ; | |
| transition-duration: 0.01ms ; | |
| scroll-behavior: auto ; | |
| } | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 9. EMPTY STATES | |
| Clean, helpful empty states | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .empty-state { | |
| text-align: center; | |
| padding: 48px 24px; | |
| } | |
| .empty-state-icon { | |
| width: 64px; | |
| height: 64px; | |
| margin: 0 auto 16px; | |
| background: var(--bg-elevated); | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .empty-state-title { | |
| font-size: 18px; | |
| font-weight: 600; | |
| color: var(--text-primary); | |
| margin-bottom: 8px; | |
| } | |
| .empty-state-description { | |
| font-size: 14px; | |
| color: var(--text-secondary); | |
| max-width: 300px; | |
| margin: 0 auto; | |
| } | |
| .empty-state-actions { | |
| margin-top: 24px; | |
| display: flex; | |
| gap: 12px; | |
| justify-content: center; | |
| flex-wrap: wrap; | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 10. CARD INTERACTIONS | |
| Premium feel for all card components | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Card hover - subtle elevation */ | |
| .card-hover { | |
| border: 1px solid var(--border-subtle); | |
| transition: | |
| border-color 0.15s var(--ease-out), | |
| box-shadow 0.2s var(--ease-out), | |
| transform 0.1s var(--ease-out); | |
| } | |
| .card-hover:hover { | |
| border-color: var(--border-medium); | |
| box-shadow: var(--shadow-sm); | |
| } | |
| /* Card active - press effect */ | |
| .card-hover:active { | |
| transform: scale(0.99); | |
| } | |
| /* Premium card - glass effect with fallback */ | |
| .premium-card { | |
| background: var(--bg-surface); | |
| border: 1px solid var(--border-subtle); | |
| border-radius: var(--radius-md); | |
| transition: | |
| background-color 0.2s var(--ease-out), | |
| border-color 0.15s var(--ease-out), | |
| box-shadow 0.2s var(--ease-out); | |
| } | |
| .premium-card:hover { | |
| background: var(--bg-elevated); | |
| border-color: var(--border-medium); | |
| box-shadow: var(--shadow-md); | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 11. FORM ELEMENTS | |
| Clean, accessible form controls | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Global: kill all native focus styles on form elements. | |
| Visual feedback is handled per-component (outer focus-within glow). */ | |
| input:focus, | |
| textarea:focus, | |
| select:focus { | |
| outline: none; | |
| box-shadow: none; | |
| } | |
| /* Explicit form inputs (login, settings, onboarding) keep their own focus ring */ | |
| .input-field:focus { | |
| border-color: var(--accent-primary); | |
| box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.08); | |
| } | |
| /* Input hover state */ | |
| input:hover:not(:focus), | |
| textarea:hover:not(:focus), | |
| select:hover:not(:focus) { | |
| border-color: var(--border-medium); | |
| } | |
| /* Input disabled state */ | |
| input:disabled, | |
| textarea:disabled, | |
| select:disabled { | |
| background: var(--bg-glass); | |
| border-color: var(--border-subtle); | |
| color: var(--text-muted); | |
| cursor: not-allowed; | |
| } | |
| /* Input error state */ | |
| input.error, | |
| textarea.error, | |
| select.error { | |
| border-color: var(--accent-red); | |
| background: rgba(251, 113, 133, 0.05); | |
| } | |
| input.error:focus, | |
| textarea.error:focus, | |
| select.error:focus { | |
| box-shadow: 0 0 0 3px rgba(251, 113, 133, 0.15); | |
| } | |
| /* Label interactions */ | |
| label { | |
| cursor: pointer; | |
| transition: color 0.15s var(--ease-out); | |
| } | |
| label:hover { | |
| color: var(--text-primary); | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 12. NAVIGATION | |
| Smooth, confident navigation | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Link transitions */ | |
| a { | |
| transition: color 0.15s var(--ease-out); | |
| } | |
| /* Nav item active state */ | |
| .nav-item { | |
| position: relative; | |
| transition: | |
| color 0.15s var(--ease-out), | |
| background-color 0.15s var(--ease-out); | |
| } | |
| .nav-item:active { | |
| transform: scale(0.97); | |
| } | |
| /* Nav underline indicator */ | |
| .nav-underline { | |
| position: absolute; | |
| bottom: 0; | |
| left: 0; | |
| right: 0; | |
| height: 2px; | |
| background: var(--accent-primary); | |
| border-radius: 1px; | |
| transform: scaleX(0); | |
| transition: transform 0.2s var(--ease-out); | |
| } | |
| .nav-item.active .nav-underline { | |
| transform: scaleX(1); | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 13. HYDRATION | |
| Prevent layout shift and flicker | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Prevent layout shift on hydration */ | |
| input.caret-transparent, | |
| input.caret-transparent:focus { | |
| caret-color: transparent; | |
| } | |
| .hydrate-safe { | |
| contain-intrinsic-size: auto 1000px; | |
| content-visibility: auto; | |
| } | |
| /* Skeleton during loading */ | |
| [aria-busy="true"] { | |
| position: relative; | |
| } | |
| [aria-busy="true"]::after { | |
| content: ""; | |
| position: absolute; | |
| inset: 0; | |
| background: linear-gradient( | |
| 90deg, | |
| transparent 0%, | |
| rgba(255, 255, 255, 0.04) 50%, | |
| transparent 100% | |
| ); | |
| background-size: 200% 100%; | |
| animation: skeleton-loading 1.5s infinite; | |
| border-radius: inherit; | |
| pointer-events: none; | |
| } | |
| /* Hide content until hydrated */ | |
| [aria-live="polite"] { | |
| opacity: 1; | |
| transition: opacity 0.2s var(--ease-out); | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 14. BUTTON VARIANTS | |
| Consistent button styles | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Primary button - consistent style */ | |
| .btn { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 8px; | |
| padding: 12px 24px; | |
| border-radius: var(--radius-sm); | |
| font-size: 14px; | |
| font-weight: 600; | |
| letter-spacing: -0.01em; | |
| transition: | |
| background-color 0.15s var(--ease-out), | |
| border-color 0.15s var(--ease-out), | |
| color 0.15s var(--ease-out), | |
| transform 0.1s var(--ease-out); | |
| min-height: 44px; | |
| touch-action: manipulation; | |
| } | |
| /* DocDoe primary action = white on near-black, matching the signup and | |
| composer-send buttons. The old amber (#F59E0B) fought the monochrome brand. */ | |
| .btn-primary { | |
| background: #ffffff; | |
| color: #080808; | |
| border: 1px solid rgba(255, 255, 255, 0.16); | |
| } | |
| .btn-primary:hover:not(:disabled) { | |
| background: rgba(255, 255, 255, 0.9); | |
| } | |
| .btn-primary:active:not(:disabled) { | |
| transform: scale(0.98); | |
| } | |
| .btn-secondary { | |
| background: var(--bg-surface); | |
| color: var(--text-primary); | |
| border: 1px solid var(--border-medium); | |
| } | |
| .btn-secondary:hover:not(:disabled) { | |
| background: var(--bg-elevated); | |
| border-color: var(--border-medium); | |
| } | |
| .btn-ghost { | |
| background: transparent; | |
| color: var(--text-secondary); | |
| border: 1px solid var(--border-subtle); | |
| } | |
| .btn-ghost:hover:not(:disabled) { | |
| background: var(--bg-glass); | |
| border-color: var(--border-medium); | |
| color: var(--text-primary); | |
| } | |
| .btn-disabled { | |
| cursor: not-allowed; | |
| opacity: 0.4; | |
| transform: none ; | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 15. TYPOGRAPHY REFINEMENTS | |
| Better readability and hierarchy | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Text balancing for headings */ | |
| h1, | |
| h2, | |
| h3, | |
| h4, | |
| h5, | |
| h6 { | |
| text-wrap: balance; | |
| } | |
| /* Line height adjustments */ | |
| p { | |
| line-height: 1.6; | |
| } | |
| /* Selection styling β mono, matching the black/white identity (no legacy amber) */ | |
| ::selection { | |
| background: rgba(255, 255, 255, 0.18); | |
| color: var(--text-primary); | |
| } | |
| /* Focus visible for all elements */ | |
| *:focus-visible { | |
| outline: 2px solid var(--accent-primary); | |
| outline-offset: 2px; | |
| } | |
| /* Remove default focus outline when using mouse */ | |
| *:focus:not(:focus-visible) { | |
| outline: none; | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 16. Z-INDEX MANAGEMENT | |
| Consistent layering | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Base z-index scale */ | |
| .z-dropdown { | |
| z-index: 100; | |
| } | |
| .z-sticky { | |
| z-index: 200; | |
| } | |
| .z-fixed { | |
| z-index: 300; | |
| } | |
| .z-modal-backdrop { | |
| z-index: 400; | |
| } | |
| .z-modal { | |
| z-index: 500; | |
| } | |
| .z-popover { | |
| z-index: 600; | |
| } | |
| .z-tooltip { | |
| z-index: 700; | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 17. FORBIDDEN WORDS REPLACEMENT | |
| Replace technical terms with student-friendly language | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Hide raw technical error messages */ | |
| .error-message { | |
| color: var(--accent-red); | |
| font-size: 14px; | |
| } | |
| /* User-friendly error states */ | |
| .error-friendly { | |
| color: var(--text-secondary); | |
| background: var(--bg-elevated); | |
| border: 1px solid var(--border-subtle); | |
| padding: 12px 16px; | |
| border-radius: var(--radius-sm); | |
| } | |
| /* Loading messages */ | |
| .loading-message { | |
| color: var(--text-secondary); | |
| } | |
| /* Success states */ | |
| .success-message { | |
| color: var(--accent-emerald); | |
| background: rgba(16, 185, 129, 0.05); | |
| border: 1px solid rgba(16, 185, 129, 0.2); | |
| padding: 12px 16px; | |
| border-radius: var(--radius-sm); | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 18. RESPONSIVE TYPE SCALE | |
| Better mobile typography | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| @media (max-width: 768px) { | |
| html { | |
| font-size: 15px; | |
| } | |
| /* Better mobile touch targets */ | |
| .mobile-touch { | |
| min-height: 48px; | |
| padding: 12px 16px; | |
| } | |
| } | |
| /* | |
| * Mobile type defaults live in the base layer so any Tailwind utility on the | |
| * element wins. Unlayered, these element selectors silently beat every | |
| * text-* class on phones (cascade layers: unlayered > layered), flattening | |
| * all heading hierarchy across the whole app. | |
| */ | |
| @layer base { | |
| @media (max-width: 768px) { | |
| h1 { | |
| font-size: 28px; | |
| } | |
| h2 { | |
| font-size: 24px; | |
| } | |
| h3 { | |
| font-size: 20px; | |
| } | |
| p, | |
| li { | |
| font-size: 15px; | |
| line-height: 1.5; | |
| } | |
| } | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 19. SAFE AREA INSETS | |
| Proper mobile viewport handling | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Safe areas are applied on fixed chrome (bottom nav, drawers, composers). | |
| Do not pad the whole body β that fights fixed footers and double-counts | |
| insets on iOS. */ | |
| /* Full viewport height handling */ | |
| .min-h-svh { | |
| min-height: 100svh; | |
| } | |
| .min-h-dvh { | |
| min-height: 100dvh; | |
| } | |
| /* Mobile bottom navigation */ | |
| .mobile-nav { | |
| padding-bottom: calc(env(safe-area-inset-bottom) + 16px); | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| 20. PRINT STYLES | |
| Clean printing for study materials | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| @media print { | |
| .no-print { | |
| display: none ; | |
| } | |
| body { | |
| background: white; | |
| color: black; | |
| } | |
| .workspace-card, | |
| .premium-panel, | |
| .glass-panel { | |
| background: white; | |
| border: 1px solid #e5e7eb; | |
| box-shadow: none; | |
| } | |
| } | |
| /* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| StudyCast / Discuss player β transcript scroller polish | |
| Dedicated thin, high-quality scrollbar for the live highlighted transcript | |
| in the floating premium player (current things perfection). | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .custom-scroll { | |
| scrollbar-width: thin; | |
| scrollbar-color: rgba(255, 255, 255, 0.18) transparent; | |
| } | |
| .custom-scroll::-webkit-scrollbar { | |
| width: 5px; | |
| } | |
| .custom-scroll::-webkit-scrollbar-track { | |
| background: transparent; | |
| } | |
| .custom-scroll::-webkit-scrollbar-thumb { | |
| background: rgba(255, 255, 255, 0.15); | |
| border-radius: 4px; | |
| } | |
| .custom-scroll::-webkit-scrollbar-thumb:hover { | |
| background: rgba(255, 255, 255, 0.28); | |
| } | |