Spaces:
Sleeping
Sleeping
| <html lang="id"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>SentiScope β Social Media Intelligence</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link href="https://fonts.googleapis.com/css2?family=Cabinet+Grotesk:wght@400;500;700;800&family=JetBrains+Mono:wght@300;400;500&display=swap" rel="stylesheet"> | |
| <style> | |
| *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } | |
| :root { | |
| --bg: #080a0f; | |
| --s1: #0e1117; | |
| --s2: #141820; | |
| --b1: rgba(255,255,255,0.06); | |
| --b2: rgba(255,255,255,0.10); | |
| --text: #e8eaf0; | |
| --muted: #4a5568; | |
| --muted2: #8892a4; | |
| --accent: #4f9cf9; | |
| --a2: #7b61ff; | |
| --green: #22c55e; | |
| --display: 'Cabinet Grotesk', sans-serif; | |
| --mono: 'JetBrains Mono', monospace; | |
| } | |
| html { scroll-behavior: smooth; } | |
| body { font-family: var(--display); background: var(--bg); color: var(--text); min-height: 100vh; overflow-x: hidden; } | |
| body::before { | |
| content: ''; | |
| position: fixed; inset: 0; | |
| background-image: linear-gradient(rgba(79,156,249,0.025) 1px, transparent 1px), linear-gradient(90deg, rgba(79,156,249,0.025) 1px, transparent 1px); | |
| background-size: 64px 64px; | |
| pointer-events: none; z-index: 0; | |
| } | |
| .orb { position: fixed; border-radius: 50%; filter: blur(130px); pointer-events: none; z-index: 0; } | |
| .orb-1 { width: 600px; height: 600px; background: rgba(79,156,249,0.07); top: -250px; right: -150px; } | |
| .orb-2 { width: 500px; height: 500px; background: rgba(123,97,255,0.06); bottom: 100px; left: -200px; } | |
| /* NAV */ | |
| nav { | |
| position: fixed; top: 0; left: 0; right: 0; z-index: 100; | |
| display: flex; align-items: center; justify-content: space-between; | |
| padding: 1rem 3rem; | |
| background: rgba(8,10,15,0.75); | |
| backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); | |
| border-bottom: 1px solid var(--b1); | |
| } | |
| .nav-brand { display: flex; align-items: center; gap: 0.65rem; text-decoration: none; } | |
| .brand-icon { | |
| width: 30px; height: 30px; border-radius: 8px; | |
| background: linear-gradient(135deg, var(--accent), var(--a2)); | |
| display: flex; align-items: center; justify-content: center; | |
| font-weight: 800; font-size: 0.8rem; color: #fff; | |
| } | |
| .brand-name { font-size: 0.95rem; font-weight: 800; letter-spacing: -0.02em; color: var(--text); } | |
| .brand-name b { color: var(--accent); font-weight: 800; } | |
| nav ul { display: flex; gap: 2rem; list-style: none; } | |
| nav ul a { font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted2); text-decoration: none; transition: color .2s; } | |
| nav ul a:hover { color: var(--text); } | |
| .nav-pill { font-family: var(--mono); font-size: 0.6rem; background: rgba(79,156,249,0.1); color: var(--accent); border: 1px solid rgba(79,156,249,0.22); padding: 0.25rem 0.65rem; border-radius: 20px; letter-spacing: 0.06em; } | |
| /* HERO */ | |
| .hero { | |
| position: relative; z-index: 1; | |
| min-height: 100vh; | |
| display: flex; flex-direction: column; align-items: center; justify-content: center; | |
| padding: 8rem 2rem 5rem; text-align: center; | |
| } | |
| .eyebrow { | |
| display: inline-flex; align-items: center; gap: 0.5rem; | |
| font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase; | |
| color: var(--accent); background: rgba(79,156,249,0.08); border: 1px solid rgba(79,156,249,0.18); | |
| padding: 0.3rem 0.85rem; border-radius: 100px; margin-bottom: 2rem; | |
| animation: fu 0.6s 0.1s both; | |
| } | |
| .eyebrow i { display: inline-block; width: 5px; height: 5px; background: var(--accent); border-radius: 50%; animation: blink 2s infinite; } | |
| @keyframes blink { 0%,100%{opacity:1;} 50%{opacity:0.3;} } | |
| h1.ht { | |
| font-size: clamp(3rem, 7.5vw, 6.5rem); | |
| font-weight: 800; line-height: 0.98; letter-spacing: -0.04em; | |
| margin-bottom: 1.5rem; animation: fu 0.7s 0.2s both; | |
| } | |
| h1.ht .l1 { display: block; color: var(--text); } | |
| h1.ht .l2 { | |
| display: block; | |
| background: linear-gradient(135deg, var(--accent) 20%, var(--a2) 80%); | |
| -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; | |
| } | |
| h1.ht .l3 { display: block; color: var(--muted2); } | |
| .hero-sub { | |
| max-width: 520px; font-size: 0.95rem; line-height: 1.75; color: var(--muted2); | |
| margin: 0 auto 2.5rem; animation: fu 0.7s 0.3s both; | |
| } | |
| /* FORM */ | |
| .form-box { | |
| width: 100%; max-width: 540px; | |
| background: var(--s1); border: 1px solid var(--b2); border-radius: 14px; | |
| padding: 1.75rem; animation: fu 0.7s 0.4s both; | |
| box-shadow: 0 4px 6px -1px rgba(0,0,0,.3), 0 32px 80px -12px rgba(0,0,0,.5), 0 0 50px rgba(79,156,249,0.06); | |
| position: relative; overflow: hidden; | |
| } | |
| .form-box::after { | |
| content:''; position:absolute; top:0;left:0;right:0; height:1px; | |
| background: linear-gradient(90deg, transparent 5%, rgba(79,156,249,0.5) 50%, transparent 95%); | |
| } | |
| .f-row { display: grid; grid-template-columns: 1fr auto; gap: 0.6rem; margin-bottom: 0.75rem; } | |
| .f-group { display: flex; flex-direction: column; gap: 0.35rem; } | |
| .f-group label { font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); } | |
| .f-input { | |
| font-family: var(--mono); font-size: 0.88rem; | |
| background: var(--s2); border: 1px solid var(--b2); border-radius: 7px; | |
| padding: 0.7rem 0.9rem; color: var(--text); outline: none; width: 100%; | |
| transition: border-color .2s, box-shadow .2s; | |
| } | |
| .f-input::placeholder { color: var(--muted); } | |
| .f-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(79,156,249,0.12); } | |
| .src-lbl { font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); margin-bottom: 0.5rem; display: flex; align-items: center; justify-content: space-between; } | |
| .src-lbl b { color: var(--accent); cursor: pointer; font-weight: 400; transition: opacity .2s; } | |
| .src-lbl b:hover { opacity: 0.7; } | |
| .src-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0.4rem; margin-bottom: 0.2rem; } | |
| .src-item { position: relative; } | |
| .src-item input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; } | |
| .src-item label { | |
| display: flex; align-items: center; gap: 0.5rem; | |
| background: var(--s2); border: 1px solid var(--b2); border-radius: 7px; | |
| padding: 0.5rem 0.6rem; cursor: pointer; | |
| transition: border-color .15s, background .15s; | |
| user-select: none; min-height: 48px; | |
| } | |
| .src-item label:hover { filter: brightness(1.1); } | |
| .src-item input:checked + label { border-color: var(--accent); background: rgba(79,156,249,0.1); } | |
| .src-ico { font-size: 1rem; flex-shrink: 0; } | |
| .src-info { display: flex; flex-direction: column; gap: 0.05rem; flex: 1; min-width: 0; } | |
| .src-name { font-size: 0.7rem; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } | |
| .src-sub { font-family: var(--mono); font-size: 0.48rem; letter-spacing: 0.04em; color: var(--muted); } | |
| .src-box { | |
| width: 13px; height: 13px; border-radius: 3px; | |
| border: 1px solid var(--b2); flex-shrink: 0; | |
| display: flex; align-items: center; justify-content: center; | |
| transition: background .15s, border-color .15s; | |
| } | |
| .src-item input:checked + label .src-box { background: var(--accent); border-color: var(--accent); } | |
| .src-item input:checked + label .src-box::after { | |
| content: ''; display: block; width: 7px; height: 3.5px; | |
| border-left: 1.5px solid #fff; border-bottom: 1.5px solid #fff; | |
| transform: rotate(-45deg) translateY(-1px); | |
| } | |
| .src-warn { font-family: var(--mono); font-size: 0.55rem; color: #f59e0b; margin-top: 0.4rem; display: none; } | |
| .src-warn.show { display: block; } | |
| /* SLIDER */ | |
| .slider-wrap { display:flex; flex-direction:column; gap:0.35rem; margin-top:0.1rem; } | |
| .slider-row { display:flex; align-items:center; gap:0.75rem; } | |
| input[type="range"] { flex:1; -webkit-appearance:none; appearance:none; height:3px; background:var(--b2); border-radius:2px; outline:none; cursor:pointer; } | |
| input[type="range"]::-webkit-slider-thumb { -webkit-appearance:none; width:14px; height:14px; border-radius:50%; background:linear-gradient(135deg,var(--accent),var(--a2)); cursor:pointer; transition:transform .15s; } | |
| input[type="range"]::-webkit-slider-thumb:hover { transform:scale(1.2); } | |
| .slider-val { font-family:var(--mono); font-size:0.72rem; font-weight:500; color:var(--accent); min-width:2.5rem; text-align:right; } | |
| /* MULTI-KEYWORD */ | |
| .kw-tags { display:flex; flex-wrap:wrap; gap:0.35rem; margin-top:0.4rem; min-height:1.5rem; } | |
| .kw-tag { display:inline-flex; align-items:center; gap:0.3rem; background:rgba(79,156,249,0.1); border:1px solid rgba(79,156,249,0.25); border-radius:5px; padding:0.15rem 0.5rem; font-family:var(--mono); font-size:0.62rem; color:var(--accent); } | |
| .kw-tag button { background:none; border:none; color:var(--accent); cursor:pointer; font-size:0.7rem; line-height:1; padding:0; opacity:0.7; } | |
| .kw-tag button:hover { opacity:1; } | |
| .kw-add-hint { font-family:var(--mono); font-size:0.55rem; color:var(--muted); } | |
| .btn-go { | |
| align-self: flex-end; | |
| background: linear-gradient(135deg, var(--accent), var(--a2)); | |
| color: #fff; border: none; border-radius: 7px; | |
| padding: 0.7rem 1.3rem; | |
| font-family: var(--display); font-size: 0.85rem; font-weight: 700; | |
| cursor: pointer; display: flex; align-items: center; gap: 0.35rem; | |
| transition: opacity .2s, transform .15s, box-shadow .2s; | |
| white-space: nowrap; | |
| box-shadow: 0 4px 20px rgba(79,156,249,0.28); | |
| } | |
| .btn-go:hover { opacity: 0.88; transform: translateY(-1px); box-shadow: 0 8px 28px rgba(79,156,249,0.38); } | |
| .btn-go:active { transform: translateY(0); } | |
| .f-hint { font-family: var(--mono); font-size: 0.58rem; color: var(--muted); margin-top: 0.65rem; } | |
| .f-hint b { color: var(--muted2); } | |
| /* STATS */ | |
| .stats { | |
| display: flex; gap: 0; margin-top: 2.5rem; | |
| background: var(--s1); border: 1px solid var(--b2); border-radius: 10px; overflow: hidden; | |
| animation: fu 0.7s 0.5s both; | |
| } | |
| .stat { | |
| flex: 1; padding: 1rem 1.5rem; | |
| display: flex; flex-direction: column; gap: 0.2rem; align-items: center; | |
| border-right: 1px solid var(--b1); transition: background .2s; | |
| } | |
| .stat:last-child { border-right: none; } | |
| .stat:hover { background: var(--s2); } | |
| .stat-n { | |
| font-size: 1.4rem; font-weight: 800; letter-spacing: -0.03em; | |
| background: linear-gradient(135deg, var(--text), var(--muted2)); | |
| -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; | |
| } | |
| .stat-l { font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); } | |
| /* SCROLL */ | |
| .scroll-down { | |
| position: absolute; bottom: 2.5rem; left: 50%; transform: translateX(-50%); | |
| display: flex; flex-direction: column; align-items: center; gap: 0.4rem; | |
| animation: fu 1s 0.8s both; | |
| } | |
| .scroll-down span { font-family: var(--mono); font-size: 0.5rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted); } | |
| .scroll-mouse { width: 18px; height: 26px; border: 1.5px solid var(--b2); border-radius: 9px; display: flex; align-items: flex-start; justify-content: center; padding-top: 4px; } | |
| .scroll-dot { width: 2px; height: 5px; background: var(--accent); border-radius: 1px; animation: sd 1.5s infinite; } | |
| @keyframes sd { 0%{opacity:1;transform:translateY(0)} 100%{opacity:0;transform:translateY(7px)} } | |
| /* FEATURES */ | |
| .sec { position: relative; z-index: 1; max-width: 1200px; margin: 0 auto; padding: 5rem 3rem; } | |
| .sec-tag { font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); margin-bottom: 0.75rem; } | |
| .sec-h { font-size: 2.4rem; font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; margin-bottom: 3rem; } | |
| .sec-h em { font-style: normal; color: var(--muted2); } | |
| .feat-grid { | |
| display: grid; grid-template-columns: repeat(4, 1fr); | |
| gap: 1px; background: var(--b1); border: 1px solid var(--b1); border-radius: 12px; overflow: hidden; | |
| } | |
| .feat { | |
| background: var(--s1); padding: 1.75rem 1.5rem; | |
| display: flex; flex-direction: column; gap: 0.9rem; | |
| transition: background .2s; | |
| opacity: 0; transform: translateY(16px); transition: opacity .45s, transform .45s, background .2s; | |
| } | |
| .feat.vis { opacity: 1; transform: translateY(0); } | |
| .feat:hover { background: var(--s2); } | |
| .feat-ico { | |
| width: 38px; height: 38px; border-radius: 9px; | |
| display: flex; align-items: center; justify-content: center; font-size: 1rem; | |
| } | |
| .ic-b { background: rgba(79,156,249,0.1); } | |
| .ic-p { background: rgba(123,97,255,0.1); } | |
| .ic-g { background: rgba(34,197,94,0.1); } | |
| .ic-a { background: rgba(245,158,11,0.1); } | |
| .feat-name { font-size: 0.88rem; font-weight: 700; } | |
| .feat-desc { font-family: var(--mono); font-size: 0.65rem; line-height: 1.7; color: var(--muted2); } | |
| /* PIPELINE */ | |
| .pipe-wrap { | |
| display: grid; grid-template-columns: repeat(5, 1fr); | |
| position: relative; gap: 0; | |
| } | |
| .pipe-wrap::before { | |
| content: ''; position: absolute; top: 27px; left: 9%; right: 9%; height: 1px; | |
| background: linear-gradient(90deg, transparent, var(--b2), rgba(79,156,249,0.4), var(--b2), transparent); | |
| } | |
| .pipe { | |
| display: flex; flex-direction: column; align-items: center; gap: 0.9rem; | |
| padding: 0 0.75rem; text-align: center; | |
| } | |
| .pipe-circle { | |
| width: 54px; height: 54px; border-radius: 50%; | |
| background: var(--s2); border: 1px solid var(--b2); | |
| display: flex; align-items: center; justify-content: center; | |
| font-family: var(--mono); font-size: 0.7rem; color: var(--accent); | |
| position: relative; z-index: 1; transition: background .2s, border-color .2s; | |
| } | |
| .pipe:hover .pipe-circle { background: rgba(79,156,249,0.1); border-color: var(--accent); } | |
| .pipe-name { font-size: 0.8rem; font-weight: 700; } | |
| .pipe-info { font-family: var(--mono); font-size: 0.6rem; color: var(--muted2); line-height: 1.5; } | |
| /* TECH */ | |
| .tech-band { | |
| position: relative; z-index: 1; | |
| border-top: 1px solid var(--b1); border-bottom: 1px solid var(--b1); | |
| padding: 1.5rem 3rem; display: flex; align-items: center; gap: 2rem; flex-wrap: wrap; | |
| } | |
| .tech-lbl { font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); white-space: nowrap; } | |
| .tech-chips { display: flex; gap: 0.5rem; flex-wrap: wrap; } | |
| .chip { | |
| font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.04em; | |
| padding: 0.25rem 0.65rem; border-radius: 5px; border: 1px solid var(--b2); | |
| color: var(--muted2); background: var(--s1); transition: border-color .2s, color .2s; | |
| white-space: nowrap; | |
| } | |
| .chip:hover { border-color: var(--accent); color: var(--accent); } | |
| .chip.hi { border-color: rgba(79,156,249,0.28); color: var(--accent); background: rgba(79,156,249,0.06); } | |
| /* FOOTER */ | |
| footer { | |
| position: relative; z-index: 1; | |
| padding: 1.75rem 3rem; | |
| display: flex; align-items: center; justify-content: space-between; | |
| border-top: 1px solid var(--b1); | |
| } | |
| .footer-l { display: flex; align-items: center; gap: 0.6rem; } | |
| .footer-copy { font-family: var(--mono); font-size: 0.6rem; color: var(--muted); letter-spacing: 0.04em; } | |
| .footer-links { display: flex; gap: 1.5rem; } | |
| .footer-links a { font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); text-decoration: none; transition: color .2s; } | |
| .footer-links a:hover { color: var(--text); } | |
| /* LOADING */ | |
| #loading { | |
| display: none; position: fixed; inset: 0; | |
| background: rgba(8,10,15,0.94); z-index: 500; | |
| flex-direction: column; align-items: center; justify-content: center; gap: 1.75rem; | |
| backdrop-filter: blur(12px); | |
| } | |
| #loading.on { display: flex; } | |
| .ld-icon { | |
| width: 54px; height: 54px; border-radius: 13px; | |
| background: linear-gradient(135deg, var(--accent), var(--a2)); | |
| display: flex; align-items: center; justify-content: center; | |
| font-weight: 800; font-size: 1.4rem; color: #fff; | |
| animation: breathe 2s ease-in-out infinite; | |
| } | |
| @keyframes breathe { 0%,100%{transform:scale(1)} 50%{transform:scale(1.06)} } | |
| .ld-title { font-size: 1rem; font-weight: 700; color: var(--text); letter-spacing: -0.02em; } | |
| .ld-step { font-family: var(--mono); font-size: 0.68rem; color: var(--muted2); transition: opacity .3s; } | |
| .ld-bar { width: 260px; height: 2px; background: var(--s2); border-radius: 1px; overflow: hidden; } | |
| .ld-fill { height: 100%; background: linear-gradient(90deg, var(--accent), var(--a2)); animation: sweep 1.8s ease-in-out infinite; border-radius: 1px; } | |
| @keyframes sweep { 0%{transform:translateX(-100%);width:35%} 50%{width:55%} 100%{transform:translateX(280%);width:35%} } | |
| /* ANIM */ | |
| @keyframes fu { from{opacity:0;transform:translateY(18px)} to{opacity:1;transform:translateY(0)} } | |
| /* RESPONSIVE */ | |
| @media(max-width:900px){ | |
| nav { padding: 1rem 1.5rem; } | |
| nav ul { display: none; } | |
| .hero { padding: 6rem 1.5rem 4rem; } | |
| h1.ht { font-size: 2.8rem; } | |
| .f-row { grid-template-columns: 1fr; } | |
| .btn-go { width: 100%; justify-content: center; } | |
| .sec { padding: 3.5rem 1.5rem; } | |
| .feat-grid { grid-template-columns: 1fr 1fr; } | |
| .pipe-wrap { grid-template-columns: 1fr 1fr; gap: 1.5rem; } | |
| .pipe-wrap::before { display: none; } | |
| .tech-band { padding: 1.2rem 1.5rem; } | |
| footer { padding: 1.5rem; flex-direction: column; gap: 1rem; align-items: flex-start; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="orb orb-1"></div> | |
| <div class="orb orb-2"></div> | |
| <!-- LOADING --> | |
| <div id="loading"> | |
| <div class="ld-icon">S</div> | |
| <div class="ld-title">Sedang menganalisisβ¦</div> | |
| <div class="ld-step" id="ld-step">Menghubungkan ke sumber data</div> | |
| <div class="ld-bar"><div class="ld-fill"></div></div> | |
| </div> | |
| <!-- NAV --> | |
| <nav> | |
| <a href="/" class="nav-brand"> | |
| <div class="brand-icon">S</div> | |
| <span class="brand-name">Senti<b>Scope</b></span> | |
| </a> | |
| <ul> | |
| <li><a href="#fitur">Fitur</a></li> | |
| <li><a href="#pipeline">Pipeline</a></li> | |
| <li><a href="#stack">Stack</a></li> | |
| </ul> | |
| <span class="nav-pill">v2.0 Β· IndoBERT</span> | |
| </nav> | |
| <!-- HERO --> | |
| <section class="hero"> | |
| <div class="eyebrow"><i></i> Platform Analisis Sentimen Media Sosial</div> | |
| <h1 class="ht"> | |
| <span class="l1">Petakan Opini</span> | |
| <span class="l2">Publik Digital</span> | |
| <span class="l3">Secara Real-time</span> | |
| </h1> | |
| <p class="hero-sub"> | |
| Analisis sentimen berbasis IndoBERT & RoBERTa untuk YouTube, Reddit, Instagram, TikTok, dan Google News β | |
| dilengkapi deteksi bot, topic modeling LDA, dan visualisasi jaringan GNN. | |
| </p> | |
| <div class="form-box"> | |
| <div class="f-row"> | |
| <div class="f-group"> | |
| <label for="keyword">Kata Kunci / Topik</label> | |
| <input type="text" id="keyword" class="f-input" placeholder="IKN, pemilu, BBM subsidiβ¦" autocomplete="off"> | |
| </div> | |
| <button class="btn-go" onclick="go()">Analisis β</button> | |
| </div> | |
| <div class="f-group"> | |
| <div class="src-lbl"> | |
| <span>Sumber Data</span> | |
| <b onclick="toggleAll()">Pilih Semua</b> | |
| </div> | |
| <div class="src-grid"> | |
| <div class="src-item"> | |
| <input type="checkbox" id="src-yt" value="youtube" checked> | |
| <label for="src-yt"> | |
| <span class="src-ico">βΆ</span> | |
| <span class="src-info"><span class="src-name">YouTube</span><span class="src-sub">Komentar video</span></span> | |
| <span class="src-box"></span> | |
| </label> | |
| </div> | |
| <div class="src-item"> | |
| <input type="checkbox" id="src-rd" value="reddit" checked> | |
| <label for="src-rd"> | |
| <span class="src-ico">πΎ</span> | |
| <span class="src-info"><span class="src-name">Reddit</span><span class="src-sub">Komentar thread</span></span> | |
| <span class="src-box"></span> | |
| </label> | |
| </div> | |
| <div class="src-item"> | |
| <input type="checkbox" id="src-ig" value="instagram"> | |
| <label for="src-ig"> | |
| <span class="src-ico">πΈ</span> | |
| <span class="src-info"><span class="src-name">Instagram</span><span class="src-sub">via Apify</span></span> | |
| <span class="src-box"></span> | |
| </label> | |
| </div> | |
| <div class="src-item"> | |
| <input type="checkbox" id="src-tt" value="tiktok"> | |
| <label for="src-tt"> | |
| <span class="src-ico">π΅</span> | |
| <span class="src-info"><span class="src-name">TikTok</span><span class="src-sub">via Apify</span></span> | |
| <span class="src-box"></span> | |
| </label> | |
| </div> | |
| <div class="src-item"> | |
| <input type="checkbox" id="src-nw" value="news"> | |
| <label for="src-nw"> | |
| <span class="src-ico">π°</span> | |
| <span class="src-info"><span class="src-name">Google News</span><span class="src-sub">via SerpApi</span></span> | |
| <span class="src-box"></span> | |
| </label> | |
| </div> | |
| </div> | |
| <p class="src-warn" id="src-warn">β Pilih minimal satu sumber data</p> | |
| </div> | |
| <div class="kw-tags" id="kw-tags"></div> | |
| <p class="kw-add-hint">Tekan <b>Enter</b> atau <b>,</b> untuk tambah keyword Β· Maks. 3 keyword</p> | |
| <div class="slider-wrap" style="margin-top:0.75rem"> | |
| <label style="font-family:var(--mono);font-size:0.58rem;letter-spacing:0.14em;text-transform:uppercase;color:var(--muted)">Confidence Threshold</label> | |
| <div class="slider-row"> | |
| <input type="range" id="conf-slider" min="0.3" max="0.9" step="0.05" value="0.6"> | |
| <span class="slider-val" id="conf-val">0.60</span> | |
| </div> | |
| </div> | |
| <p class="f-hint" style="margin-top:0.5rem">Prediksi di bawah threshold akan ditandai <b>Uncertain</b></p> | |
| </div> | |
| <div class="stats"> | |
| <div class="stat"><span class="stat-n">9+</span><span class="stat-l">Analisis</span></div> | |
| <div class="stat"><span class="stat-n">5</span><span class="stat-l">Sumber</span></div> | |
| <div class="stat"><span class="stat-n">3</span><span class="stat-l">Model AI</span></div> | |
| <div class="stat"><span class="stat-n">ID</span><span class="stat-l">Bahasa</span></div> | |
| </div> | |
| <div class="scroll-down"> | |
| <span>Scroll</span> | |
| <div class="scroll-mouse"><div class="scroll-dot"></div></div> | |
| </div> | |
| </section> | |
| <!-- FEATURES --> | |
| <section class="sec" id="fitur"> | |
| <p class="sec-tag">Kapabilitas</p> | |
| <h2 class="sec-h">Analisis multidimensional <em>dalam satu platform</em></h2> | |
| <div class="feat-grid"> | |
| <div class="feat"> | |
| <div class="feat-ico ic-b">π§ </div> | |
| <div class="feat-name">Sentimen NLP</div> | |
| <p class="feat-desc">Klasifikasi positif / negatif / netral menggunakan transformer IndoBERT fine-tuned pada data bahasa Indonesia.</p> | |
| </div> | |
| <div class="feat"> | |
| <div class="feat-ico ic-p">πΈ</div> | |
| <div class="feat-name">Deteksi Bot</div> | |
| <p class="feat-desc">Identifikasi akun tidak otentik via cosine similarity dan graph centrality dengan threshold adaptif berbasis GNN.</p> | |
| </div> | |
| <div class="feat"> | |
| <div class="feat-ico ic-g">π</div> | |
| <div class="feat-name">Topic Modeling</div> | |
| <p class="feat-desc">Ekstraksi topik laten dari komentar menggunakan LDA dengan 3 komponen, disajikan sebagai word cluster.</p> | |
| </div> | |
| <div class="feat"> | |
| <div class="feat-ico ic-a">π</div> | |
| <div class="feat-name">Prediksi Tren</div> | |
| <p class="feat-desc">Proyeksi arah sentimen menggunakan regresi linier pada urutan data masuk untuk melihat tren publik.</p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- PIPELINE --> | |
| <section class="sec" id="pipeline" style="padding-top:0"> | |
| <p class="sec-tag">Cara Kerja</p> | |
| <h2 class="sec-h">Pipeline <em>end-to-end</em> otomatis</h2> | |
| <div class="pipe-wrap"> | |
| <div class="pipe"><div class="pipe-circle">01</div><div class="pipe-name">Input</div><div class="pipe-info">Kata kunci & pilih sumber data</div></div> | |
| <div class="pipe"><div class="pipe-circle">02</div><div class="pipe-name">Scraping</div><div class="pipe-info">YouTube, Reddit, Instagram, TikTok & Google News</div></div> | |
| <div class="pipe"><div class="pipe-circle">03</div><div class="pipe-name">Preprocessing</div><div class="pipe-info">Cleaning, normalisasi, stopword removal</div></div> | |
| <div class="pipe"><div class="pipe-circle">04</div><div class="pipe-name">Inference</div><div class="pipe-info">IndoBERT + GNN + LDA secara paralel</div></div> | |
| <div class="pipe"><div class="pipe-circle">05</div><div class="pipe-name">Dashboard</div><div class="pipe-info">Visualisasi interaktif + ekspor CSV</div></div> | |
| </div> | |
| </section> | |
| <!-- TECH --> | |
| <div class="tech-band" id="stack"> | |
| <span class="tech-lbl">Tech Stack</span> | |
| <div class="tech-chips"> | |
| <span class="chip hi">IndoBERT</span> | |
| <span class="chip hi">RoBERTa-ID</span> | |
| <span class="chip hi">GNN</span> | |
| <span class="chip">Flask</span> | |
| <span class="chip">PyTorch</span> | |
| <span class="chip">scikit-learn</span> | |
| <span class="chip">NetworkX</span> | |
| <span class="chip">LDA</span> | |
| <span class="chip">YouTube API</span> | |
| <span class="chip">Reddit PRAW</span> | |
| <span class="chip hi">Apify Instagram</span> | |
| <span class="chip hi">Apify TikTok</span> | |
| <span class="chip hi">SerpApi News</span> | |
| <span class="chip">HuggingFace Spaces</span> | |
| <span class="chip">Docker</span> | |
| </div> | |
| </div> | |
| <!-- FOOTER --> | |
| <footer> | |
| <div class="footer-l"> | |
| <div class="brand-icon" style="width:22px;height:22px;font-size:0.65rem;border-radius:5px">S</div> | |
| <span class="footer-copy">SentiScope © 2025 β Social Media Intelligence Platform</span> | |
| </div> | |
| <div class="footer-links"> | |
| <a href="/">Home</a> | |
| <a href="/download">Download CSV</a> | |
| </div> | |
| </footer> | |
| <script> | |
| const STEPS = [ | |
| 'Menghubungkan ke sumber dataβ¦', | |
| 'Mengambil komentar YouTubeβ¦', | |
| 'Mengambil thread Redditβ¦', | |
| 'Menjalankan model IndoBERTβ¦', | |
| 'Menghitung topic modeling LDAβ¦', | |
| 'Menganalisis jaringan botβ¦', | |
| 'Menyusun hasil visualisasiβ¦', | |
| ]; | |
| let si = 0, st; | |
| function tick() { | |
| si = (si + 1) % STEPS.length; | |
| const el = document.getElementById('ld-step'); | |
| el.style.opacity = 0; | |
| setTimeout(() => { el.textContent = STEPS[si]; el.style.opacity = 1; }, 250); | |
| st = setTimeout(tick, 2000); | |
| } | |
| function getSelectedSources() { | |
| const boxes = document.querySelectorAll('.src-item input[type="checkbox"]:checked'); | |
| const vals = Array.from(boxes).map(b => b.value); | |
| if (vals.length === 0) return null; | |
| if (vals.length === 5) return 'all'; | |
| return vals.join(','); | |
| } | |
| function toggleAll() { | |
| const boxes = document.querySelectorAll('.src-item input[type="checkbox"]'); | |
| const anyUnchecked = Array.from(boxes).some(b => !b.checked); | |
| boxes.forEach(b => { b.checked = anyUnchecked; }); | |
| const btn = document.querySelector('.src-lbl b'); | |
| btn.textContent = anyUnchecked ? 'Batal Semua' : 'Pilih Semua'; | |
| } | |
| // sync toggle-all label | |
| document.addEventListener('change', () => { | |
| const boxes = document.querySelectorAll('.src-item input[type="checkbox"]'); | |
| const btn = document.querySelector('.src-lbl b'); | |
| const allOn = Array.from(boxes).every(b => b.checked); | |
| btn.textContent = allOn ? 'Batal Semua' : 'Pilih Semua'; | |
| document.getElementById('src-warn').classList.remove('show'); | |
| }); | |
| // ββ Multi-keyword management ββ | |
| const kwTags = []; | |
| document.getElementById('keyword').addEventListener('keydown', function(e) { | |
| if ((e.key === 'Enter' || e.key === ',') && this.value.trim()) { | |
| e.preventDefault(); | |
| addKeyword(this.value.trim().replace(',','')); | |
| this.value = ''; | |
| } | |
| }); | |
| function addKeyword(kw) { | |
| if (!kw || kwTags.includes(kw) || kwTags.length >= 3) return; | |
| kwTags.push(kw); | |
| renderTags(); | |
| } | |
| function removeKeyword(kw) { | |
| const idx = kwTags.indexOf(kw); | |
| if (idx > -1) kwTags.splice(idx, 1); | |
| renderTags(); | |
| } | |
| function renderTags() { | |
| const container = document.getElementById('kw-tags'); | |
| container.innerHTML = kwTags.map(k => | |
| `<span class="kw-tag">${k}<button onclick="removeKeyword('${k}')">Γ</button></span>` | |
| ).join(''); | |
| } | |
| // ββ Confidence slider ββ | |
| document.getElementById('conf-slider').addEventListener('input', function() { | |
| document.getElementById('conf-val').textContent = parseFloat(this.value).toFixed(2); | |
| }); | |
| async function go() { | |
| const inputKw = document.getElementById('keyword').value.trim(); | |
| if (inputKw) addKeyword(inputKw); | |
| document.getElementById('keyword').value = ''; | |
| const allKw = kwTags.length ? kwTags : [inputKw]; | |
| const kw = allKw.filter(Boolean).join(','); | |
| const src = getSelectedSources(); | |
| const confTh = parseFloat(document.getElementById('conf-slider').value); | |
| if (!kw) { | |
| const inp = document.getElementById('keyword'); | |
| inp.style.borderColor = '#ef4444'; | |
| inp.focus(); | |
| setTimeout(() => inp.style.borderColor = '', 1500); | |
| return; | |
| } | |
| if (!src) { | |
| document.getElementById('src-warn').classList.add('show'); | |
| return; | |
| } | |
| document.getElementById('loading').classList.add('on'); | |
| document.getElementById('ld-step').textContent = STEPS[0]; | |
| st = setTimeout(tick, 2000); | |
| try { | |
| const r = await fetch('/analyze', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ keyword: kw, source: src, conf_threshold: confTh }) | |
| }); | |
| const d = await r.json(); | |
| clearTimeout(st); | |
| document.getElementById('loading').classList.remove('on'); | |
| sessionStorage.setItem('analysisResult', JSON.stringify({ keyword: kw, source: src, ...d })); | |
| window.location.href = '/result'; | |
| } catch(e) { | |
| clearTimeout(st); | |
| document.getElementById('loading').classList.remove('on'); | |
| alert('Terjadi kesalahan. Periksa koneksi dan konfigurasi API key.'); | |
| } | |
| } | |
| document.getElementById('keyword').addEventListener('keydown', e => { if (e.key === 'Enter') go(); }); | |
| // Feature reveal | |
| const feats = document.querySelectorAll('.feat'); | |
| const io = new IntersectionObserver(entries => { | |
| entries.forEach((e, i) => { if (e.isIntersecting) setTimeout(() => e.target.classList.add('vis'), i * 80); }); | |
| }, { threshold: 0.1 }); | |
| feats.forEach(f => io.observe(f)); | |
| </script> | |
| </body> | |
| </html> |