/* app.css - Design System Premium untuk SpeedTest */ /* Impor font Roboto asli proyek */ @font-face { font-family: "Roboto"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/roboto-v30-latin-regular.eot"); src: local(""), url("../fonts/roboto-v30-latin-regular.eot?#iefix") format("embedded-opentype"), url("../fonts/roboto-v30-latin-regular.woff2") format("woff2"), url("../fonts/roboto-v30-latin-regular.woff") format("woff"), url("../fonts/roboto-v30-latin-regular.ttf") format("truetype"), url("../fonts/roboto-v30-latin-regular.svg#Roboto") format("svg"); } @font-face { font-family: "Roboto"; font-style: normal; font-weight: 500; font-display: swap; src: url("assets/fonts/roboto-v30-latin-500.eot"); src: local(""), url("assets/fonts/roboto-v30-latin-500.eot?#iefix") format("embedded-opentype"), url("assets/fonts/roboto-v30-latin-500.woff2") format("woff2"), url("assets/fonts/roboto-v30-latin-500.woff") format("woff"), url("assets/fonts/roboto-v30-latin-500.ttf") format("truetype"), url("assets/fonts/roboto-v30-latin-500.svg#Roboto") format("svg"); } html, body { margin: 0; padding: 0; width: 100%; height: 100%; font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: radial-gradient(circle at 50% 50%, #F8FAFC 0%, #E2E8F0 100%); display: flex; justify-content: center; align-items: center; overflow: hidden; transition: background 0.4s ease; } ::-webkit-scrollbar { display: none; } html { -ms-overflow-style: none; scrollbar-width: none; } /* Container Utama */ .app-layout { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; max-width: 960px; padding: 24px; box-sizing: border-box; gap: 24px; } /* Header Dashboard */ .app-header { display: flex; align-items: center; gap: 16px; animation: fadeInDown 0.6s cubic-bezier(0.16, 1, 0.3, 1) both; } .header-logo-img { width: 40px; height: 40px; object-fit: contain; filter: drop-shadow(0 4px 12px rgba(79, 172, 254, 0.3)); } .header-text { display: flex; align-items: center; gap: 10px; } .header-text h1 { margin: 0; font-family: 'Outfit', sans-serif; font-size: 24px; font-weight: 800; letter-spacing: -0.02em; color: #0F172A; } .header-badge { font-family: 'Inter', sans-serif; font-size: 11px; font-weight: 600; color: #2563EB; background: rgba(37, 99, 235, 0.08); padding: 4px 10px; border-radius: 12px; border: 1px solid rgba(37, 99, 235, 0.15); text-transform: uppercase; letter-spacing: 0.03em; margin-top: 4px; } .client-ip-container { position: absolute; top: 20px; left: calc(50% - 150px); transform: translateX(-50%); display: flex; justify-content: center; align-items: center; gap: 6px; font-family: 'Inter', sans-serif; font-size: 13px; font-weight: 500; color: #64748B; z-index: 20; pointer-events: none; white-space: nowrap; transition: all 0.3s ease; } @media only screen and (orientation: portrait) { .client-ip-container { left: 50%; top: 12px; } } .client-ip-container span#client-ip-text { color: #0EA5E9; font-weight: 700; } /* Card Wrapper Speed Test */ .app-card { position: relative; width: 100%; background: rgba(255, 255, 255, 0.7); backdrop-filter: blur(24px) saturate(180%); -webkit-backdrop-filter: blur(24px) saturate(180%); border: 1px solid rgba(255, 255, 255, 0.4); border-radius: 32px; box-shadow: 0 20px 40px -15px rgba(15, 23, 42, 0.05), 0 0 80px rgba(15, 23, 42, 0.02), inset 0 1px 0 rgba(255, 255, 255, 0.6); padding: 40px; box-sizing: border-box; display: flex; justify-content: center; align-items: center; transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1); animation: scaleIn 0.8s cubic-bezier(0.16, 1, 0.3, 1) both; } .app-card:hover { transform: translateY(-4px); box-shadow: 0 30px 60px -20px rgba(15, 23, 42, 0.08), 0 0 100px rgba(15, 23, 42, 0.03), inset 0 1px 0 rgba(255, 255, 255, 0.8); border-color: rgba(255, 255, 255, 0.6); } /* SVG App Sizing */ .openSpeedtestApp { width: 100%; max-width: 600px; height: auto; aspect-ratio: 586 / 346; display: none; overflow: hidden; } /* Spinner Loader */ .spinner { position: absolute; display: flex; gap: 8px; justify-content: center; align-items: center; z-index: 99; } .spinner>div { width: 12px; height: 12px; background: linear-gradient(135deg, #00F2FE 0%, #4FACFE 100%); border-radius: 50%; animation: bounceDelay 1.4s infinite ease-in-out both; } .spinner .bounce1 { animation-delay: -0.32s; } .spinner .bounce2 { animation-delay: -0.16s; } /* ========================================== KONTROL TAMPILAN ELEMENT (PENTING!) Menyembunyikan komponen SVG secara default agar tidak bertumpuk. ========================================== */ #UI-Desk { display: none; } #UI-Mob { display: none; } #ipMob { display: none; } #ipDesk { display: none; } #upSymbolDesk { display: none; } #downSymbolDesk { display: none; } #upSymbolMob { display: none; } #downSymbolMob { display: none; } .ConnectError { display: none; } /* ========================================== TYPOGRAPHY DI DALAM SVG (ASLI ROBOTO) Menggunakan font-family dan ukuran asli agar layout & koordinat SVG tidak berantakan ========================================== */ .oDoLive-Speed { font-family: 'Roboto', sans-serif !important; font-size: 20px !important; font-weight: 500 !important; fill: #500516 !important; text-anchor: middle !important; } .oDoLive-Status { font-family: 'Roboto', sans-serif !important; font-size: 10px !important; font-weight: 500 !important; fill: #94A3B8 !important; text-anchor: middle !important; } .rtextnum { font-family: 'Roboto', sans-serif !important; font-size: 23px !important; font-weight: 500 !important; fill: #0F172A !important; text-anchor: middle !important; } .rtext { font-family: 'Roboto', sans-serif !important; font-size: 10px !important; font-weight: 400 !important; fill: #64748B !important; } .rtextmbms { font-family: 'Roboto', sans-serif !important; font-size: 12px !important; font-weight: 500 !important; fill: #94A3B8 !important; text-anchor: middle !important; } .oDo-Meter { font-family: 'Roboto', sans-serif !important; font-size: 16.63px !important; font-weight: 500 !important; fill: #94A3B8 !important; } .oDoTop-Speed { font-family: 'Roboto', sans-serif !important; font-size: 16.96px !important; font-weight: 500 !important; fill: #94A3B8 !important; text-anchor: end !important; } .jitter-Mob { font-family: 'Roboto', sans-serif !important; font-size: 9px !important; font-weight: 500 !important; fill: #64748B !important; text-anchor: middle !important; } .buttonTxt { font-family: 'Roboto', sans-serif !important; font-size: 40px !important; font-weight: 500 !important; fill: #ffffff !important; text-anchor: middle !important; } /* ========================================== ESTETIKA DAN DESAIN ELEMEN SVG ========================================== */ .Cards { fill: rgba(248, 250, 252, 0.8) !important; stroke: rgba(226, 232, 240, 0.8) !important; stroke-width: 1.5px !important; transition: all 0.3s ease; } .uiBg { fill: #94A3B8 !important; } .Symbol { fill: url(#gradient) !important; } .progressbg { stroke: #E2E8F0 !important; stroke-width: 8px !important; stroke-linecap: round !important; stroke-linejoin: round !important; stroke-dasharray: 400 !important; stroke-dashoffset: 0; } .intro-Progress { stroke: #4FACFE !important; stroke-width: 8px !important; stroke-linecap: round !important; stroke-linejoin: round !important; stroke-dasharray: 400 !important; stroke-dashoffset: 0; } .progressElmstart { stroke: #4FACFE !important; stroke-width: 8px !important; stroke-linecap: round !important; stroke-linejoin: round !important; stroke-dasharray: 400 !important; stroke-dashoffset: 0; display: block !important; } .main-Gaugebg { fill: none !important; stroke: #E2E8F0 !important; stroke-linecap: round !important; stroke-linejoin: round !important; stroke-width: 22px !important; stroke-dasharray: 681 !important; } .main-GaugeBlue { fill: none !important; stroke: url(#gradient) !important; stroke-linecap: round !important; stroke-linejoin: round !important; stroke-width: 22px !important; stroke-dasharray: 681 !important; stroke-opacity: 0; } .main-GaugeWhite { fill: none !important; stroke: rgb(255, 255, 255) !important; stroke-linecap: round !important; stroke-linejoin: round !important; stroke-width: 15px !important; stroke-dasharray: 0, 681 !important; stroke-dashoffset: 1; stroke-opacity: 0; } .deskStart { fill: none !important; stroke: url(#gradient) !important; stroke-linecap: round !important; stroke-linejoin: round !important; stroke-dasharray: 681 !important; } /* Button & Interactive elements */ .startButton { fill: url(#gradient) !important; cursor: pointer; filter: drop-shadow(0 8px 20px rgba(0, 242, 254, 0.25)); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transform-box: fill-box; transform-origin: center; } .startButton:hover { filter: drop-shadow(0 12px 28px rgba(0, 242, 254, 0.45)); opacity: 0.95; transform: scale(1.02); } .startButton:active { transform: scale(0.98); } .Startsettings { cursor: pointer; opacity: 0.3; transition: all 0.3s ease; transform-box: fill-box; transform-origin: center; } .Startsettings:hover { opacity: 0.9; transform: rotate(30deg); } /* Restyle logo di SVG menggunakan CSS */ svg [style*="fill: #3da6ff"] { fill: #2563EB !important; /* Modern Royal Blue */ } svg [style*="fill: #4d4d4d"] { fill: #0F172A !important; /* Slate 900 */ } /* Dark mode toggle */ .darkmode { fill: #94A3B8 !important; transition: all 0.3s ease; transform-box: fill-box; transform-origin: center; } .darkmode:hover { fill: #2563EB !important; transform: scale(1.1); } #daymode { margin-right: 40px; } /* Footer & Credits */ .Credits { margin-top: 10px; text-align: center; font-family: 'Inter', sans-serif; font-size: 13px; color: #64748B; animation: fadeInUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) both; animation-delay: 0.2s; } .Credits p { margin: 4px 0; } .Credits a { text-decoration: none; color: #2563EB; font-weight: 600; transition: color 0.2s ease; } .Credits a:hover { color: #1d4ed8; } .copyright { font-size: 11px; color: #94A3B8; } /* Media Queries Responsif */ .Mobile, .Desktop { visibility: hidden; width: 100vw; height: 100vh; } @media only screen and (orientation: landscape) { .Mobile { visibility: hidden; display: none; } .Desktop { visibility: visible; display: block; } } @media only screen and (orientation: portrait) { .app-card { padding: 24px; border-radius: 24px; } .openSpeedtestApp { width: 100%; max-width: 320px; aspect-ratio: 295.9 / 363.3; } .Mobile { visibility: visible; display: block; } .Desktop { visibility: hidden; display: none; } } @media only screen and (max-width: 360px) { .Credits { display: none; } } /* Animasi */ @keyframes bounceDelay { 0%, 80%, 100% { transform: scale(0); opacity: 0.3; } 40% { transform: scale(1.0); opacity: 1; } } @keyframes fadeInDown { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes scaleIn { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } } /* Tombol Refresh / Uji Lagi */ .refresh-btn { display: none; /* Disembunyikan secara default */ background: linear-gradient(135deg, #00F2FE 0%, #4FACFE 100%); color: white; border: none; padding: 12px 28px; font-family: 'Outfit', 'Inter', sans-serif; font-size: 15px; font-weight: 700; border-radius: 50px; cursor: pointer; box-shadow: 0 8px 20px rgba(0, 242, 254, 0.25); align-items: center; gap: 10px; z-index: 10; margin-top: 10px; margin-bottom: -6px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); animation: fadeInUp 0.4s cubic-bezier(0.16, 1, 0.3, 1) both; } .refresh-btn:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(0, 242, 254, 0.45); filter: brightness(1.05); } .refresh-btn:active { transform: translateY(0); } .refresh-btn svg { transition: transform 0.4s ease; } .refresh-btn:hover svg { transform: rotate(180deg); }