ڈیش بورڈ
0
0
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title></title> | |
| <meta charset="utf-8" /> | |
| <script src="Scripts/jquery-1.9.1.min.js"></script> | |
| <link href="Content/bootstrap.min.css" rel="stylesheet" /> | |
| <script src="Scripts/isRockFx.js"></script> | |
| <script> | |
| $(function () { | |
| $('#ButtonCal').click( | |
| function () { | |
| //取得用戶輸入的參數 | |
| var para = { 'height': $('#txbHeight').val(), 'weight': $('#txbWeight').val() }; | |
| //呼叫API | |
| ExecuteAPI('Example', 'BMI', para, | |
| //呼叫WebAPI成功時運行的Call Back Function | |
| function (result) { | |
| alert(result.Data); | |
| } | |
| ); | |
| } | |
| ); | |
| }); | |
| </script> | |
| </head> | |
| <body> | |
| <div class="row" style="margin:10px"> | |
| <div class="col-md-12"> | |
| <div class="form-group"> | |
| 身高: | |
| <input id="txbHeight" class="form-control" placeholder="請輸入身高" /> | |
| 體重: | |
| <input id="txbWeight" class="form-control" placeholder="請輸入體重" /> | |
| <br /> | |
| <button class="btn btn-primary" id="ButtonCal">計算</button> | |
| </div> | |
| </div> | |
| </div> | |
| </body> | |
| </html> |
<title>Ware Studio — Professional Online Mixing & Mastering</title> ``` <script src="https://unpkg.com/feather-icons"></script> <style> /* ========================================================================== 1. CSS VARIABLES & RESET ========================================================================== */ :root { --bg-color: #0B0B0C; --card-bg: #141416; --card-border: rgba(255, 255, 255, 0.07); --accent: #4F7CFF; --accent-glow: rgba(79, 124, 255, 0.25); --text-main: #FFFFFF; --text-muted: #9CA3AF; --font-title: 'Space Grotesk', sans-serif; --font-body: 'Inter', sans-serif; --container-width: 1140px; --transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1); } *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { scroll-behavior: smooth; background-color: var(--bg-color); color: var(--text-main); font-family: var(--font-body); line-height: 1.6; overflow-x: hidden; } /* Typography */ h1, h2, h3, h4, .font-title { font-family: var(--font-title); color: var(--text-main); letter-spacing: -0.02em; } p { color: var(--text-muted); } a { color: inherit; text-decoration: none; transition: var(--transition); } /* Layout Utility */ .container { max-width: var(--container-width); margin: 0 auto; padding: 0 24px; } section { padding: 120px 0; position: relative; } .section-header { text-align: center; max-width: 600px; margin: 0 auto 64px auto; } .section-header h2 { font-size: 2.5rem; margin-bottom: 12px; } /* Buttons */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 14px 28px; border-radius: 8px; font-family: var(--font-title); font-weight: 600; font-size: 0.95rem; cursor: pointer; transition: var(--transition); border: 1px solid transparent; } .btn-primary { background-color: var(--accent); color: #fff; box-shadow: 0 0 20px var(--accent-glow); } .btn-primary:hover { transform: translateY(-2px); box-shadow: 0 0 30px rgba(79, 124, 255, 0.45); } .btn-secondary { background: rgba(255, 255, 255, 0.05); color: var(--text-main); border: 1px solid var(--card-border); } .btn-secondary:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.2); transform: translateY(-2px); } /* Cards with Hover Lift */ .card { background-color: var(--card-bg); border: 1px solid var(--card-border); border-radius: 16px; padding: 32px; transition: var(--transition); } .card:hover { transform: translateY(-6px); border-color: rgba(79, 124, 255, 0.4); box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5); } /* Scroll Animations */ .fade-in { opacity: 0; transform: translateY(20px); transition: opacity 0.8s ease, transform 0.8s ease; } .fade-in.visible { opacity: 1; transform: translateY(0); } /* ========================================================================== 2. NAVBAR ========================================================================== */ .navbar { position: fixed; top: 0; left: 0; width: 100%; z-index: 1000; padding: 20px 0; transition: var(--transition); } .navbar.scrolled { background: rgba(11, 11, 12, 0.85); backdrop-filter: blur(12px); border-bottom: 1px solid var(--card-border); padding: 14px 0; } .nav-container { display: flex; justify-content: space-between; align-items: center; } .logo { font-family: var(--font-title); font-weight: 700; font-size: 1.25rem; letter-spacing: 1px; } .logo span { color: var(--accent); } .nav-links { display: flex; gap: 32px; list-style: none; } .nav-links a { font-size: 0.9rem; color: var(--text-muted); } .nav-links a:hover { color: var(--text-main); } /* Mobile Nav Toggle */ .menu-toggle { display: none; background: none; border: none; color: var(--text-main); cursor: pointer; } /* ========================================================================== 3. HERO SECTION ========================================================================== */ .hero { min-height: 100vh; display: flex; align-items: center; justify-content: center; text-align: center; position: relative; padding-top: 100px; } /* Ambient Glow Effect */ .hero-glow { position: absolute; top: 30%; left: 50%; transform: translate(-50%, -50%); width: 500px; height: 500px; background: radial-gradient(circle, var(--accent-glow) 0%, rgba(11,11,12,0) 70%); filter: blur(80px); z-index: -1; pointer-events: none; } .hero-content { max-width: 800px; } .hero-subtitle { text-transform: uppercase; font-size: 0.85rem; letter-spacing: 3px; color: var(--accent); font-weight: 600; margin-bottom: 16px; } .hero-title { font-size: clamp(2.8rem, 6vw, 4.5rem); line-height: 1.1; margin-bottom: 24px; } .hero-desc { font-size: 1.2rem; max-width: 540px; margin: 0 auto 40px auto; } .scroll-indicator { position: absolute; bottom: 40px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text-muted); animation: bounce 2s infinite; } @Keyframes bounce { 0%, 20%, 50%, 80%, 100% { transform: translate(-50%, 0); } 40% { transform: translate(-50%, -8px); } 60% { transform: translate(-50%, -4px); } } /* ========================================================================== 4. SERVICES ========================================================================== */ .services-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; } .service-icon { font-size: 2rem; margin-bottom: 20px; display: inline-block; } .service-card h3 { font-size: 1.3rem; margin-bottom: 12px; } /* ========================================================================== 5. WHY CHOOSE US ========================================================================== */ .why-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; } .why-item { display: flex; align-items: center; gap: 16px; background: var(--card-bg); border: 1px solid var(--card-border); padding: 20px 24px; border-radius: 12px; } .why-icon { color: var(--accent); display: flex; align-items: center; justify-content: center; } .why-item span { font-weight: 500; font-size: 1.05rem; } /* ========================================================================== 6. WORKFLOW ========================================================================== */ .workflow-steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 24px; position: relative; } .step-card { text-align: center; position: relative; } .step-number { font-family: var(--font-title); font-size: 3rem; font-weight: 700; color: rgba(255, 255, 255, 0.1); margin-bottom: -20px; } .step-card h3 { font-size: 1.2rem; margin-top: 10px; } /* ========================================================================== 7. PORTFOLIO & AUDIO PLAYER ========================================================================== */ .portfolio-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 32px; } .portfolio-card { background: var(--card-bg); border: 1px solid var(--card-border); border-radius: 16px; overflow: hidden; display: flex; flex-direction: column; } .portfolio-cover { position: relative; width: 100%; height: 220px; background-size: cover; background-position: center; } .portfolio-overlay { position: absolute; inset: 0; background: rgba(11, 11, 12, 0.6); display: flex; align-items: center; justify-content: center; gap: 16px; opacity: 0; transition: var(--transition); } .portfolio-card:hover .portfolio-overlay { opacity: 1; } .icon-btn { width: 44px; height: 44px; border-radius: 50%; background: var(--text-main); color: var(--bg-color); display: flex; align-items: center; justify-content: center; transition: var(--transition); } .icon-btn:hover { transform: scale(1.1); background: var(--accent); color: #fff; } .portfolio-info { padding: 24px; flex-grow: 1; display: flex; flex-direction: column; justify-content: space-between; } .audio-player-widget { margin-top: 16px; background: rgba(0,0,0,0.3); padding: 12px; border-radius: 8px; border: 1px solid var(--card-border); } .player-controls { display: flex; align-items: center; gap: 12px; } .play-btn { background: var(--accent); border: none; color: white; width: 36px; height: 36px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; } .progress-bar { flex-grow: 1; height: 4px; background: rgba(255,255,255,0.1); border-radius: 2px; overflow: hidden; cursor: pointer; } .progress-fill { width: 0%; height: 100%; background: var(--accent); } /* ========================================================================== 8. TESTIMONIALS ========================================================================== */ .testimonials-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; } .stars { color: #FFB800; margin-bottom: 12px; display: flex; gap: 4px; } .client-info { margin-top: 20px; display: flex; align-items: center; gap: 12px; } .client-avatar { width: 40px; height: 40px; border-radius: 50%; background: #333; } .client-details h4 { font-size: 0.95rem; } .client-details p { font-size: 0.8rem; } /* ========================================================================== 9. FAQ ========================================================================== */ .faq-list { max-width: 760px; margin: 0 auto; display: flex; flex-direction: column; gap: 16px; } .faq-item { background: var(--card-bg); border: 1px solid var(--card-border); border-radius: 12px; overflow: hidden; } .faq-question { width: 100%; padding: 20px 24px; background: none; border: none; color: var(--text-main); font-family: var(--font-title); font-size: 1.1rem; text-align: left; display: flex; justify-content: space-between; align-items: center; cursor: pointer; } .faq-answer { padding: 0 24px 20px 24px; display: none; color: var(--text-muted); font-size: 0.95rem; } .faq-item.active .faq-answer { display: block; } .faq-item.active .faq-icon { transform: rotate(180deg); } /* ========================================================================== 10. CONTACT & BOOKING FORM ========================================================================== */ .contact-container { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: start; } .contact-info h3 { font-size: 2rem; margin-bottom: 16px; } .social-links { display: flex; gap: 16px; margin-top: 24px; } .booking-form { display: flex; flex-direction: column; gap: 16px; } .form-group { display: flex; flex-direction: column; gap: 8px; } .form-group label { font-size: 0.85rem; color: var(--text-muted); } .form-group input, .form-group select, .form-group textarea { background: rgba(255, 255, 255, 0.03); border: 1px solid var(--card-border); padding: 12px 16px; border-radius: 8px; color: var(--text-main); font-family: var(--font-body); outline: none; transition: var(--transition); } .form-group input:focus, .form-group select:focus, .form-group textarea:focus { border-color: var(--accent); background: rgba(255, 255, 255, 0.05); } /* Floating WhatsApp Button */ .whatsapp-float { position: fixed; bottom: 24px; right: 24px; width: 56px; height: 56px; background-color: #25D366; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 20px rgba(37, 211, 102, 0.4); z-index: 999; transition: var(--transition); } .whatsapp-float:hover { transform: scale(1.1); } /* ========================================================================== 11. FOOTER ========================================================================== */ footer { border-top: 1px solid var(--card-border); padding: 60px 0 30px 0; background: #070708; } .footer-content { display: flex; justify-content: space-between; align-items: center; margin-bottom: 40px; flex-wrap: wrap; gap: 24px; } .footer-bottom { text-align: center; padding-top: 24px; border-top: 1px solid rgba(255,255,255,0.05); font-size: 0.85rem; } /* ========================================================================== 12. RESPONSIVE DESIGN ========================================================================== */ @media (max-width: 768px) { section { padding: 80px 0; } .nav-links { display: none; } /* Add JS toggle for mobile menu if needed */ .contact-container { grid-template-columns: 1fr; } .hero-title { font-size: 2.5rem; } } </style>Ware Studio
Professional Online
Mixing & MasteringWe help artists achieve clean, powerful and release-ready sound.
ScrollOur Services
Tailored audio post-production services for modern music producers and independent artists.
🎚Mixing
Balanced, wide and professional mix. Bringing clarity, depth, and character to your multi-track recordings.
🎧Mastering
Loudness optimized for every streaming platform (Spotify, Apple Music, Tidal) without sacrificing dynamics.
✂Audio Editing
Vocal tuning (Auto-Tune/Melodyne), timing correction, background noise cleanup, and seamless audio alignment.
Why Ware Studio
Designed to provide a seamless, hassle-free remote studio experience.
Streaming ReadyProfessional QualityFast TurnaroundUnlimited CommunicationSecure File DeliveryWorldwide Online ServiceSimple Workflow
How we bring your music from raw tracks to a polished master in 4 simple steps.
01Upload Stems
Export your uncompressed audio files and send them securely.
02Mixing Process
We shape your sound using modern analog-modeled tools.
03Review
Listen to the first draft and request tweaks if needed.
04Final Delivery
Receive high-resolution WAV files optimized for streaming.
Featured Work
Listen to recent tracks mixed and mastered by Ware Studio.
<!-- Track Item 1 --> <div class="portfolio-card fade-in"> <div class="portfolio-cover" style="background-image: url('https://images.unsplash.com/photo-1511671782779-c97d3d27a1d4?auto=format&fit=crop&w=600&q=80');"> <div class="portfolio-overlay"> <a href="https://spotify.com" target="_blank" class="icon-btn" aria-label="Listen on Spotify"><i data-feather="music"></i></a> <a href="https://youtube.com" target="_blank" class="icon-btn" aria-label="Watch on YouTube"><i data-feather="youtube"></i></a> </div> </div> <div class="portfolio-info"> <div> <h3>Neon Lights</h3> <p style="font-size: 0.85rem;">Artist Name • Synthwave / Pop</p> </div> <div class="audio-player-widget"> <div class="player-controls"> <button class="play-btn" onclick="togglePlay(this, 'audio1')"><i data-feather="play"></i></button> <div class="progress-bar" onclick="seek(event, 'audio1')"><div class="progress-fill" id="fill-audio1"></div></div> </div> <audio id="audio1" src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"></audio> </div> </div> </div> <!-- Track Item 2 --> <div class="portfolio-card fade-in"> <div class="portfolio-cover" style="background-image: url('https://images.unsplash.com/photo-1470225620780-dba8ba36b745?auto=format&fit=crop&w=600&q=80');"> <div class="portfolio-overlay"> <a href="https://spotify.com" target="_blank" class="icon-btn" aria-label="Listen on Spotify"><i data-feather="music"></i></a> <a href="https://youtube.com" target="_blank" class="icon-btn" aria-label="Watch on YouTube"><i data-feather="youtube"></i></a> </div> </div> <div class="portfolio-info"> <div> <h3>Midnight Echoes</h3> <p style="font-size: 0.85rem;">Artist Name • Alternative Rock</p> </div> <div class="audio-player-widget"> <div class="player-controls"> <button class="play-btn" onclick="togglePlay(this, 'audio2')"><i data-feather="play"></i></button> <div class="progress-bar" onclick="seek(event, 'audio2')"><div class="progress-fill" id="fill-audio2"></div></div> </div> <audio id="audio2" src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"></audio> </div> </div> </div> </div> </div>What Artists Say
Trusted by musicians and producers around the globe.
★★★★★"Ware Studio completely transformed my raw mix into a commercial masterpiece. The low end is tight and punchy!"
Sarah Jenkins
Indie Singer-Songwriter
<div class="card fade-in"> <div class="stars">★★★★★</div> <p>"Fast turnaround, incredible communication, and the mastering level was spot on for Spotify. Highly recommended."</p> <div class="client-info"> <div class="client-avatar" style="background-image: url('https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=100&q=80'); background-size: cover;"></div> <div class="client-details"> <h4>David K.</h4> <p>Electronic Music Producer</p> </div> </div> </div> </div> </div>Frequently Asked Questions
How do I prepare my files for mixing?Export your tracks as 24-bit or 32-bit float WAV/AIFF files without clipping. Make sure to turn off master bus effects and keep all track names organized.How many revisions do I get?We offer unlimited revisions within reason until you are 100% satisfied with the sound.What is the standard turnaround time?Typically, a single mix draft takes 3 to 5 business days. Mastering takes 1 to 2 business days. Express delivery options are available upon request.<script> // Initialize Feather Icons feather.replace(); // Navbar Scroll Effect const navbar = document.getElementById('navbar'); window.addEventListener('scroll', () => { if (window.scrollY > 50) { navbar.classList.add('scrolled'); } else { navbar.classList.remove('scrolled'); } }); // Intersection Observer for Scroll Fade-In Animations const observerOptions = { threshold: 0.1 }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); } }); }, observerOptions); document.querySelectorAll('.fade-in').forEach(el => observer.observe(el)); // Accordion FAQ Toggle document.querySelectorAll('.faq-question').forEach(button => { button.addEventListener('click', () => { const faqItem = button.parentElement; faqItem.classList.toggle('active'); }); }); // Custom Audio Player Functionality let currentAudio = null; let currentBtn = null; function togglePlay(btn, audioId) { const audio = document.getElementById(audioId); if (currentAudio && currentAudio !== audio) { currentAudio.pause(); if (currentBtn) currentBtn.innerHTML = ''; } if (audio.paused) { audio.play(); btn.innerHTML = ''; currentAudio = audio; currentBtn = btn; } else { audio.pause(); btn.innerHTML = ''; } feather.replace(); audio.ontimeupdate = () => { const progress = (audio.currentTime / audio.duration) * 100; document.getElementById(`fill-${audioId}`).style.width = `${progress}%`; }; } function seek(event, audioId) { const audio = document.getElementById(audioId); const progressBar = event.currentTarget; const clickPosition = (event.clientX - progressBar.getBoundingClientRect().left) / progressBar.offsetWidth; audio.currentTime = clickPosition * audio.duration; } // Form Submit Demo function handleFormSubmit(e) { Ready to Start Your Project?
Let's take your music sound to the next level. Fill out the form or reach out directly via messaging.
<form class="booking-form" onsubmit="handleFormSubmit(event)"> <div class="form-group"> <label for="name">Your Name</label> <input type="text" id="name" required placeholder="John Doe"> </div> <div class="form-group"> <label for="email">Email Address</label> <input type="email" id="email" required placeholder="john@example.com"> </div> <div class="form-group"> <label for="service">Service Needed</label> <select id="service" style="color: var(--text-main);"> <option style="background: var(--card-bg);" value="mixing-mastering">Mixing & Mastering</option> <option style="background: var(--card-bg);" value="mixing">Mixing Only</option> <option style="background: var(--card-bg);" value="mastering">Mastering Only</option> <option style="background: var(--card-bg);" value="editing">Audio Editing / Vocal Tuning</option> </select> </div> <div class="form-group"> <label for="message">Project Details / Link to Demo</label> <textarea id="message" rows="4" placeholder="Tell us about your project..."></textarea> </div> <button type="submit" class="btn btn-primary" style="width: 100%;">Book Now</button> </form> </div> </div>
e.preventDefault();
</script> ```alert('Thank you! Your project request has been sent. We will get back to you shortly.'); }
Sorry, something went wrong.
Buatlah aplikasi ai yang menghasilkan video modal ketik dan ide
body {
background-color: #0f172a;
color: #f8fafc;
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden;
}
header {
background-color: #1e293b;
padding: 15px 20px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #334155;
}
.logo {
font-size: 1.5rem;
font-weight: bold;
color: #38bdf8;
display: flex;
align-items: center;
gap: 8px;
}
.badge {
background-color: #22c55e;
color: #000;
font-size: 0.75rem;
padding: 3px 8px;
border-radius: 12px;
font-weight: bold;
}
.main-container {
display: flex;
flex: 1;
height: calc(100vh - 65px);
}
/* Sidebar Control Panel */
.control-panel {
width: 350px;
background-color: #1e293b;
padding: 20px;
display: flex;
flex-direction: column;
gap: 15px;
border-right: 1px solid #334155;
overflow-y: auto;
}
label {
font-size: 0.9rem;
color: #94a3b8;
}
textarea {
width: 100%;
height: 120px;
background-color: #0f172a;
border: 1px solid #475569;
border-radius: 8px;
padding: 12px;
color: #fff;
font-size: 0.95rem;
resize: none;
outline: none;
}
textarea:focus {
border-color: #38bdf8;
}
button.btn-generate {
background-color: #0284c7;
color: white;
border: none;
padding: 12px;
border-radius: 8px;
font-weight: bold;
cursor: pointer;
transition: background 0.2s;
}
button.btn-generate:hover {
background-color: #0369a1;
}
.presets {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 10px;
}
.preset-btn {
background-color: #334155;
border: none;
color: #e2e8f0;
padding: 8px 12px;
border-radius: 6px;
text-align: left;
font-size: 0.85rem;
cursor: pointer;
transition: background 0.2s;
}
.preset-btn:hover {
background-color: #475569;
}
/* Area Preview Apps/Game */
.preview-panel {
flex: 1;
background-color: #020617;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
}
iframe {
width: 100%;
height: 100%;
border: none;
background-color: #ffffff;
}
.placeholder-text {
color: #64748b;
text-align: center;
}
@media (max-width: 768px) {
.main-container {
flex-direction: column;
}
.control-panel {
width: 100%;
height: auto;
}
}
</style>
<button class="btn-generate" onclick="generateApp()">✨ Buat Aplikasi Sekarang</button>
<div>
<label>Coba Contoh Ide Instan:</label>
<div class="presets">
<button class="preset-btn" onclick="usePreset('game-tebak')">🎮 Game Tebak Angka Neon</button>
<button class="preset-btn" onclick="usePreset('kalkulator')">🧮 Kalkulator Diskon Belanja</button>
<button class="preset-btn" onclick="usePreset('todo')">📝 Aplikasi Catatan Tugas</button>
</div>
</div>
</div>
<!-- Panel Preview -->
<div class="preview-panel" id="previewPanel">
<div class="placeholder-text" id="placeholder">
<h3>Layar Aplikasi/Game AI</h3>
<p>Ketik ide di sebelah kiri lalu klik "Buat Aplikasi Sekarang"</p>
</div>
<iframe id="appFrame" style="display: none;"></iframe>
</div>
</head>
<body>
<div class="box">
<h2>🎯 Game Tebak Angka (1-10)</h2>
<p style="color:#8b949e">Ketik angka lalu tekan tebak!</p><br>
<input type="number" id="num" min="1" max="10">
<button onclick="check()">Tebak</button>
<h3 id="res" style="margin-top:20px; color:#f0883e;"></h3>
</div>
<script>
let target = Math.floor(Math.random() * 10) + 1;
function check() {
let val = document.getElementById('num').value;
let res = document.getElementById('res');
if(val == target) {
res.innerHTML = "🎉 Benar Sekali! Angkanya adalah " + target;
res.style.color = "#3fb950";
} else if(val > target) {
res.innerHTML = "📉 Terlalu Tinggi!";
} else {
res.innerHTML = "📈 Terlalu Rendah!";
}
}
<\/script>
</body>
</html>
`,
'kalkulator': `
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; padding: 30px; background: #f4f4f9; display: flex; justify-content: center; }
.card { background: white; padding: 25px; border-radius: 10px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); width: 100%; max-width: 300px; }
input { width: 100%; padding: 10px; margin: 8px 0; border: 1px solid #ccc; border-radius: 5px; box-sizing: border-box; }
button { width: 100%; padding: 10px; background: #4f46e5; color: white; border: none; border-radius: 5px; cursor: pointer; font-weight: bold; }
.result { margin-top: 15px; font-weight: bold; color: #16a34a; }
</style>
</head>
<body>
<div class="card">
<h3>🧮 Kalkulator Diskon</h3>
<label>Harga Asli (Rp):</label>
<input type="number" id="price" placeholder="100000">
<label>Diskon (%):</label>
<input type="number" id="discount" placeholder="20">
<button onclick="calc()">Hitung Diskon</button>
<div class="result" id="output"></div>
</div>
<script>
function calc() {
let p = parseFloat(document.getElementById('price').value) || 0;
let d = parseFloat(document.getElementById('discount').value) || 0;
let cut = (p * d) / 100;
let total = p - cut;
document.getElementById('output').innerHTML = "Hemat: Rp " + cut.toLocaleString() + "<br>Bayar: Rp " + total.toLocaleString();
}
<\/script>
</body>
</html>
`,
'todo': `
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; padding: 20px; background: #fff; }
input { padding: 8px; width: 70%; border: 1px solid #ccc; border-radius: 4px; }
button { padding: 8px 12px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; }
ul { list-style: none; padding: 0; margin-top: 15px; }
li { background: #f8f9fa; padding: 10px; border-bottom: 1px solid #ddd; display: flex; justify-content: space-between; }
</style>
</head>
<body>
<h3>📝 Catatan Tugas</h3>
<input type="text" id="task" placeholder="Tambah tugas baru...">
<button onclick="add()">Tambah</button>
<ul id="list"></ul>
<script>
function add() {
let inp = document.getElementById('task');
if(!inp.value) return;
let li = document.createElement('li');
li.innerHTML = inp.value + ' <span style="color:red;cursor:pointer" onclick="this.parentElement.remove()">❌</span>';
document.getElementById('list').appendChild(li);
inp.value = '';
}
<\/script>
</body>
</html>
`
};
function usePreset(key) {
if(key === 'game-tebak') {
document.getElementById('promptInput').value = "Buatkan game tebak angka neon sederhana";
} else if(key === 'kalkulator') {
document.getElementById('promptInput').value = "Buatkan kalkulator hitung diskon belanja";
} else if(key === 'todo') {
document.getElementById('promptInput').value = "Buatkan aplikasi daftar catatan tugas simpel";
}
generateApp();
}
function generateApp() {
const prompt = document.getElementById('promptInput').value.toLowerCase();
const iframe = document.getElementById('appFrame');
const placeholder = document.getElementById('placeholder');
let selectedHtml = "";
if (prompt.includes("game") || prompt.includes("tebak")) {
selectedHtml = templates['game-tebak'];
} else if (prompt.includes("kalkulator") || prompt.includes("diskon") || prompt.includes("hitung")) {
selectedHtml = templates['kalkulator'];
} else if (prompt.includes("tugas") || prompt.includes("catatan") || prompt.includes("todo")) {
selectedHtml = templates['todo'];
} else {
// Generik default jika tidak mencakup kata kunci khusus
selectedHtml = `
<!DOCTYPE html>
<html>
<body style="font-family:sans-serif; text-align:center; padding:50px; background:#f0f4f8;">
<h2>🚀 Aplikasi Berhasil Dibuat!</h2>
<p>Hasil generasi untuk prompt: <b>"${prompt}"</b></p>
<button onclick="alert('Fitur aplikasi berjalan!')" style="padding:10px 20px; background:#0284c7; color:white; border:none; border-radius:6px; cursor:pointer;">Uji Coba Tombol</button>
</body>
</html>
`;
}
placeholder.style.display = 'none';
iframe.style.display = 'block';
// Render kode ke Iframe
const doc = iframe.contentWindow.document;
doc.open();
doc.write(selectedHtml);
doc.close();
}
</script>
<title>قطتي التفاعلية</title> <style> * { box-sizing: border-box; user-select: none; } body { margin: 0; min-height: 100vh; background: linear-gradient(145deg, #1f3a5f, #0d1b2a); display: flex; justify-content: center; align-items: center; font-family: 'Segoe UI', Tahoma, sans-serif; } .game-container { background: #2a4b74; padding: 25px 30px 35px; border-radius: 70px 70px 40px 40px; box-shadow: 0 20px 30px rgba(0, 0, 0, 0.7), inset 0 0 15px #6d9fd1; text-align: center; max-width: 450px; width: 100%; } h1 { color: #ffe484; text-shadow: 0 3px 0 #a57c1e, 0 5px 10px black; font-size: 2rem; margin: -5px 0 10px 0; letter-spacing: 2px; } #catCanvas { background: #9ac2d9; border-radius: 120px 120px 60px 60px; display: block; margin: 10px auto; width: 100%; max-width: 320px; height: auto; aspect-ratio: 1/1; cursor: pointer; box-shadow: inset 0 -8px 0 #4a6f8a, 0 12px 18px rgba(0, 0, 0, 0.5); touch-action: none; } .status-box { background: #0f263b; padding: 12px 10px; border-radius: 60px; margin: 18px 0 14px; color: #c7e6ff; font-weight: bold; font-size: 1.1rem; box-shadow: inset 0 3px 8px #00000066; border: 1px solid #5787b0; min-height: 55px; display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; } .status-box span { background: #1d3d57; padding: 5px 18px; border-radius: 40px; color: #ffd966; } .btn-group { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin: 10px 0 5px; } .btn { background: #fedb5f; border: none; border-radius: 60px; padding: 10px 22px; font-weight: bold; font-size: 1rem; color: #1f2e3f; box-shadow: 0 6px 0 #896e1f, 0 6px 10px black; cursor: pointer; transition: 0.08s linear; display: inline-flex; align-items: center; gap: 6px; touch-action: manipulation; } .btn:active { transform: translateY(5px); box-shadow: 0 1px 0 #896e1f; } .btn-secondary { background: #b3d0e8; box-shadow: 0 6px 0 #5c7993; color: #0b1d2b; } .footer { color: #8bb3d1; margin-top: 15px; font-size: 0.8rem; } #speechHint { background: #192f42; padding: 4px 14px; border-radius: 50px; color: #9fc9e5; font-size: 0.9rem; } </style> ```<script> (function() { // ---------- إعدادات اللعبة ---------- const canvas = document.getElementById('catCanvas'); const ctx = canvas.getContext('2d'); const moodDisplay = document.getElementById('moodDisplay'); const speechHint = document.getElementById('speechHint'); // حالات القطة const MOOD = { HAPPY: '😊 سعيدة', SAD: '😢 حزينة', ANGRY: '😾 غضبانة', SLEEPY: '😴 نعسانة', TALKING: '🗣️ تتكلم' }; let currentMood = MOOD.HAPPY; let eyeBlink = 0; // 0 مفتوح, 1 مغلق let blinkTimer = 0; let earAngle = 0; // لتحريك الأذن let mouthOpen = 0; // 0 مغلق, 1 مفتوح let talkTimer = 0; let tailWag = 0; // متغيرات الصوت let recognition = null; let isListening = false; let lastRecognizedText = ''; // ---------- رسم القطة ---------- function drawCat(blink, ear, mouth, tail, mood) { ctx.clearRect(0, 0, 400, 400); // خلفية دائرية ناعمة const grd = ctx.createRadialGradient(200, 200, 50, 200, 200, 200); grd.addColorStop(0, '#b8daf0'); grd.addColorStop(1, '#7aa5c4'); ctx.fillStyle = grd; ctx.beginPath(); ctx.arc(200, 200, 190, 0, Math.PI * 2); ctx.fill(); // ---- جسم القطة ---- ctx.shadowColor = 'rgba(0,0,0,0.3)'; ctx.shadowBlur = 18; ctx.shadowOffsetY = 5; // الجسد (بيضاوي) ctx.fillStyle = '#f5b27e'; ctx.strokeStyle = '#b16d3a'; ctx.lineWidth = 2.5; ctx.beginPath(); ctx.ellipse(200, 240, 90, 70, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); // الرأس (دائرة) ctx.fillStyle = '#f5b27e'; ctx.strokeStyle = '#b16d3a'; ctx.beginPath(); ctx.arc(200, 160, 80, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); // ---- الأذنان ---- ctx.fillStyle = '#f5b27e'; ctx.strokeStyle = '#b16d3a'; ctx.lineWidth = 2; // أذن يمنى (مع زاوية) ctx.save(); ctx.translate(245, 100); ctx.rotate(0.3 + ear * 0.1); ctx.beginPath(); ctx.moveTo(0, -10); ctx.lineTo(-25, -50); ctx.lineTo(25, -45); ctx.closePath(); ctx.fill(); ctx.stroke(); // أذن داخلي ctx.fillStyle = '#f7c2a0'; ctx.beginPath(); ctx.moveTo(0, -10); ctx.lineTo(-15, -40); ctx.lineTo(15, -37); ctx.closePath(); ctx.fill(); ctx.restore(); // أذن يسرى ctx.save(); ctx.translate(155, 100); ctx.rotate(-0.3 - ear * 0.1); ctx.fillStyle = '#f5b27e'; ctx.strokeStyle = '#b16d3a'; ctx.beginPath(); ctx.moveTo(0, -10); ctx.lineTo(-25, -45); ctx.lineTo(25, -50); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#f7c2a0'; ctx.beginPath(); ctx.moveTo(0, -10); ctx.lineTo(-15, -37); ctx.lineTo(15, -40); ctx.closePath(); ctx.fill(); ctx.restore(); // ---- العينان ---- ctx.shadowBlur = 8; // العين اليمنى ctx.fillStyle = '#ffffff'; ctx.beginPath(); ctx.ellipse(230, 155, 22, 25, 0, 0, Math.PI * 2); ctx.fill(); ctx.strokeStyle = '#4a2810'; ctx.lineWidth = 2; ctx.stroke(); // بؤبؤ العين ctx.fillStyle = '#2d1a0a'; if (blink < 0.3) { ctx.beginPath(); ctx.ellipse(232, 158, 11, 14, 0, 0, Math.PI * 2); ctx.fill(); // انعكاس ctx.fillStyle = 'white'; ctx.beginPath(); ctx.arc(237, 152, 4, 0, Math.PI * 2); ctx.fill(); } else { // رمش (خط) ctx.strokeStyle = '#2d1a0a'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(210, 155); ctx.lineTo(250, 155); ctx.stroke(); } // العين اليسرى ctx.fillStyle = '#ffffff'; ctx.beginPath(); ctx.ellipse(170, 155, 22, 25, 0, 0, Math.PI * 2); ctx.fill(); ctx.strokeStyle = '#4a2810'; ctx.lineWidth = 2; ctx.stroke(); ctx.fillStyle = '#2d1a0a'; if (blink < 0.3) { ctx.beginPath(); ctx.ellipse(168, 158, 11, 14, 0, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = 'white'; ctx.beginPath(); ctx.arc(163, 152, 4, 0, Math.PI * 2); ctx.fill(); } else { ctx.strokeStyle = '#2d1a0a'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(150, 155); ctx.lineTo(190, 155); ctx.stroke(); } // ---- الأنف ---- ctx.shadowBlur = 5; ctx.fillStyle = '#f08080'; ctx.beginPath(); ctx.moveTo(200, 180); ctx.lineTo(190, 190); ctx.lineTo(210, 190); ctx.closePath(); ctx.fill(); // ---- الفم ---- ctx.strokeStyle = '#7a3f1a'; ctx.lineWidth = 2.5; ctx.beginPath(); if (mouth > 0.3) { // فم مفتوح (دائرة) ctx.arc(200, 202, 14, 0, Math.PI); ctx.fillStyle = '#a04a3a'; ctx.fill(); } else { // فم مغلق (خط) ctx.moveTo(182, 195); ctx.quadraticCurveTo(200, 205, 218, 195); } ctx.stroke(); // ---- الشوارب ---- ctx.strokeStyle = '#4f3a2a'; ctx.lineWidth = 1.8; ctx.shadowBlur = 3; for (let i = -1; i <= 1; i += 2) { ctx.beginPath(); ctx.moveTo(170 + i * 20, 185 + i * 5); ctx.lineTo(120 + i * 30, 175 + i * 12); ctx.stroke(); ctx.beginPath(); ctx.moveTo(170 + i * 20, 195 + i * 5); ctx.lineTo(120 + i * 30, 195 + i * 12); ctx.stroke(); ctx.beginPath(); ctx.moveTo(170 + i * 20, 205 + i * 5); ctx.lineTo(125 + i * 30, 215 + i * 10); ctx.stroke(); } // ---- الذيل (يتحرك) ---- ctx.shadowBlur = 10; ctx.fillStyle = '#e8a06b'; ctx.strokeStyle = '#b16d3a'; ctx.lineWidth = 6; ctx.beginPath(); const tailBaseX = 290, tailBaseY = 260; ctx.moveTo(tailBaseX, tailBaseY); const tailSway = Math.sin(tail) * 12; ctx.quadraticCurveTo(330 + tailSway, 200 + tailSway * 0.4, 350 + tailSway * 1.2, 150 + tailSway * 0.3); ctx.stroke(); // نهاية الذيل ctx.fillStyle = '#d68b50'; ctx.beginPath(); ctx.arc(350 + tailSway * 1.2, 150 + tailSway * 0.3, 12, 0, Math.PI * 2); ctx.fill(); // ---- الكفوف الأمامية ---- ctx.shadowBlur = 8; ctx.fillStyle = '#f5b27e'; ctx.strokeStyle = '#b16d3a'; ctx.lineWidth = 2; for (let side = -1; side <= 1; side += 2) { ctx.beginPath(); ctx.ellipse(160 + side * 50, 290, 18, 22, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); // وسادة ctx.fillStyle = '#e8967a'; ctx.beginPath(); ctx.ellipse(160 + side * 50, 295, 8, 10, 0, 0, Math.PI * 2); ctx.fill(); } ctx.shadowBlur = 0; ctx.shadowOffsetY = 0; // تعبيرات إضافية حسب المزاج if (mood === MOOD.SAD) { ctx.fillStyle = '#5b7f9e'; ctx.font = '30px sans-serif'; ctx.fillText('💧', 140, 130); ctx.fillText('💧', 230, 125); } else if (mood === MOOD.ANGRY) { ctx.strokeStyle = '#3f1a0a'; ctx.lineWidth = 4; // حاجبين مقطبين ctx.beginPath(); ctx.moveTo(150, 120); ctx.lineTo(185, 130); ctx.stroke(); ctx.beginPath(); ctx.moveTo(250, 120); ctx.lineTo(215, 130); ctx.stroke(); // علامة غضب ctx.fillStyle = '#cc3333'; ctx.font = '28px sans-serif'; ctx.fillText('⚡', 270, 100); } else if (mood === MOOD.SLEEPY) { ctx.fillStyle = '#4a6f8a'; ctx.font = '28px sans-serif'; ctx.fillText('💤', 140, 110); ctx.fillText('💤', 240, 105); } } // ---------- تحديث الحالة ---------- function updateGame() { // الطرفة التلقائية blinkTimer++; if (blinkTimer > 120) { eyeBlink = 1; if (blinkTimer > 135) { eyeBlink = 0; blinkTimer = 0; } } // تحريك الذيل tailWag += 0.06; // إنهاء التحدث بعد فترة if (talkTimer > 0) { talkTimer--; if (talkTimer === 0) { mouthOpen = 0; if (currentMood === MOOD.TALKING) { currentMood = MOOD.HAPPY; updateMoodDisplay(); } } } // تحريك الأذن بشكل طبيعي earAngle = Math.sin(Date.now() / 1500) * 0.2; drawCat(eyeBlink, earAngle, mouthOpen, tailWag, currentMood); requestAnimationFrame(updateGame); } function updateMoodDisplay() { moodDisplay.textContent = currentMood; } // ---------- التفاعل مع القطة ---------- function setMood(newMood, duration = 0) { currentMood = newMood; updateMoodDisplay(); if (duration > 0) { setTimeout(() => { if (currentMood === newMood) { currentMood = MOOD.HAPPY; updateMoodDisplay(); } }, duration); } } function petCat() { setMood(MOOD.HAPPY); speechHint.textContent = '🤗 دلعتني! أنا سعيدة'; // حركة الأذن earAngle = 0.7; setTimeout(() => { earAngle = 0; }, 300); // فتح الفم قليلاً mouthOpen = 0.6; setTimeout(() => { mouthOpen = 0; }, 400); } function hitCat() { setMood(MOOD.ANGRY, 1800); speechHint.textContent = '😾 آه! لماذا تضربني؟'; mouthOpen = 1; setTimeout(() => { mouthOpen = 0; }, 600); earAngle = -0.9; setTimeout(() => { earAngle = 0; }, 400); } function makeSleepy() { setMood(MOOD.SLEEPY, 2500); speechHint.textContent = '😴 أنعس... نمت...'; eyeBlink = 1; setTimeout(() => { eyeBlink = 0; }, 2000); } // ---------- خاصية التعرف على الصوت (كرر كلامي) ---------- function initSpeech() { if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) { speechHint.textContent = '😺 قطتي
<canvas id="catCanvas" width="400" height="400"></canvas> <div class="status-box" id="statusBox"> <span id="speechHint">👆 اضغط القطة</span> <span id="moodDisplay">😊 سعيدة</span> </div> <div class="btn-group"> <button class="btn" id="micBtn">🎤 كرر كلامي</button> <button class="btn btn-secondary" id="petBtn">🤚 دلّعني</button> <button class="btn btn-secondary" id="resetBtn">🌀 إعادة</button> </div> <div class="footer"> اضغط على القطة أو استخدم الأزرار </div>⚠️ متصفحك لا يدعم الصوت'; return false; } const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; recognition = new SpeechRecognition(); recognition.lang = 'ar-AR'; recognition.continuous = false; recognition.interimResults = false; recognition.onstart = function() { isListening = true; speechHint.textContent = '🎤 استمع... تكلم الآن'; }; recognition.onresult = function(event) { const text = event.results[0][0].transcript; lastRecognizedText = text; speechHint.textContent = '🗣️ قلت: "' + text + '"'; // تفاعل القطة setMood(MOOD.TALKING, 1500); mouthOpen = 1; talkTimer = 25; // تحريك الأذن earAngle = 0.8; setTimeout(() => { earAngle = 0; }, 500); // نطق النص (تخيلي) setTimeout(() => { if (currentMood === MOOD.TALKING) { currentMood = MOOD.HAPPY; updateMoodDisplay(); } }, 1200); isListening = false; }; recognition.onerror = function(event) { speechHint.textContent = '❌ خطأ: ' + event.error; isListening = false; if (event.error === 'not-allowed') { speechHint.textContent = '🚫 امنح إذن الميكروفون'; } }; recognition.onend = function() { isListening = false; if (speechHint.textContent.includes('استمع')) { speechHint.textContent = '👆 اضغط "كرر كلامي" مرة أخرى'; } }; return true; } function startListening() { if (!recog ```nition) { const supported = initSpeech(); if (!supported) return; } if (isListening) { recogniti
https://gist.github.com/isdaviddong/23cc140c1780828b44f79397f737b95e.js
আমি একটা এপস বানিয়ে নিতে চাই সিগনাল দেখাবে তার
<div class="btn-group">
<button class="btn-sub" onclick="ghatao()">- घटाएं</button>
<button class="btn-reset" onclick="resetKaro()">रीसेट</button>
<button class="btn-add" onclick="badhao()">+ बढ़ाएं</button>
</div>
<div class="btn-group">
<button class="btn-sub" onclick="ghatao()">- घटाएं</button>
<button class="btn-reset" onclick="resetKaro()">रीसेट</button>
<button class="btn-add" onclick="badhao()">+ बढ़ाएं</button>
</div>
Teknik Kendaraan Ringan | Lulusan SMK Muhammadiyah 1 Blora
<div class="section">
<h2>PROFIL SINGKAT</h2>
<p>Lulusan SMK Muhammadiyah 1 Blora jurusan Teknik Kendaraan Ringan yang disiplin, pekerja keras, dan cepat belajar. Memiliki semangat tinggi, bertanggung jawab, dan mampu bekerja dalam tim maupun individu. Siap ditempatkan dimanapun dan ingin mengembangkan karir serta keterampilan di dunia kerja.</p>
</div>
<div class="section">
<h2>PENDIDIKAN</h2>
<div class="item">
<h3>SMK MUHAMMADIYAH 1 BLORA</h3>
<span>2023 - 2026 | Jurusan: Teknik Kendaraan Ringan</span>
<ul>
<li>Mempelajari perawatan mesin, sistem kelistrikan, dan K3</li>
<li>Terbiasa bekerja sesuai prosedur dan tepat waktu</li>
</ul>
</div>
</div>
<div class="section">
<h2>PENGALAMAN KERJA
<div class="header">
<h1>Self Attendance</h1>
<p id="currentDate"></p>
<p id="currentTime"></p>
</div>
<div class="card">
<label for="userName">Name</label>
<input
type="text"
id="userName"
placeholder="Enter your name"
>
<button
class="checkin"
id="checkInBtn"
onclick="checkIn()">
✓ Check In
</button>
<button
class="checkout"
id="checkOutBtn"
onclick="checkOut()">
⏰ Check Out
</button>
<div class="status" id="status">
Attendance not marked
</div>
</div>
<div class="card">
<h2>Attendance History</h2>
<br>
<div id="history">
<p class="empty">No attendance records</p>
</div>
</div>
No attendance records
`; return; } history.innerHTML = ""; [...attendance].reverse().forEach(record => { const item = document.createElement("div"); item.className = "attendance-item"; item.innerHTML = ` ${record.name}📅 ${record.date}
🟢 Check In: ${record.checkIn}
🔴 Check Out: ${record.checkOut || "Not checked out"}
`; history.appendChild(item); }); } displayHistory(); </script>import os, zipfile
root="/mnt/data/ma_soi_mobile_v1"
os.makedirs(root, exist_ok=True)
html='''<!doctype html>
Phiên bản Mobile
Cần 6 người chơi
0/6
🎲 Chia vai← Quay lạiĐưa điện thoại cho
Không cho người khác nhìn thấy.
✓ Đã xem':'👁️ Xem vai')+'6 người đã nhận vai.
Bản Mobile V1 đã hoàn tất phần menu, người chơi và chia vai.
Hệ thống hành động ban đêm và bỏ phiếu sẽ được thêm ở phiên bản tiếp theo.
↩️ Về phòngwith open(root+"/index.html","w",encoding="utf-8") as f:f.write(html)
with open(root+"/README.txt","w",encoding="utf-8") as f:f.write("Ma Sói Mobile V1 - mở index.html bằng Chrome trên điện thoại.")
zip_path="/mnt/data/Ma_Soi_Mobile_Phan_1.zip"
with zipfile.ZipFile(zip_path,"w",zipfile.ZIP_DEFLATED) as z:
z.write(root+"/index.html","index.html")
z.write(root+"/README.txt","README.txt")
print(zip_path)
website/
│
├── index.html
│
├── assets/
│ ├── logo.png
│ ├── aditya-vikram-singh.jpg
│ ├── hero.jpg
│ ├── about.jpg
│ ├── education.jpg
│ ├── gau-seva.jpg
│ ├── temple.jpg
│ ├── women.jpg
│ ├── lok-seva.jpg
│ ├── farmer.jpg
│ └── donation-bg.jpg
│
├── donate.html
└── server/
index.html
assets/
server/
Website design kijiye
Hello
Nice
Hello
body {
background-color: #f3f4f6;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}
.card {
background: #ffffff;
width: 100%;
max-width: 400px;
border-radius: 18px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
padding: 24px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.header h2 {
font-size: 1.25rem;
font-weight: 700;
color: #111827;
display: flex;
align-items: center;
gap: 8px;
}
.btn-scan {
background-color: #eff6ff;
color: #2563eb;
border: none;
padding: 8px 14px;
border-radius: 20px;
cursor: pointer;
font-size: 0.85rem;
font-weight: 600;
display: flex;
align-items: center;
gap: 6px;
transition: all 0.2s ease;
}
.btn-scan:hover {
background-color: #dbeafe;
}
.btn-scan svg {
transition: transform 0.5s ease;
}
.btn-scan.spinning svg {
animation: spin 1s linear infinite;
}
@keyframes spin {
100% { transform: rotate(360deg); }
}
.status-bar {
background-color: #eff6ff;
color: #2563eb;
padding: 10px 14px;
border-radius: 10px;
font-size: 0.85rem;
margin-bottom: 16px;
display: none;
align-items: center;
gap: 8px;
}
.wifi-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 10px;
}
.wifi-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 14px;
border: 1px solid #e5e7eb;
border-radius: 12px;
transition: all 0.2s ease;
}
.wifi-item:hover {
border-color: #3b82f6;
}
.wifi-main {
display: flex;
align-items: center;
gap: 12px;
}
.wifi-icon-container {
display: flex;
align-items: center;
justify-content: center;
color: #4b5563;
}
.wifi-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.wifi-name {
font-weight: 600;
color: #1f2937;
font-size: 0.95rem;
display: flex;
align-items: center;
gap: 6px;
}
.wifi-details {
font-size: 0.75rem;
color: #6b7280;
display: flex;
align-items: center;
gap: 4px;
}
.btn-action {
border: none;
padding: 6px 14px;
border-radius: 8px;
cursor: pointer;
font-size: 0.8rem;
font-weight: 600;
transition: all 0.2s ease;
}
.btn-connect {
background-color: #f3f4f6;
color: #374151;
}
.btn-connect:hover {
background-color: #e5e7eb;
}
.btn-disconnect {
background-color: #fee2e2;
color: #dc2626;
}
.btn-disconnect:hover {
background-color: #fca5a5;
}
.connected {
border-color: #10b981;
background-color: #f0fdf4;
}
.connected .wifi-icon-container {
color: #10b981;
}
/* SVG Signal Custom Bar Styles */
.signal-bar {
fill: #d1d5db;
}
.signal-bar.active {
fill: currentColor;
}
/* Modal Styling */
.modal-overlay {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.4);
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s ease;
z-index: 100;
}
.modal-overlay.active {
opacity: 1;
pointer-events: auto;
}
.modal {
background: #ffffff;
width: 90%;
max-width: 340px;
border-radius: 16px;
padding: 20px;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}
.modal h3 {
font-size: 1.1rem;
color: #111827;
margin-bottom: 4px;
}
.modal p {
font-size: 0.85rem;
color: #6b7280;
margin-bottom: 14px;
}
.input-group {
margin-bottom: 16px;
}
.input-wrapper {
position: relative;
display: flex;
align-items: center;
}
.input-wrapper input {
width: 100%;
padding: 10px 38px 10px 12px;
border: 1px solid #d1d5db;
border-radius: 8px;
font-size: 0.9rem;
outline: none;
}
.input-wrapper input:focus {
border-color: #2563eb;
}
.toggle-password {
position: absolute;
right: 10px;
background: none;
border: none;
cursor: pointer;
color: #6b7280;
display: flex;
align-items: center;
justify-content: center;
padding: 2px;
}
.toggle-password:hover {
color: #111827;
}
.error-text {
color: #dc2626;
font-size: 0.75rem;
margin-top: 6px;
display: none;
}
.modal-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
}
.btn-secondary {
background: #f3f4f6;
border: none;
color: #374151;
padding: 8px 14px;
border-radius: 8px;
cursor: pointer;
font-size: 0.85rem;
font-weight: 500;
}
.btn-primary {
background: #2563eb;
color: white;
border: none;
padding: 8px 14px;
border-radius: 8px;
cursor: pointer;
font-size: 0.85rem;
font-weight: 600;
}
.btn-primary:hover {
background-color: #1d4ed8;
}
</style>
<div id="statusBar" class="status-bar">Memindai jaringan di sekitar...</div>
<ul id="wifiList" class="wifi-list"></ul>
Masukkan kata sandi untuk jaringan ini.
<div class="input-group">
<div class="input-wrapper">
<input type="password" id="passwordInput" placeholder="Kata Sandi (min. 8 karakter)" autocomplete="off">
<button type="button" class="toggle-password" onclick="togglePasswordVisibility()" title="Tampilkan Kata Sandi">
<svg id="eyeIcon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
<circle cx="12" cy="12" r="3"></circle>
</svg>
</button>
</div>
<span id="errorText" class="error-text">Kata sandi minimal 8 karakter!</span>
</div>
<div class="modal-actions">
<button class="btn-secondary" onclick="closeModal()">Batal</button>
<button class="btn-primary" onclick="submitPassword()">Hubungkan</button>
</div>
</div>
Kontrol HP - Lock, Senter, Kelap-Kelip
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
body {
background: #0a0a0f;
font-family: 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 16px;
}
/* Tampilan HP /
.phone {
width: 100%;
max-width: 380px;
background: #111;
border-radius: 48px;
padding: 16px 12px 24px;
box-shadow: 0 30px 40px rgba(0,0,0,0.5), inset 0 1px 2px rgba(255,255,255,0.05);
border: 1px solid #2c2c3a;
}
.screen {
background: #121212;
border-radius: 40px;
padding: 20px 16px;
min-height: 600px;
display: flex;
flex-direction: column;
transition: all 0.2s ease;
position: relative;
}
/ Efek kelap-kelip global /
.screen.blink-effect {
animation: blinkFlash 0.3s ease-in-out 3;
background-color: #fff5e0;
}
@Keyframes blinkFlash {
0% { background-color: #121212; }
50% { background-color: #ffefc0; box-shadow: 0 0 20px rgba(255,200,0,0.5); }
100% { background-color: #121212; }
}
/ Mode layar terkunci */
.screen.locked {
filter: blur(4px);
pointer-events: none;
background: #0a0a0a;
}
.screen.locked::after {
content: "🔒 LAYAR TERKUNCI";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,0.85);
color: white;
padding: 12p