@import "tailwindcss"; /* FlatRender Hokm — "Persian Luxury" theme. Deep navy/teal table, gold filigree accents, geometric motifs. */ :root { --navy-950: #060c1f; --navy-900: #0a142e; --navy-800: #0e1c3f; --navy-700: #14274f; --teal-700: #0d6b6b; --teal-500: #14b8a6; --teal-400: #2dd4bf; --gold-600: #b8860b; --gold-500: #d4af37; --gold-400: #e6c659; --gold-300: #f1da8a; --cream: #f5ecd6; --background: var(--navy-950); --foreground: #eef2f8; } @theme inline { --color-navy-950: var(--navy-950); --color-navy-900: var(--navy-900); --color-navy-800: var(--navy-800); --color-navy-700: var(--navy-700); --color-teal-700: var(--teal-700); --color-teal-500: var(--teal-500); --color-teal-400: var(--teal-400); --color-gold-600: var(--gold-600); --color-gold-500: var(--gold-500); --color-gold-400: var(--gold-400); --color-gold-300: var(--gold-300); --color-cream: var(--cream); --font-sans: var(--font-vazir), var(--font-jakarta), system-ui, sans-serif; } :root { /* Self-hosted @fontsource families (see app/layout.tsx imports). */ --font-vazir: "Vazirmatn Variable", system-ui, sans-serif; --font-jakarta: "Plus Jakarta Sans Variable", system-ui, sans-serif; } /* Premium (pro) perk: animated shimmering chat bubble. */ @keyframes chatshimmer { 0% { background-position: 0% 50%; } 100% { background-position: 200% 50%; } } .premium-chat { background: linear-gradient(90deg, #d4af37, #ffe9a8, #d4af37, #ffe9a8); background-size: 200% 100%; animation: chatshimmer 3s linear infinite; color: #2a1f04; font-weight: 600; box-shadow: 0 0 10px rgba(212, 175, 55, 0.45); } /* Tactile "3D press" buttons (casual card-game feel) — a solid underside that compresses on tap. Pair with a bg/glass class for the face. */ .press-3d { box-shadow: 0 6px 0 0 rgba(0, 0, 0, 0.30), 0 8px 16px rgba(0, 0, 0, 0.28); transition: transform 0.08s ease, box-shadow 0.08s ease; } .press-3d:active { transform: translateY(4px); box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.30), 0 3px 8px rgba(0, 0, 0, 0.28); } @media (prefers-reduced-motion: reduce) { .press-3d, .press-3d:active { transition: none; transform: none; } } /* HUD text stays legible over the dynamic felt/table (game-ui best practice). */ .hud-shadow { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6), 0 0 6px rgba(0, 0, 0, 0.4); } /* Safe-area helpers for notch / home-indicator on phones. */ .safe-top { padding-top: max(0.75rem, env(safe-area-inset-top)); } .safe-bottom { padding-bottom: max(0.5rem, env(safe-area-inset-bottom)); } .safe-x { padding-left: max(0.75rem, env(safe-area-inset-left)); padding-right: max(0.75rem, env(safe-area-inset-right)); } html, body { height: 100%; overflow-x: hidden; overscroll-behavior: none; } body { background: radial-gradient(1200px 800px at 50% -10%, rgba(20, 184, 166, 0.12), transparent 60%), radial-gradient(900px 700px at 50% 120%, rgba(212, 175, 55, 0.08), transparent 55%), var(--navy-950); color: var(--foreground); font-family: var(--font-sans); -webkit-font-smoothing: antialiased; overflow: hidden; } /* Persian geometric motif — subtle tiled background */ .persian-pattern { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 80 80'%3E%3Cg fill='none' stroke='%23d4af37' stroke-opacity='0.06' stroke-width='1'%3E%3Cpath d='M40 0 L80 40 L40 80 L0 40 Z'/%3E%3Cpath d='M40 16 L64 40 L40 64 L16 40 Z'/%3E%3Ccircle cx='40' cy='40' r='6'/%3E%3C/g%3E%3C/svg%3E"); background-size: 80px 80px; } /* Felt table surface */ .felt { background: radial-gradient(ellipse at 50% 45%, rgba(45, 212, 191, 0.18), transparent 62%), radial-gradient(ellipse at 50% 50%, var(--teal-700) 0%, #0a3a3a 45%, #06201f 100%); box-shadow: inset 0 0 120px rgba(0, 0, 0, 0.55), inset 0 0 0 2px rgba(212, 175, 55, 0.25), 0 30px 80px rgba(0, 0, 0, 0.6); } .gold-text { background: linear-gradient(180deg, var(--gold-300), var(--gold-500) 55%, var(--gold-600)); -webkit-background-clip: text; background-clip: text; color: transparent; } .gold-border { border: 1px solid rgba(212, 175, 55, 0.45); } .glass { background: rgba(10, 20, 46, 0.72); backdrop-filter: blur(14px); border: 1px solid rgba(212, 175, 55, 0.18); } .btn-gold { background: linear-gradient(180deg, var(--gold-400), var(--gold-600)); color: #2a1f04; font-weight: 700; box-shadow: 0 8px 24px rgba(212, 175, 55, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.4); transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease; } .btn-gold:hover { transform: translateY(-1px); filter: brightness(1.05); box-shadow: 0 12px 30px rgba(212, 175, 55, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.5); } .btn-gold:active { transform: translateY(0); } /* Card face */ .card-face { background: linear-gradient(160deg, #fffdf7, #f3ead2); border: 1px solid rgba(0, 0, 0, 0.12); box-shadow: 0 6px 14px rgba(0, 0, 0, 0.35), inset 0 0 0 1px rgba(255, 255, 255, 0.6); } .card-back { background: repeating-linear-gradient(45deg, rgba(212, 175, 55, 0.22) 0 6px, transparent 6px 12px), linear-gradient(160deg, var(--navy-700), var(--navy-900)); border: 1px solid rgba(212, 175, 55, 0.45); box-shadow: 0 6px 14px rgba(0, 0, 0, 0.4), inset 0 0 0 2px rgba(212, 175, 55, 0.25); } ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-thumb { background: rgba(212, 175, 55, 0.3); border-radius: 8px; } [dir="rtl"] { font-family: var(--font-vazir), system-ui, sans-serif; } @keyframes float-up { from { transform: translateY(110vh); } to { transform: translateY(-20vh); } } .float-suit { animation-name: float-up; animation-timing-function: linear; animation-iteration-count: infinite; } @media (prefers-reduced-motion: reduce) { .float-suit { animation: none; display: none; } } /* ── Game-table UNO animations ──────────────────────────────────────── */ /* Floating coin for win celebrations */ @keyframes coin-rise { 0% { transform: translateY(0) rotate(0deg) scale(1); opacity: 1; } 80% { opacity: 0.8; } 100% { transform: translateY(-190px) rotate(520deg) scale(0.3); opacity: 0; } } /* Playable card glow pulse */ @keyframes playable-glow { 0%, 100% { box-shadow: 0 8px 18px rgba(0,0,0,0.4), 0 0 0 2px rgba(212,175,55,0.7), 0 0 14px rgba(212,175,55,0.3); } 50% { box-shadow: 0 10px 22px rgba(0,0,0,0.5), 0 0 0 3px rgba(212,175,55,1), 0 0 30px rgba(212,175,55,0.65); } } .card-playable { animation: playable-glow 1.15s ease-in-out infinite; } /* Active-player avatar ring pulse */ @keyframes player-glow { 0%, 100% { box-shadow: 0 0 0 3px rgba(212,175,55,0.9), 0 0 18px rgba(212,175,55,0.4); } 50% { box-shadow: 0 0 0 5px rgba(212,175,55,1), 0 0 40px rgba(212,175,55,0.75); } } .active-player-ring { animation: player-glow 1.4s ease-in-out infinite; } /* Turn-indicator "YOUR TURN" pill bounce */ @keyframes your-turn-bounce { 0%, 100% { transform: translateX(-50%) scale(1); } 50% { transform: translateX(-50%) scale(1.06); } } /* Confetti fall */ @keyframes confetti-fall { 0% { transform: translateY(0) rotate(0deg); opacity: 1; } 100% { transform: translateY(140px) rotate(400deg); opacity: 0; } } /* XP bar fill */ @keyframes xp-fill { from { width: 0%; } } .xp-bar-fill { animation: xp-fill 1.1s ease-out forwards; } /* ── Accessibility / input ─────────────────────────────────────────── */ /* Visible focus ring for keyboard / controller / switch navigation. Only shows for keyboard-style focus (:focus-visible), never on mouse/touch tap — so it stays invisible during normal play but makes the app fully navigable without a pointer (game-ui-design: controller-first, no navigation dead-ends). */ :focus-visible { outline: 2px solid var(--gold-400); outline-offset: 2px; border-radius: 6px; } /* Inputs already show a gold ring on focus; avoid doubling it up. */ input:focus-visible, textarea:focus-visible { outline: none; } /* Minimum comfortable tap target (Apple 44pt / Google 48dp). Pair with a centering grid so a small icon still gets a big, reliable hit area. */ .tap { min-width: 44px; min-height: 44px; } /* Honor the OS "reduce motion" setting across the whole app. Decorative game motion (coin rain, confetti, pulsing glows, count-ups) is neutralized to near- instant, and the always-pulsing HUD loops are stopped outright. Functional state changes still happen — they just snap instead of animating. (game-ui-design: motion-sickness-trigger is a high-severity accessibility issue.) */ @media (prefers-reduced-motion: reduce) { .card-playable, .active-player-ring, .float-suit { animation: none !important; } .float-suit { display: none; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } }