Includes fixes found while reviewing the app: - Results: open each result by a type+agent+id key, so a video and a material draft with the same id no longer open each other's popup - AuthGate: clear the query cache during render, before pages build their queries, and remount pages on organization switch (pages no longer stay on skeletons for up to a minute after sign-in or refresh) - Instruction: keep only failed rules after a partial approve, so retrying does not create the successful schedules twice; drop the monthly note once count or frequency is edited - Parser/schedules: never schedule a count below one - Audio: ignore the end event of a cancelled utterance when changing speed - Downloads: revoke the object URL later so Safari/Firefox can read it - Results: refetch SCORM content when any part's revision changes; show a failed video as failed instead of "still rendering" Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
334 lines
84 KiB
HTML
334 lines
84 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="id">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<meta name="description" content="Learning Lab Express by Bawana. Konsol development terhubung ke engine learning-lab.">
|
|
<title>Learning Lab Express · DEV</title>
|
|
<style>:root{--blue:#2563eb;--blue-dark:#194dcc;--navy:#142d50;--ink:#1b2c46;--muted:#768399;--line:#e6ebf2;--bg:#f7f9fc;--light:#eef5ff;--green:#14866b;--radius:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:var(--ink);font-size:14px}
|
|
.admin-menu{margin-top:26px;border-top:1px solid var(--line);padding-top:16px}.admin-menu summary{list-style:none;display:flex;align-items:center;justify-content:space-between;padding:12px;color:var(--muted);font-size:11px;cursor:pointer}.admin-menu summary::-webkit-details-marker{display:none}.admin-menu summary svg{width:14px}.admin-menu[open] summary svg{transform:rotate(180deg)}.auto-hero-note{display:flex;align-items:center;gap:7px;font-size:10px;color:#6c83a3;margin-top:18px}.auto-hero-note svg{width:14px;height:14px;color:var(--blue)}.auto-flow{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:22px 0 18px;padding:0 3px;color:#607594;font-size:11px}.auto-flow>span{display:flex;align-items:center;gap:9px}.auto-flow b{color:var(--blue);background:#eaf2ff;border-radius:50%;display:grid;place-items:center;width:27px;height:27px;font-size:10px}.auto-flow>svg{width:15px;color:#9eafc7}.upload-box.upload-compact{display:flex;align-items:center;gap:18px;text-align:left;padding:25px 28px;margin-bottom:25px}.upload-compact .upload-symbol{margin:0;width:45px;height:45px;flex-shrink:0}.upload-compact>div{flex:1}.upload-compact h3{font-size:14px}.upload-compact p{font-size:11px;margin:6px 0}.upload-compact small{font-size:9px}.upload-compact .btn{flex-shrink:0}
|
|
@media(max-width:600px){.auto-flow{flex-direction:column;align-items:flex-start;gap:12px;margin:18px 0}.auto-flow>svg{display:none}.upload-box.upload-compact{flex-wrap:wrap;padding:20px;gap:13px}.upload-compact>div{flex-basis:calc(100% - 60px)}.upload-compact .btn{width:100%}.auto-hero-note{line-height:1.6}.admin-menu{margin-top:0;padding-top:0;border:0}.admin-menu summary{padding:10px 6px;font-size:10px}}
|
|
*{box-sizing:border-box}body{margin:0;background:var(--bg)}button,input,select,textarea{font:inherit}button,a,input,select,textarea{outline-offset:4px}button{cursor:pointer}button:disabled{cursor:not-allowed;opacity:.48}a{color:inherit;text-decoration:none}button{color:inherit}button:focus-visible,a:focus-visible{outline:3px solid #9dbfff}svg{width:20px;height:20px;flex-shrink:0;vertical-align:middle}p{line-height:1.7;margin:0;color:var(--muted)}h1,h2,h3,h4{margin:0;letter-spacing:-.035em}h1{font-size:29px;line-height:1.25}h2{font-size:23px}h3{font-size:16px;letter-spacing:-.02em}h4{font-size:14px}small{font-size:11px;color:var(--muted)}[hidden]{display:none!important}
|
|
.brand{display:flex;align-items:center;gap:10px;line-height:1.15;font-size:16px;font-weight:750;letter-spacing:-.5px;white-space:nowrap}.brand b{font-weight:500;display:block;font-size:14px;margin-top:4px;letter-spacing:.1px}.brand small{display:block;font-size:9px;letter-spacing:1.5px;text-transform:uppercase;margin-top:7px;font-weight:600;color:#8493aa}.brand-mark{width:40px;height:42px;background:var(--blue);border-radius:11px;display:flex;align-items:center;justify-content:center;color:#fff;box-shadow:0 5px 10px #2563eb16}.brand-mark svg{width:24px;height:24px}
|
|
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:42px;padding:10px 17px;border-radius:8px;border:1px solid #dce3ee;background:white;font-size:12px;font-weight:650;white-space:nowrap;transition:background .15s,transform .15s}.btn:hover{background:#f5f8fd}.btn.primary{color:#fff;background:var(--blue);border-color:var(--blue);box-shadow:0 3px 6px #2563eb12}.btn.primary:hover{background:var(--blue-dark)}.btn.light{background:var(--light);border-color:#dfebff;color:var(--blue)}.btn.small{min-height:34px;padding:7px 11px;font-size:11px}.btn svg{width:16px;height:16px}.btn.danger{color:#b64747}.wide{width:100%}.icon-btn{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:0;border-radius:7px;padding:7px;color:#8290a5}.icon-btn:hover{background:var(--light);color:var(--blue)}.icon-btn svg{width:18px;height:18px}.text-btn{border:0;background:transparent;padding:0;color:var(--blue);font-size:12px;font-weight:600;display:inline-flex;align-items:center;gap:6px}.text-btn svg{width:15px;height:15px}.badge,.status{display:inline-flex;align-items:center;gap:5px;border-radius:5px;padding:5px 8px;font-size:10px;font-weight:650;line-height:1;white-space:nowrap}.badge.neutral{background:#eff3f8;color:#718098}.badge.blue{color:#2563eb;background:#edf4ff}.badge.purple{color:#8063bb;background:#f3effb}.badge.amber{color:#a78126;background:#fff7df}.status.ready{color:var(--green);background:#e9f7f2}.status.draft{color:#9a7a37;background:#fff6df}.dot{width:5px;height:5px;background:currentColor;border-radius:50%}
|
|
label{display:block;font-size:12px;font-weight:650;margin:0 0 8px}input:not([type=checkbox]):not([type=radio]):not([type=file]),select,textarea{width:100%;border:1px solid #dce3ed;padding:12px 13px;border-radius:8px;background:white;min-height:43px;color:var(--ink);transition:border-color .15s;outline-color:var(--blue)}input:focus,select:focus,textarea:focus{border-color:var(--blue)}input::placeholder,textarea::placeholder{color:#a3adbc}textarea{resize:vertical;line-height:1.65}input[type=checkbox]{accent-color:var(--blue);width:15px;height:15px;flex-shrink:0;cursor:pointer}.check-label{display:flex;align-items:center;gap:7px;font-weight:500;margin:0;line-height:1.6}.field{margin-bottom:22px}.field small{display:block;line-height:1.6;margin-top:7px}.field-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 20px}.error{color:#c35252;font-size:12px;margin-top:10px}.inline-note{display:flex;gap:9px;padding:13px 15px;background:#f5f8fc;border-radius:8px;font-size:11px;line-height:1.75;color:var(--muted)}.inline-note svg{width:16px;height:16px;flex-shrink:0;margin-top:2px;color:var(--blue)}
|
|
.login-layout{min-height:100vh;display:grid;grid-template-columns:55% 45%;background:white}.login-story{padding:44px 8%;background:#f0f6ff;display:flex;flex-direction:column;position:relative;overflow:hidden}.login-story:after{content:"";position:absolute;right:-260px;bottom:-370px;width:720px;height:720px;border:1px solid #dce9fc;border-radius:50%;pointer-events:none}.login-copy{margin:auto 0;padding:54px 0 45px;position:relative;z-index:1}.eyebrow{font-size:9px;font-weight:750;color:var(--blue);letter-spacing:1.6px}.login-copy h1{font-size:42px;line-height:1.22;letter-spacing:-1.6px;margin:22px 0}.login-copy>p{font-size:14px;max-width:420px;color:#74849b}.login-diagram{margin:35px 0 28px;width:390px;max-width:100%;position:relative}.mini-source,.mini-output{display:flex;align-items:center;gap:13px;padding:16px 18px;background:white;border:1px solid #e3ebf8;border-radius:11px;box-shadow:0 5px 10px #24457604;font-weight:650;font-size:12px}.mini-source{margin-right:30px}.mini-output{margin-left:30px}.mini-source small,.mini-output small{display:block;margin-top:5px;font-size:10px;font-weight:450}.mini-check{margin-left:auto;color:#31a287;background:#ecf8f3;width:22px;height:22px;text-align:center;border-radius:50%;line-height:22px}.connector{height:43px;display:flex;align-items:center;justify-content:center;gap:12px;color:var(--blue)}.connector i{display:block;width:1px;height:11px;background:#b3c8ee}.connector svg{width:24px;height:24px}.output-icon{background:#ebf3ff;border-radius:8px;padding:10px;color:var(--blue)}.mini-output .status{margin-left:auto}.login-benefits{display:flex;flex-direction:column;gap:13px;color:#607594;font-size:11px}.login-benefits>span{display:flex;align-items:center;gap:9px}.login-benefits svg{width:16px;height:16px;color:#6b8cc4}.login-footer{position:relative;z-index:1;font-size:8px;color:#8ba0bc;letter-spacing:1px;display:flex;justify-content:space-between;gap:12px}.login-footer span{letter-spacing:0}.login-panel{display:flex;align-items:center;justify-content:center;padding:45px}.login-form-wrap{width:360px;max-width:100%}.login-form-wrap h2{font-size:26px;margin-top:22px;line-height:1.3}.login-form-wrap>p{font-size:12px;margin:12px 0 30px}.login-form-wrap form>label{margin-top:20px}.password-field{position:relative}.password-field input{padding-right:45px!important}.password-field button{position:absolute;right:5px;top:6px;background:none;border:0;padding:6px;color:#929eaf}.password-field svg{width:18px;height:18px}.login-small{display:flex;align-items:center;justify-content:space-between;font-size:10px;color:#8e9aad;margin:18px 0 26px}.login-small label{font-size:10px;font-weight:500}.login-small input{width:13px;height:13px}.demo-login{margin-top:26px;display:flex;gap:10px;border:1px solid var(--line);border-radius:9px;padding:14px}.demo-login>svg{color:var(--blue);width:17px;height:17px;flex-shrink:0;margin-top:2px}.demo-login p{font-size:10px;line-height:1.8;color:#8390a2}.login-form-wrap .login-bottom{margin-top:46px;font-size:10px;text-align:center;color:#a3adbc}.login-bottom span{margin-left:6px;color:#6c86ad}
|
|
.app{display:flex;min-height:100vh}.sidebar{width:238px;flex-shrink:0;background:white;position:fixed;inset:0 auto 0 0;border-right:1px solid var(--line);padding:29px 18px 14px;display:flex;flex-direction:column;z-index:5}.sidebar>.brand{margin:0 13px 26px;font-size:14px}.sidebar .brand b{font-size:12px}.sidebar .brand-mark{width:35px;height:38px;border-radius:9px}.sidebar .brand small{font-size:8px}.workspace{display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:9px;padding:11px 10px;margin-bottom:30px;font-size:11px;font-weight:650}.workspace-icon{display:flex;align-items:center;justify-content:center;background:#eef3fa;border-radius:7px;width:29px;height:29px;color:#7086a6}.workspace small{display:block;font-weight:450;font-size:9px;margin-top:3px}.workspace>svg{width:13px;height:13px;margin-left:auto;color:#94a1b4}.nav-label{font-size:8px;font-weight:700;color:#a0aabc;letter-spacing:1.5px;margin:0 12px 14px}nav{display:flex;flex-direction:column;gap:5px}nav button{display:flex;align-items:center;gap:11px;padding:13px 13px;border:0;background:none;border-radius:8px;color:#7b879b;font-size:12px;text-align:left;font-weight:550;width:100%}nav button svg{width:18px;height:18px;color:#8995a9}nav button:hover{background:#f6f9fe}nav button.active{background:#edf4ff;color:#2563eb;font-weight:650}nav button.active svg{color:#2563eb}.nav-count{font-size:9px;background:#eef2f7;padding:3px 6px;border-radius:4px;margin-left:auto;color:#8895a9}.active .nav-count{background:#dceaff;color:#2563eb}.sidebar-help{margin: auto 0 16px;border:1px solid #e5edf9;background:#f8fbff;border-radius:10px;padding:16px 13px}.sidebar-help>svg{color:#7091c2;width:18px;height:18px;display:block;margin-bottom:11px}.sidebar-help b{font-size:11px;font-weight:650}.sidebar-help p{font-size:10px;line-height:1.7;margin:8px 0 12px}.sidebar-help button{display:flex;align-items:center;gap:7px;color:var(--blue);font-size:10px;font-weight:650;border:0;padding:0;background:none}.sidebar-help button svg{width:13px;height:13px}.profile{display:flex;gap:9px;align-items:center;padding:14px 5px 0;border-top:1px solid var(--line)}.avatar{height:32px;width:32px;background:#edf3ff;color:#527fc8;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:650}.profile b{font-size:11px;font-weight:650}.profile small{display:block;font-size:9px;margin-top:4px}.profile>.icon-btn{margin-left:auto}
|
|
.workspace-main{margin-left:238px;width:calc(100% - 238px);min-height:100vh;display:flex;flex-direction:column}.topbar{height:72px;display:flex;justify-content:space-between;align-items:center;background:white;border-bottom:1px solid var(--line);padding:0 34px;gap:15px}.breadcrumb{font-size:11px;color:#94a0b1;white-space:nowrap}.breadcrumb span{margin:0 10px;color:#c1c9d5}.breadcrumb b{color:#64738a;font-weight:550}.topbar-right{display:flex;align-items:center;gap:19px;font-size:10px;color:#8b97a9}.demo-indicator{display:flex;align-items:center;gap:6px}.demo-indicator i{width:5px;height:5px;border-radius:50%;background:#d6a34b}.demo-strip{display:flex;align-items:center;gap:9px;margin:23px 34px 0;padding:10px 13px;border:1px solid #e1ebfb;background:#f0f6ff;border-radius:7px;font-size:10px;color:#7b91b2;line-height:1.5}.demo-strip svg{width:14px;height:14px;color:#7193c6}.demo-strip-tag{margin-left:auto;font-size:8px;letter-spacing:1px;font-weight:700;color:#7b96be}.app main{padding:28px 34px 30px;width:100%;max-width:1500px;align-self:center}.page-head{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;margin-bottom:25px}.page-head p{font-size:12px;margin-top:8px}.head-actions{display:flex;gap:9px;align-items:center}.app-footer{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin: auto 34px 0;padding:18px 0;border-top:1px solid var(--line);font-size:9px;color:#99a4b5}.app-footer>span:first-child{color:#7493c3}.app-footer>span:last-child{margin-left:auto;font-size:8px}.card{background:white;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}.card-head{padding:21px 23px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;gap:10px}.card-head h3{font-size:14px}.card-head p{font-size:10px;margin-top:5px}.card-body{padding:23px}.hero{position:relative;display:grid;grid-template-columns:1.1fr 1fr;background:#edf4ff;border:1px solid #dfeaff;border-radius:14px;padding:30px 30px 29px;align-items:center;gap:15px;min-height:245px;margin-bottom:23px}.hero .eyebrow{font-size:8px;letter-spacing:1.4px}.hero h2{font-size:31px;line-height:1.23;letter-spacing:-1px;margin:15px 0 10px}.hero p{font-size:11px;max-width:375px;color:#7e91ad}.hero .head-actions{margin-top:21px}.hero-art{position:relative;justify-self:center;width:310px;max-width:100%}.hero-art .mini-source{font-size:10px;padding:13px;max-width:230px;transform:rotate(-3deg);margin-right:0}.hero-art .mini-source+.mini-source{position:relative;margin-top:8px;margin-left:25px;transform:rotate(1deg)}.hero-art .mini-source small{font-size:8px}.hero-art .file-icon{width:29px;height:34px;font-size:8px}.hero-art .connector{height:30px;margin-left:80px}.hero-art .mini-output{margin-left:45px;padding:13px;font-size:10px;position:relative;z-index:2;box-shadow:0 7px 15px #2563eb08}.hero-art .mini-output small{font-size:8px}.hero-art .output-icon{padding:8px}.hero-art .output-icon svg{width:17px;height:17px}.hero-art:before{content:"";position:absolute;border:1px dashed #c3d6f4;border-radius:50%;height:245px;width:245px;top:-10px;right:10px}
|
|
.metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px;margin-bottom:23px}.metric{background:white;border:1px solid var(--line);border-radius:11px;padding:19px 19px 16px;position:relative}.metric>span{font-size:10px;color:#8c98aa}.metric strong{display:block;font-size:27px;letter-spacing:-1px;font-weight:650;margin:10px 0 8px}.metric small{font-size:9px;color:#9aa5b5}.metric i{position:absolute;right:16px;top:16px;background:#f2f6fc;border-radius:8px;padding:8px;color:#7f9bc5}.metric i svg{width:16px;height:16px}.setup-row{padding:17px 21px;display:flex;align-items:center;gap:24px;margin-bottom:23px}.setup-row>b{font-size:11px;white-space:nowrap}.steps{display:flex;justify-content:space-between;width:100%;gap:12px}.step{display:flex;align-items:center;gap:9px;font-size:10px;color:#8a98ac;background:none;border:0;padding:0;text-align:left}.step>i{height:25px;width:25px;display:flex;align-items:center;justify-content:center;border:1px solid #dfe7f3;border-radius:50%;font-size:9px;font-style:normal;color:#8b9cb6;background:#fafcff}.step.done>i{background:#ebf8f1;color:#3b9a77;border-color:#d9efdf}.step small{font-size:8px;display:block;margin-top:4px}.step-arrow{color:#c2cddd;font-size:15px}.dashboard-grid{display:grid;grid-template-columns:1.6fr 1fr;gap:21px;margin-bottom:23px}.empty{display:flex;flex-direction:column;align-items:center;text-align:center;padding:36px 25px;color:#8090a6}.empty-icon{color:#8da9d6;background:#f2f7fe;width:48px;height:48px;border-radius:12px;display:flex;align-items:center;justify-content:center;margin-bottom:14px}.empty-icon svg{width:24px;height:24px}.empty h3{font-size:13px;color:#596d8b;margin-bottom:8px}.empty p{font-size:10px;max-width:310px;margin-bottom:18px}.schedule-mini{padding:22px}.schedule-mini .clock-circle{background:#edf4ff;color:#7499ce;display:inline-flex;padding:11px;border-radius:50%;margin-bottom:17px}.schedule-mini h3{font-size:14px;margin-bottom:8px}.schedule-mini p{font-size:10px;line-height:1.75}.schedule-mini>.btn{margin-top:18px}.schedule-meta{border-top:1px solid var(--line);margin-top:17px;padding-top:15px;display:flex;justify-content:space-between;font-size:10px;color:#8491a5}.schedule-meta b{font-size:10px;color:#566e91;font-weight:600}.section-heading{display:flex;justify-content:space-between;align-items:center;margin:26px 0 15px;gap:12px}.section-heading p{font-size:10px;margin-top:6px}.section-heading h3{font-size:14px}.match-grid{display:grid;grid-template-columns:1fr 1fr;gap:15px}.match-card{padding:18px}.match-card .pair-names{display:flex;flex-direction:column;gap:10px;font-size:11px;line-height:1.5;font-weight:600}.pair-names span{display:flex;align-items:center;gap:8px}.pair-names svg{width:15px;height:15px;color:#93a7c5}.match-tags{display:flex;gap:5px;flex-wrap:wrap;margin:15px 0}.tag{display:inline-block;font-size:9px;color:#8493a8;background:#f4f6fa;border-radius:4px;padding:4px 6px}.match-card .match-footer{display:flex;justify-content:space-between;align-items:center;gap:8px;border-top:1px solid var(--line);padding-top:13px}.match-footer small{font-size:9px}
|
|
.file-icon{width:34px;height:40px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border-radius:6px;background:#eef2f7;font-size:9px;font-weight:700;color:#8290a4;border:1px solid #e6ebf3}.file-icon.pdf{color:#d47c7c;background:#fff2f2;border-color:#fae8e8}.file-icon.pptx{color:#c58e5d;background:#fff5ea;border-color:#f8eadb}.file-icon.docx{color:#6e94d6;background:#f0f5ff;border-color:#e2eafb}.file-icon.txt,.file-icon.md{color:#689d86;background:#eef9f3;border-color:#def0e5}.upload-box{border:1.5px dashed #c9d9ef;border-radius:12px;background:#f9fbff;text-align:center;padding:31px 24px;margin-bottom:18px;transition:background .15s}.upload-box.drag{background:#eaf2ff;border-color:var(--blue)}.upload-symbol{display:inline-flex;padding:12px;background:#eaf2ff;border:1px solid #deebff;color:#7299d5;border-radius:12px;margin-bottom:14px}.upload-box h3{font-size:14px;margin-bottom:8px}.upload-box p{font-size:10px;margin-bottom:17px}.upload-box .upload-limit{font-size:9px;margin:11px 0 0}.toolbar{padding:17px 21px;display:flex;justify-content:space-between;gap:15px;align-items:center;border-bottom:1px solid var(--line)}.toolbar h3{font-size:13px}.toolbar .toolbar-controls{display:flex;gap:10px;max-width:520px;width:55%}.search{position:relative;width:100%;max-width:280px}.search>svg{position:absolute;left:11px;top:11px;width:15px;height:15px;color:#9aa7ba}.search input{padding:9px 12px 9px 34px!important;font-size:10px;min-height:35px!important}.toolbar select{padding:8px 11px;font-size:10px;min-height:35px;width:155px}.table-wrap{overflow:auto}table{border-collapse:collapse;width:100%;text-align:left}th{font-size:9px;font-weight:650;color:#9aa6b7;background:#fbfcfe;padding:13px 21px;border-bottom:1px solid var(--line);white-space:nowrap}td{padding:17px 21px;border-bottom:1px solid #eff2f7;font-size:10px;color:#8390a4;vertical-align:middle}tbody tr:last-child td{border-bottom:0}.file-name{display:flex;gap:12px;align-items:center;min-width:200px}.file-name b{font-size:11px;display:block;font-weight:600;color:#455a78;line-height:1.5;max-width:280px;overflow-wrap:anywhere}.file-name small{font-size:9px;display:block;margin-top:5px}.table-actions{white-space:nowrap;text-align:right}.table-note{border-top:1px solid var(--line);font-size:9px;color:#9aa7ba;padding:13px 21px}.notice-row{display:flex;align-items:center;gap:10px;font-size:10px;color:#8396b2;background:#edf4ff;border:1px solid #e0eafb;border-radius:8px;padding:12px 15px;margin-bottom:20px}.notice-row svg{width:15px;height:15px;flex-shrink:0}.notice-row button{margin-left:auto;white-space:nowrap;font-size:10px}.two-column{display:grid;grid-template-columns:1.55fr 1fr;align-items:start;gap:23px}.form-card .card-body{padding:25px}.form-section-title{font-size:11px;font-weight:700;color:#4c6280;margin-bottom:21px}.form-footer{border-top:1px solid var(--line);padding:17px 25px;display:flex;justify-content:space-between;align-items:center;gap:15px}.form-footer small{font-size:9px;line-height:1.6}.side-card{padding:23px}.side-card h3{font-size:13px;margin-bottom:12px}.side-card p{font-size:11px;margin-bottom:18px}.side-list{margin:0;padding:0;list-style:none;counter-reset:steps}.side-list li{counter-increment:steps;display:flex;align-items:flex-start;gap:11px;font-size:11px;color:#7c8da5;padding:12px 0;border-bottom:1px solid #f0f3f8;line-height:1.7}.side-list li:before{content:counter(steps);font-size:9px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:#edf4ff;color:#7b9ac7;flex-shrink:0;width:22px;height:22px}.side-list li:last-child{border-bottom:0}.mode-box{display:flex;gap:12px;background:#f7faff;border:1px solid #e3ecfa;border-radius:10px;padding:16px;margin-bottom:26px}.mode-box>span{background:#e9f2ff;color:#6d95d1;border-radius:8px;padding:9px;height:38px}.mode-box b{font-size:11px}.mode-box p{font-size:10px;line-height:1.7;margin-top:5px}.mode-box .badge{margin-left:auto;height:22px;font-size:8px}.output-checks{display:grid;grid-template-columns:1fr 1fr;gap:12px;padding:16px;border:1px solid var(--line);border-radius:8px}.output-checks label{font-size:11px}.switch-row{display:flex;justify-content:space-between;align-items:center;padding:18px;background:#f8fbff;border:1px solid #e6eefb;border-radius:9px;margin-bottom:25px}.switch-row b{font-size:12px}.switch-row p{font-size:10px;margin-top:5px}.switch{width:35px;height:20px;position:relative;display:inline-flex}.switch input{width:100%;height:100%;opacity:0;position:absolute;z-index:1;margin:0}.switch i{position:absolute;inset:0;background:#d7dfeb;border-radius:20px;transition:background .2s}.switch i:after{content:"";height:14px;width:14px;background:white;border-radius:50%;position:absolute;left:3px;top:3px;transition:transform .2s}.switch input:checked+i{background:var(--blue)}.switch input:checked+i:after{transform:translateX(15px)}.next-run{margin:19px 0;padding:16px;border:1px solid #dfebfb;background:#f4f8ff;border-radius:9px}.next-run small{font-size:9px}.next-run strong{display:block;font-size:12px;line-height:1.7;color:#5a78a2;margin-top:7px}.schedule-tip{padding:16px;background:#fafbfd;border:1px solid var(--line);border-radius:8px;font-size:10px;line-height:1.8;color:#8b98ab}
|
|
.results-summary{display:flex;gap:7px;margin-top:13px}.result-list{padding:0 21px}.result-row{display:flex;align-items:center;gap:15px;padding:21px 0;border-bottom:1px solid var(--line)}.result-row:last-child{border:0}.result-cover{width:46px;height:52px;background:#edf5ff;border:1px solid #e3edfc;border-radius:8px;display:flex;align-items:center;justify-content:center;flex-shrink:0;color:#7297ce}.result-main{flex:1;min-width:0}.result-title{font-size:12px;color:#455a79;font-weight:650;background:none;border:0;padding:0;text-align:left;line-height:1.55}.result-meta{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:7px;color:#98a4b5;font-size:9px}.result-meta .tag{padding:3px 5px;font-size:8px}.result-actions{display:flex;gap:7px;align-items:center}.mini-result{display:flex;align-items:center;gap:11px;padding:18px 22px;border-bottom:1px solid #f0f3f8}.mini-result:last-child{border:0}.mini-result .result-cover{width:35px;height:40px}.mini-result .result-cover svg{width:18px;height:18px}.mini-result button{border:0;background:transparent;font-size:11px;text-align:left;padding:0;font-weight:600;line-height:1.5;color:#526986}.mini-result small{font-size:9px;display:block;margin-top:5px}.mini-result .status{margin-left:auto;font-size:8px}.mini-result>div:nth-child(2){min-width:0}
|
|
dialog{padding:0;border:1px solid #e6ebf2;border-radius:15px;box-shadow:0 28px 95px #142d5038;width:740px;max-width:calc(100vw - 30px);max-height:92vh;color:var(--ink);overflow:hidden;background:white}dialog::backdrop{background:#142d5070;backdrop-filter:blur(3px)}dialog.preview{width:1030px}.modal-head{padding:23px 25px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;gap:15px;align-items:flex-start}.modal-head h2{font-size:20px;letter-spacing:-.5px}.modal-head p{font-size:10px;line-height:1.7;margin-top:7px}.modal-body{padding:24px 25px;max-height:65vh;overflow:auto}.modal-foot{display:flex;align-items:center;justify-content:flex-end;gap:9px;border-top:1px solid var(--line);padding:16px 25px;background:#fff}.modal-foot>small{margin-right:auto;font-size:9px;line-height:1.5}.source-choices{display:flex;flex-direction:column;gap:8px;margin:14px 0 20px}.source-choice{display:flex;align-items:center;gap:11px;padding:13px;border:1px solid var(--line);border-radius:8px;margin:0;font-weight:500;cursor:pointer}.source-choice:has(input:checked){border-color:#a6c4f5;background:#f8fbff}.source-choice.disabled{opacity:.5;cursor:default}.source-choice>div{flex:1;font-size:11px;line-height:1.7}.source-choice b{font-weight:600;display:block}.source-choice small{font-size:9px}.source-choice .file-icon{width:28px;height:33px;font-size:8px}.generate-summary{display:flex;align-items:center;gap:18px;padding:14px 15px;border-radius:8px;background:#f7faff;color:#91a0b7;font-size:10px}.generate-summary span{display:flex;align-items:center;gap:6px}.generate-summary svg{width:15px;height:15px}.progress-state{padding:55px 30px 45px;text-align:center}.progress-orb{display:inline-flex;width:64px;height:64px;align-items:center;justify-content:center;color:var(--blue);background:#edf5ff;border-radius:18px;margin-bottom:22px}.progress-orb svg{width:30px;height:30px;animation:pulse 1.3s ease-in-out infinite}.progress-state h3{font-size:19px;margin-bottom:12px}.progress-state p{font-size:11px}.progress-track{width:290px;max-width:90%;height:5px;background:#edf1f8;border-radius:5px;overflow:hidden;margin:25px auto 16px}.progress-track i{display:block;background:var(--blue);height:100%;width:5%;transition:width .4s;border-radius:5px}.progress-state small{font-size:9px}@keyframes pulse{50%{transform:scale(.87);opacity:.6}}
|
|
.preview-top{display:flex;align-items:center;gap:7px;font-size:10px;color:#96a2b4;margin-bottom:12px}.preview-layout{display:grid;grid-template-columns:1fr 226px;gap:27px}.prose h1{font-size:25px;margin-bottom:18px;line-height:1.35}.prose h2{font-size:15px;margin:25px 0 10px;letter-spacing:-.2px}.prose p,.prose li{font-size:12px;color:#6f819b;line-height:1.9;white-space:pre-line;overflow-wrap:anywhere}.prose ul,.prose ol{padding-left:19px}.prose .ref-line{font-size:9px;color:#a3afbe;margin-top:8px}.quiz-item{border:1px solid var(--line);padding:14px;border-radius:8px;margin:12px 0}.quiz-item strong{font-size:11px;display:block;font-weight:600;line-height:1.7}.quiz-item ol{list-style:upper-alpha;font-size:11px}.quiz-item li{font-size:11px}.quiz-item details{font-size:10px;color:#668e7e;margin-top:8px}.preview-side{padding:17px;background:#f8faff;border:1px solid #e4ecf9;border-radius:10px;height:max-content;position:sticky;top:0}.preview-side h3{font-size:11px;margin-bottom:15px}.preview-side .detail-label{font-size:8px;color:#a0adbd;margin:17px 0 5px;letter-spacing:.5px;text-transform:uppercase}.preview-side b{font-size:10px;font-weight:600;display:block;line-height:1.7;overflow-wrap:anywhere}.preview-source{padding:9px 0;border-bottom:1px solid #e8eef8;font-size:10px;line-height:1.7;color:#7f93af}.preview-source:last-child{border:0}.preview-source svg{width:13px;height:13px;margin-right:5px}.preview-tabs{display:flex;gap:17px;border-bottom:1px solid var(--line);margin-bottom:21px}.preview-tabs button{padding:0 0 11px;background:none;border:0;font-size:11px;color:#8e9bb0;border-bottom:2px solid transparent}.preview-tabs button.active{color:var(--blue);border-color:var(--blue);font-weight:650}.edit-area{font-size:12px!important;min-height:360px}.help-steps{display:flex;flex-direction:column;gap:22px}.help-step{display:flex;gap:14px}.help-step>span{background:#edf4ff;color:#5787d1;width:29px;height:29px;border-radius:8px;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:12px}.help-step h3{font-size:12px;margin-bottom:5px}.help-step p{font-size:11px}.toast{position:fixed;bottom:25px;left:50%;transform:translate(-50%,20px);opacity:0;pointer-events:none;z-index:30;background:#203b62;color:white;box-shadow:0 7px 25px #142d5020;border-radius:9px;padding:14px 19px;max-width:calc(100vw - 35px);font-size:12px;line-height:1.6;transition:opacity .18s,transform .18s}.toast.show{opacity:1;transform:translate(-50%,0)}.toast.error{background:#9f4747}.muted{color:var(--muted)}.spacer{height:20px}.source-text{white-space:pre-wrap;font-size:12px;line-height:1.9;color:#6a7d98;background:#f8faff;padding:19px;border:1px solid #e4ecf9;border-radius:8px;max-height:350px;overflow:auto;overflow-wrap:anywhere}
|
|
@media(min-width:1600px){.app main{padding-top:36px}.hero{min-height:280px}.hero h2{font-size:35px}.metrics{gap:20px}}
|
|
@media(max-width:1120px){.sidebar{width:210px;padding-left:13px;padding-right:13px}.workspace-main{margin-left:210px;width:calc(100% - 210px)}.topbar{padding:0 24px}.demo-strip{margin-left:24px;margin-right:24px}.app main{padding-left:24px;padding-right:24px}.hero{padding:25px;grid-template-columns:1.2fr 1fr}.hero h2{font-size:27px}.hero-art{width:260px}.hero-art .mini-output{margin-left:20px}.hero .btn{padding:9px 11px;font-size:10px}.metric{padding:17px 14px}.metric i{right:11px;top:13px;padding:6px}.metrics{gap:11px}.setup-row{gap:14px;padding:16px}.step{font-size:9px}.step small{font-size:8px}.dashboard-grid{grid-template-columns:1.3fr 1fr;gap:16px}.two-column{grid-template-columns:1.5fr 1fr;gap:16px}.card-body,.form-card .card-body{padding:21px}.toolbar .toolbar-controls{width:65%}.page-head h1{font-size:26px}.login-copy h1{font-size:36px}.login-panel{padding:35px}.preview-layout{grid-template-columns:1fr 200px}}
|
|
@media(max-width:900px){.hero-art{display:none}.hero{display:block}.hero p{max-width:470px}.metrics{grid-template-columns:1fr 1fr}.dashboard-grid,.two-column{grid-template-columns:1fr}.setup-row{align-items:flex-start;flex-direction:column}.setup-row>b{margin-bottom:7px}.schedule-mini .btn{width:100%}.match-grid{grid-template-columns:1fr}.topbar-right>#header-date{display:none}.preview-layout{grid-template-columns:1fr}.preview-side{position:static;display:none}.login-layout{grid-template-columns:1fr 1fr}.login-copy h1{font-size:30px}.login-story{padding:35px 30px}.login-footer span{display:none}.login-copy>p{font-size:12px}.login-benefits{font-size:10px}}
|
|
@media(max-width:700px){.sidebar{position:static;width:100%;padding:15px 17px 0;display:block;border-right:0;border-bottom:1px solid var(--line)}.sidebar>.brand{margin:0 0 16px;font-size:14px}.sidebar .brand b{display:inline;margin-left:3px}.sidebar .brand small{margin-top:4px;letter-spacing:1px}.sidebar .brand-mark{width:31px;height:34px}.workspace,.nav-label,.sidebar-help,.profile{display:none}.sidebar nav{flex-direction:row;overflow:auto;gap:4px;margin:0 -3px;padding-bottom:9px}.sidebar nav button{font-size:9px;gap:5px;padding:10px;white-space:nowrap;width:auto}.sidebar nav svg{width:14px;height:14px}.nav-count{display:none}.app{display:block}.workspace-main{margin:0;width:100%}.topbar{height:50px;padding:0 19px}.breadcrumb{font-size:10px}.topbar-right{gap:10px;font-size:9px}.demo-strip{margin:17px 17px 0;font-size:9px;padding:9px 10px}.demo-strip-tag{display:none}.app main{padding:23px 17px}.page-head{flex-direction:column;gap:15px;margin-bottom:21px}.page-head h1{font-size:26px}.page-head p{font-size:11px}.page-head .head-actions{width:100%}.page-head .head-actions .btn{flex:1}.hero{padding:23px}.hero h2{font-size:27px}.hero p{font-size:10px}.metric strong{font-size:25px}.metric small{font-size:8px}.setup-row{padding:16px}.step-arrow{display:none}.steps{gap:8px}.step{align-items:flex-start;gap:6px}.step>i{width:21px;height:21px;flex-shrink:0}.step small{font-size:7px}.app-footer{margin-left:17px;margin-right:17px;font-size:8px}.app-footer>span:last-child{display:none}.toolbar{padding:16px;flex-direction:column;align-items:stretch;gap:12px}.toolbar .toolbar-controls{width:100%;max-width:none}.search{max-width:none}.result-list{padding:0 16px}.result-row{gap:10px;flex-wrap:wrap}.result-main{min-width:200px}.result-actions{margin-left:56px}.field-grid{grid-template-columns:1fr}.output-checks{grid-template-columns:1fr}.form-footer{padding:16px 20px;align-items:flex-start;flex-direction:column}.form-footer .btn{width:100%}.modal-head{padding:20px}.modal-head h2{font-size:19px}.modal-body{padding:20px;max-height:63vh}.modal-foot{padding:15px 20px;flex-wrap:wrap}.modal-foot>small{width:100%;margin-bottom:5px}.modal-foot .btn{flex:1;font-size:10px;padding:9px}.generate-summary{gap:10px;flex-wrap:wrap;font-size:9px}.login-layout{display:flex;flex-direction:column}.login-story{padding:22px 25px;background:#f3f7ff}.login-copy{padding:26px 0 16px}.login-copy h1{font-size:28px;margin:13px 0}.login-copy h1 br:last-child{display:none}.login-copy>p{font-size:11px}.login-diagram,.login-benefits,.login-footer{display:none}.login-story .brand b{display:inline;font-size:14px;margin-left:3px}.login-story .brand small{font-size:8px}.login-story .brand-mark{width:33px;height:36px}.eyebrow{font-size:7px}.login-panel{padding:30px 25px}.login-form-wrap{width:100%;max-width:400px}.login-form-wrap h2{font-size:23px;margin-top:16px}.login-form-wrap>p{margin-bottom:22px}.login-form-wrap .login-bottom{margin-top:30px}}
|
|
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
|
|
@media(max-width:700px){.sidebar nav{flex-wrap:wrap;overflow:visible;align-items:flex-start}.sidebar nav>button{flex:1;justify-content:center}.sidebar nav .admin-menu{width:100%;margin:3px 0 0;padding:4px 0 0;border-top:1px solid var(--line)}.sidebar nav .admin-menu summary{padding:7px 10px;justify-content:flex-start;gap:8px;font-size:9px}.sidebar nav .admin-menu button{display:inline-flex;width:auto;padding:8px 10px;font-size:9px}.sidebar nav .admin-menu summary svg{width:12px;height:12px}}
|
|
/* Content library and format-specific previews. */
|
|
@media(max-width:600px){.overview-banner{display:grid!important;grid-template-columns:42px minmax(0,1fr);align-items:start!important}.overview-banner>div{min-width:0}.overview-banner>.status{grid-column:2;margin:0!important;justify-self:start}}
|
|
.overview-banner{display:flex;align-items:center;gap:20px;background:#edf4ff;border:1px solid #dfeaff;border-radius:14px;padding:26px 28px;margin-bottom:24px}.overview-symbol{display:grid;place-items:center;width:55px;height:55px;border-radius:15px;color:var(--blue);background:white;flex-shrink:0}.overview-symbol svg{width:27px;height:27px}.overview-banner h2{font-size:23px;margin:9px 0 6px}.overview-banner p{font-size:11px}.overview-banner>.status{margin-left:auto}.metric strong.date-metric{font-size:21px;letter-spacing:-.7px;margin-top:16px}.summary-metrics{margin-bottom:26px}.format-summary{display:flex;justify-content:center;flex-wrap:wrap;gap:28px;padding:22px 0 4px;font-size:10px;color:var(--muted)}.format-summary>span{display:flex;align-items:center;gap:8px}.format-summary b{color:var(--ink);margin-left:4px}.type-badge{display:inline-flex;align-items:center;gap:5px;padding:5px 7px;border-radius:5px;font-size:9px;font-weight:650;white-space:nowrap;background:#edf4ff;color:#4872bd}.type-badge svg{width:12px;height:12px}.type-badge.pdf{background:#fff0ee;color:#c77b72}.type-badge.scorm{background:#f1edfc;color:#8a6dc0}.type-badge.audio{background:#eaf6f3;color:#518e80}.content-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:18px;padding:22px}.content-card{border:1px solid var(--line);border-radius:11px;overflow:hidden;min-width:0;background:white}.content-cover{height:122px;position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;background:#ecf3ff;color:#5d85c5}.content-cover>svg{width:30px;height:30px;stroke-width:1.3}.content-cover>span{font-size:11px;font-weight:650}.content-cover>small{position:absolute;top:11px;left:12px;font-size:7px;letter-spacing:1.2px;color:inherit;opacity:.65}.content-cover.pdf{background:#fbf1ef;color:#bd867d}.content-cover.audio{background:#edf7f4;color:#679b8d}.content-cover.scorm{background:#f2effa;color:#9a82bb}.content-card-body{padding:15px}.content-card-top{display:flex;align-items:center;justify-content:space-between;gap:5px;margin-bottom:12px}.content-card-top .status{font-size:8px;padding:5px 6px}.content-title{display:block;text-align:left;border:0;padding:0;background:none;font-weight:650;font-size:13px;line-height:1.55;letter-spacing:-.2px;min-height:61px;color:var(--ink);overflow-wrap:anywhere}.content-title:hover{color:var(--blue)}.content-card-body>p{font-size:9px;margin:9px 0 15px}.content-card-foot{border-top:1px solid var(--line);padding-top:13px;display:flex;align-items:center;justify-content:space-between;gap:8px}.content-card-foot>span{font-size:8px;color:#a0aabd}.content-card-foot .text-btn{font-size:10px}.content-card-foot svg{width:12px;height:12px}.supported-formats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:20px}.supported-formats>div{display:flex;align-items:center;gap:12px;border:1px solid var(--line);border-radius:10px;padding:17px;background:white}.supported-formats b{font-size:12px}.supported-formats small{display:block;font-size:9px;margin-top:6px}.format-icon{display:grid;place-items:center;width:38px;height:40px;border-radius:8px;background:#edf4ff;color:#5d85c5;flex-shrink:0}.format-icon.scorm{color:#8a6dc0;background:#f1edfc}.format-icon.audio{color:#518e80;background:#eaf6f3}.format-icon.pdf{color:#c77b72;background:#fff0ee}.file-icon.scorm{font-size:7px;background:#f1edfc;color:#8a6dc0}.file-icon.mp4,.file-icon.webm,.file-icon.mov,.file-icon.m4v{color:#5d85c5;background:#edf4ff}.file-icon.mp3,.file-icon.wav,.file-icon.m4a,.file-icon.ogg,.file-icon.aac,.file-icon.flac{background:#eaf6f3;color:#518e80}.preview-notice{display:flex;gap:9px;padding:12px 14px;background:#eef5ff;border-radius:7px;color:#6d86a8;font-size:11px;line-height:1.7;margin-bottom:18px}.preview-notice.concept{background:#fff8e9;color:#a88c55}.preview-notice svg{width:16px;height:16px;margin-top:2px}.storyboard-screen{padding:25px;background:#eef4ff;border:1px solid #dae7fa;border-radius:12px;min-height:290px;display:flex;flex-direction:column;align-items:center;text-align:center;justify-content:center;color:#3f659c}.storyboard-screen>span{font-size:8px;letter-spacing:1.6px}.storyboard-screen>div{margin:21px 0 13px}.storyboard-screen svg{width:38px;height:38px;stroke-width:1.3}.storyboard-screen h2{font-size:22px}.storyboard-screen p{font-size:11px;max-width:460px;margin:13px 0;color:#7c92b1}.storyboard-screen>small{font-size:8px;margin-top:16px}.scene-list{display:flex;gap:8px;overflow:auto;padding:14px 0 6px}.scene-list button{padding:11px;text-align:left;flex:0 0 128px;font-size:9px;line-height:1.6;background:white;border:1px solid var(--line);border-radius:7px;color:#8b98ab}.scene-list button b{display:block;margin-bottom:6px;font-size:8px}.scene-list button.active{border-color:#a7c4fa;background:#f3f7ff;color:var(--blue)}.script-details>summary{font-size:12px;color:var(--blue);cursor:pointer;margin-bottom:20px}.audio-preview{text-align:center;padding:26px;background:#f1f8f6;border-radius:12px;border:1px solid #e0efea}.audio-orb{display:grid;place-items:center;background:white;color:#619d89;border-radius:50%;height:58px;width:58px;margin:0 auto 18px}.audio-orb svg{width:27px;height:27px}.waveform{display:flex;justify-content:center;gap:4px;height:60px;align-items:center;margin:0 auto 20px;max-width:100%;overflow:hidden}.waveform i{width:3px;border-radius:4px;flex-shrink:0;background:#9bc7b8}.audio-preview h2{font-size:20px}.audio-preview p{font-size:11px;margin:12px auto 20px}.audio-preview .head-actions{justify-content:center}.audio-preview>small{display:block;font-size:9px;margin-top:15px}.scorm-preview-head{display:flex;gap:11px;align-items:center;padding:15px;background:#f3effb;color:#9377b8;border-radius:8px;margin-bottom:23px;font-size:12px}.scorm-preview-head svg{width:26px;height:26px}.scorm-preview-head small{display:block;font-size:9px;margin-top:5px}.scorm-preview>h2{font-size:23px}.scorm-preview>p{font-size:11px;margin:10px 0 20px}.chapter{border:1px solid var(--line);border-radius:8px;margin:10px 0;overflow:hidden}.chapter summary{cursor:pointer;list-style:none;display:flex;align-items:center;gap:11px;padding:15px;font-size:12px;font-weight:600;background:#fafbfe}.chapter summary>span{font-size:9px;background:#f0edf8;color:#9a83ba;padding:7px;border-radius:5px}.chapter>p{font-size:12px;padding:17px;white-space:pre-wrap}.source-player{display:block;width:100%;max-height:350px;margin:0 auto 20px;border-radius:8px}.upload-issues{font-size:12px;line-height:1.9;color:#b47a6a}
|
|
@media(max-width:1250px){.content-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.content-title{min-height:42px}.supported-formats{gap:10px}.supported-formats>div{padding:12px;gap:8px}.supported-formats small{font-size:8px}.overview-banner h2{font-size:20px}}
|
|
@media(max-width:900px){.overview-banner{align-items:flex-start;flex-wrap:wrap;padding:22px}.overview-banner>.status{margin:0 0 0 75px}.supported-formats{grid-template-columns:repeat(2,1fr)}.toolbar-controls{flex-wrap:wrap!important;gap:8px!important}.toolbar-controls>.search{flex-basis:100%}.toolbar-controls>select{flex:1}.format-summary{gap:14px}}
|
|
@media(max-width:600px){.overview-banner{gap:14px;padding:19px}.overview-symbol{width:42px;height:44px}.overview-banner>div{flex:1}.overview-banner h2{font-size:19px;line-height:1.4}.overview-banner .eyebrow{font-size:6px;letter-spacing:1px}.overview-banner p{font-size:9px}.overview-banner>.status{margin:0 0 0 56px;font-size:9px}.content-grid{grid-template-columns:1fr;padding:16px;gap:17px}.content-cover{height:130px}.content-title{min-height:0;font-size:14px}.content-card-top .status{font-size:9px}.content-card-body{padding:17px}.format-summary{justify-content:flex-start}.format-summary>span{width:calc(50% - 14px);font-size:9px}.supported-formats>div{padding:12px}.supported-formats small{font-size:8px}.metric strong.date-metric{font-size:17px}.audio-preview{padding:22px 16px}.audio-preview .head-actions{flex-wrap:wrap}.audio-preview h2{font-size:19px}.storyboard-screen{min-height:290px;padding:24px 18px}.storyboard-screen h2{font-size:20px}.waveform{gap:3px}.upload-limit{line-height:1.9!important}.card-head{flex-wrap:wrap}.content-grid .text-btn{font-size:11px}}
|
|
/* Brain and the L&D assistant workflow. */
|
|
.journey-strip{display:flex;gap:15px;justify-content:space-between;flex-wrap:wrap;margin:0 0 24px;padding:0 3px;font-size:11px;color:#7a8ba5}.journey-strip>span{display:flex;align-items:center;gap:9px}.journey-strip b{display:grid;place-items:center;width:24px;height:24px;border-radius:50%;background:#eaf2ff;color:var(--blue);font-size:9px}.brain-banner{display:flex;align-items:center;gap:23px;padding:29px;background:#edf4ff;border:1px solid #dfeaff;border-radius:14px;margin-bottom:20px}.brain-symbol{height:76px;width:76px;border-radius:20px;background:white;color:var(--blue);display:grid;place-items:center;flex-shrink:0}.brain-symbol svg{width:42px;height:42px;stroke-width:1.25}.brain-banner h2{font-size:25px;margin:11px 0 9px}.brain-banner p{font-size:11px}.brain-formats{display:flex;gap:7px;margin-top:15px}.brain-context{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin:22px 0}.brain-context>div{display:flex;align-items:center;gap:12px;padding:5px 3px;color:#7192be}.brain-context b{display:block;font-size:12px;color:#4a6285}.brain-context small{display:block;font-size:10px;margin-top:5px;line-height:1.7}.brain-selection{padding:13px 23px;background:#fbfcfe;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;gap:15px;font-size:10px;color:var(--muted)}.brain-selection label{font-size:11px}.brain-topics{margin:26px 0 3px}.brain-topics h3{font-size:14px}.brain-topics p{font-size:10px;margin:7px 0 14px}.brain-topics>div{display:flex;flex-wrap:wrap;gap:7px}.upload-success{display:flex;align-items:center;gap:17px;padding:23px;margin-bottom:20px}.upload-success>span{padding:10px;background:#eaf6f2;color:#559a84;border-radius:50%}.upload-success h3{font-size:14px}.upload-success p{font-size:11px;margin-top:7px}.upload-success .btn{margin-left:auto}.ai-workspace{display:grid;grid-template-columns:1.05fr 1fr;gap:23px;align-items:start}.assistant-title{display:flex;gap:12px;align-items:center}.assistant-title>span{display:grid;place-items:center;width:38px;height:40px;border-radius:9px;background:#edf4ff;color:var(--blue)}.ai-messages{padding:24px 22px;max-height:450px;overflow:auto;min-height:215px}.ai-message{display:flex;align-items:flex-start;gap:10px;margin-bottom:18px}.ai-message:last-child{margin-bottom:0}.ai-message>span{display:grid;place-items:center;flex-shrink:0;width:25px;height:27px;border-radius:7px;background:#eaf2ff;color:#6f91c5}.ai-message svg{width:14px;height:14px}.ai-message p{background:#f5f8fd;border-radius:0 10px 10px;padding:14px;font-size:11px;line-height:1.85;color:#788da9;white-space:pre-wrap}.ai-message.user{flex-direction:row-reverse}.ai-message.user p{border-radius:10px 0 10px 10px;background:#eef4ff;color:#587cb2}.prompt-chips{display:flex;gap:7px;flex-wrap:wrap;padding:0 22px 20px}.prompt-chips button{font-size:9px;padding:8px 10px;border:1px solid #dfe9f8;border-radius:20px;background:white;color:#7390b7}.prompt-chips button:hover{background:#f0f6ff;color:var(--blue)}#ai-request-form{padding:20px 22px;border-top:1px solid var(--line);background:#fcfdff}#ai-request-form textarea{font-size:12px;min-height:110px}.ai-compose-footer{display:flex;gap:15px;align-items:center;justify-content:space-between;margin-top:14px}.ai-compose-footer small{font-size:9px;line-height:1.7}.ai-compose-footer .btn{font-size:11px;flex-shrink:0}.ai-disclosure{display:flex;align-items:flex-start;gap:8px;padding:17px 22px;font-size:9px;line-height:1.8;color:#9ba8bb;border-top:1px solid var(--line)}.ai-disclosure svg{width:13px;height:13px;margin-top:3px;flex-shrink:0}.ai-plan .card-body{padding:23px}.ai-plan label{font-size:11px}.ai-plan .field{margin-bottom:20px}.ai-plan .field-grid{gap:0 14px}.plan-source{display:flex;align-items:center;gap:10px;padding:14px;background:#f1f6ff;border-radius:8px;margin-bottom:21px}.plan-source>span{display:grid;place-items:center;width:33px;height:34px;border-radius:8px;background:white;color:#7c9bcc}.plan-source b{font-size:11px}.plan-source small{display:block;font-size:8px;line-height:1.6;margin-top:4px}.plan-source .text-btn{margin-left:auto;font-size:10px}.plan-actions{display:flex;gap:9px}.plan-actions .btn{flex:1;padding:10px;font-size:11px}.ai-plan .switch-row{padding:16px 0 20px;margin-top:0}.result-tabs{display:flex;gap:7px;border-bottom:1px solid #e5ebf4;margin-bottom:20px}.result-tabs button{background:none;border:0;border-bottom:2px solid transparent;font-size:12px;padding:11px 17px 14px;color:#92a0b6}.result-tabs button.active{color:var(--blue);border-color:var(--blue)}.result-tabs b{font-size:9px;background:#edf3ff;color:#85a0c7;padding:3px 5px;border-radius:4px;margin-left:5px}.research-list{padding:0 22px}.research-row{display:flex;align-items:center;gap:16px;padding:22px 0;border-bottom:1px solid var(--line)}.research-row:last-child{border-bottom:0}.research-row>span{display:grid;place-items:center;height:43px;width:43px;background:#f0f5fd;color:#819cc4;border-radius:9px;flex-shrink:0}.research-row h3{font-size:13px;margin-top:10px;line-height:1.6;overflow-wrap:anywhere}.research-row p{font-size:9px;margin-top:7px}.research-row>.btn{margin-left:auto;flex-shrink:0}.content-cover.text{background:#edf3fa;color:#849bb7}.type-badge.text{background:#edf3fa;color:#7993b7}.format-icon.text{background:#edf3fa;color:#849bb7}
|
|
@media(max-width:1100px){.ai-workspace{grid-template-columns:1fr}.ai-messages{min-height:150px}.ai-plan .field-grid{grid-template-columns:1fr 1fr}.brain-banner h2{font-size:22px}}
|
|
@media(max-width:700px){.sidebar nav{gap:4px}.sidebar nav>button{flex:1 0 auto;padding:9px;font-size:9px}.ai-workspace{gap:20px}.brain-context{grid-template-columns:1fr;gap:12px}.brain-selection{align-items:flex-start;flex-direction:column;gap:8px;padding:13px 17px}.brain-banner{padding:22px;gap:17px;align-items:flex-start}.brain-symbol{width:48px;height:50px;border-radius:12px}.brain-symbol svg{width:29px;height:29px}.brain-banner h2{font-size:21px;line-height:1.4}.brain-banner p{font-size:10px}.brain-banner .eyebrow{font-size:6px;letter-spacing:1.1px}.brain-formats{flex-wrap:wrap;gap:5px}.brain-banner>div{min-width:0}.journey-strip{display:grid;grid-template-columns:1fr 1fr;gap:14px;font-size:10px}.upload-success{flex-wrap:wrap;gap:13px;padding:20px}.upload-success>div{flex:1;min-width:180px}.upload-success .btn{width:100%;margin-left:0}.ai-plan .field-grid{grid-template-columns:1fr}.ai-messages{padding:20px 17px;max-height:340px}.ai-message p{font-size:11px;padding:12px}.prompt-chips{padding:0 17px 18px}#ai-request-form{padding:20px 17px}.ai-compose-footer{align-items:flex-start;flex-direction:column;gap:12px}.ai-compose-footer .btn{width:100%}.ai-disclosure{padding:17px}.plan-actions{flex-direction:column}.plan-actions .btn{width:100%}.ai-plan .card-body{padding:20px}.research-row{align-items:flex-start;flex-wrap:wrap;gap:12px}.research-row>div{flex:1;min-width:170px}.research-row>.btn{margin-left:55px}.research-list{padding:0 17px}.research-row h3{font-size:12px}.plan-source{gap:8px}.plan-source small{font-size:8px}.assistant-title{gap:8px}.assistant-title h3{font-size:13px}}
|
|
/* Three simple screens: upload, the combined Brain and AI workspace, results. */
|
|
.unified-workspace{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:22px;align-items:start}.compact-brain .card-head,.simple-ai .card-head{padding:19px 20px}.compact-brain .card-head>svg{color:#8ca6cd}.compact-brain .badge{margin-left:5px}.compact-brain-search{padding:17px 19px}.compact-brain-search .search{width:100%;max-width:none}.compact-brain .brain-selection{padding:12px 19px;font-size:9px}.compact-brain .brain-selection label{font-size:10px}.compact-source-list{max-height:450px;overflow:auto;padding:0 17px}.compact-source-row{display:flex;align-items:center;gap:10px;border-bottom:1px solid var(--line);padding:15px 0;min-height:74px}.compact-source-row:last-child{border-bottom:0}.compact-source-row>input{margin:0;width:14px;height:14px}.compact-source-row .file-icon{width:30px;height:35px;font-size:7px;flex-shrink:0}.compact-source-name{min-width:0;flex:1}.compact-source-name b{display:block;font-size:11px;line-height:1.5;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.compact-source-name small{display:block;font-size:8px;margin-top:5px}.compact-source-row .icon-btn{padding:4px}.compact-source-row .icon-btn svg{width:14px;height:14px}.simple-ai #ai-request-form{padding:19px 20px;background:white;border:0}.simple-ai #ai-request-form textarea{min-height:85px;font-size:12px}.simple-ai .ai-compose-footer{margin-top:12px;gap:10px}.simple-ai .prompt-chips{padding:0;gap:6px}.simple-ai .prompt-chips button{padding:6px 9px;font-size:8px}.simple-ai .ai-compose-footer>.btn{min-height:32px;padding:7px 14px;font-size:10px}.compact-ai-reply{display:flex;gap:9px;padding:12px 15px;margin:0 20px 17px;background:#f3f7ff;border-radius:8px;color:#849cc0}.compact-ai-reply svg{width:14px;height:14px;margin-top:3px}.compact-ai-reply p{font-size:10px;line-height:1.8;color:#8195b3}.simple-plan{padding:17px 20px 18px;border-top:1px solid var(--line)}.simple-plan-row{display:grid;grid-template-columns:minmax(0,1fr) 100px;gap:13px}.simple-plan .field{margin-bottom:14px}.simple-plan label{font-size:10px}.simple-plan input:not([type=checkbox]),.simple-plan select,.simple-plan textarea{font-size:11px;min-height:38px;padding:10px 11px}.simple-plan #ai-count-help{font-size:8px;line-height:1.7;display:block;margin-top:-4px}.simple-options{margin:14px 0 0}.simple-options>summary{font-size:10px;color:#8a9cb7;cursor:pointer;padding:5px 0 11px}.simple-options[open]>summary{margin-bottom:7px}.simple-options small{font-size:8px}.simple-schedule-toggle{display:flex;justify-content:space-between;align-items:center;padding:13px 0 17px;border-top:1px solid #eff2f7;margin-top:6px}.simple-schedule-toggle label{font-size:11px;color:#647f9f}.simple-schedule-toggle>span{font-size:8px;color:#a3afbf}.simple-plan #schedule-fields{padding:0 0 7px}.simple-plan .field-grid{gap:13px}.simple-plan .plan-actions{gap:9px}.simple-plan .plan-actions .btn{font-size:11px;min-height:39px}.simple-saved-status{font-size:8px;color:#9aaac0;line-height:1.8;margin-top:12px}.simple-ai>.table-note,.compact-brain>.table-note{font-size:8px;line-height:1.8;padding:13px 19px}.sidebar .profile{margin-top:auto}
|
|
@media(max-width:1000px){.unified-workspace{grid-template-columns:1fr}.compact-source-list{max-height:280px}.compact-source-row{min-height:65px;padding:12px 0}.simple-ai .ai-compose-footer{flex-direction:row;align-items:center}.simple-plan-row{grid-template-columns:minmax(0,1fr) 110px}.simple-plan .field-grid{grid-template-columns:1fr 1fr}}
|
|
@media(max-width:700px){.sidebar nav>button{flex:1 0 0;justify-content:center}.unified-workspace{gap:18px}.compact-brain .card-head,.simple-ai .card-head{padding:17px}.compact-brain .brain-selection{flex-direction:row;gap:9px;padding:11px 17px}.compact-source-row{gap:8px}.compact-source-row .file-icon{width:27px;height:32px;font-size:6px}.compact-source-name b{font-size:10px}.compact-source-name small{font-size:7px}.simple-ai #ai-request-form{padding:17px}.simple-plan{padding:17px}.simple-ai .ai-compose-footer{align-items:flex-start;gap:8px}.simple-ai .ai-compose-footer>.btn{width:auto;flex-shrink:0}.simple-ai .prompt-chips{flex-direction:column;align-items:flex-start}.simple-plan-row{grid-template-columns:minmax(0,1fr) 90px}.simple-plan .plan-actions{flex-direction:row}.simple-plan .plan-actions .btn{font-size:10px;padding:9px 8px}.compact-ai-reply{margin-left:17px;margin-right:17px}.compact-ai-reply p{font-size:9px}.simple-plan .field-grid{grid-template-columns:1fr 1fr}}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<section id="login-view" class="login-layout">
|
|
<div class="login-story">
|
|
<a class="brand" href="#" aria-label="Learning Lab Express"><span class="brand-mark" data-icon="book"></span><span>Learning Lab <b>Express</b><small>by Bawana</small></span></a>
|
|
<div class="login-copy"><span class="eyebrow">BELAJAR BARU, TANPA MULAI DARI NOL</span><h1>Pengetahuan tim.<br>Ide baru.<br>Pembelajaran tanpa henti.</h1><p>Satukan materi dalam Brain, lalu minta AI mengembangkannya menjadi konten pelatihan dan riset topik.</p>
|
|
<div class="login-diagram" aria-hidden="true"><div class="mini-source"><span class="file-icon pdf">PDF</span><div>Materi pelatihan<small>Knowledge base · Brain</small></div><span class="mini-check">✓</span></div><div class="connector"><i></i><span data-icon="spark"></span><i></i></div><div class="mini-output"><span class="output-icon" data-icon="book"></span><div>Konten pembelajaran baru<small>Terstruktur · Relevan · Siap ditinjau</small></div><span class="status ready">Baru</span></div></div>
|
|
<div class="login-benefits"><span><i data-icon="upload"></i> Upload materi ke Brain</span><span><i data-icon="clock"></i> Jadwalkan riset topik</span><span><i data-icon="download"></i> Buka dan download hasilnya</span></div>
|
|
</div>
|
|
<div class="login-footer">LEARNING LAB EXPRESS <span>Pengetahuan Anda. Kemungkinan baru.</span></div>
|
|
</div>
|
|
<div class="login-panel"><div class="login-form-wrap"><span class="badge neutral">Development</span><h2>Selamat datang kembali</h2><p>Masuk dengan akun learning-lab untuk mengelola materi dan membuat konten.</p>
|
|
<form id="login-form"><label for="login-email">Email</label><input id="login-email" type="email" autocomplete="username" required>
|
|
<label for="login-password">Password</label><div class="password-field"><input id="login-password" type="password" autocomplete="current-password" required><button type="button" data-action="toggle-password" aria-label="Tampilkan password"><span data-icon="eye"></span></button></div>
|
|
<button class="btn primary wide" type="submit" style="margin-top:18px">Masuk ke Learning Lab <span data-icon="arrow-right"></span></button>
|
|
<button class="btn wide" type="button" id="clerk-login" data-action="clerk-login" hidden style="margin-top:10px">Masuk dengan Clerk (akun organisasi)</button>
|
|
<p id="login-error" class="error" role="alert"></p></form>
|
|
<div class="demo-login"><span data-icon="info"></span><p>Email/password untuk Brain dan konten teks. Riset dan jadwal agen memerlukan <b>Clerk</b> dengan akun organisasi.</p></div>
|
|
<p class="login-bottom">Learning Lab Express <span>by Bawana</span></p>
|
|
</div></div>
|
|
</section>
|
|
<div id="app" class="app" hidden>
|
|
<aside class="sidebar">
|
|
<a class="brand" href="#" data-nav="sources"><span class="brand-mark" data-icon="book"></span><span>Learning Lab <b>Express</b><small>by Bawana</small></span></a>
|
|
<div class="workspace"><span class="workspace-icon">L</span><div>Ruang belajar<small id="workspace-name">Akun pribadi</small></div></div>
|
|
<div class="nav-label">RUANG KERJA</div>
|
|
<nav aria-label="Navigasi utama">
|
|
<button data-nav="sources"><span data-icon="upload"></span>Upload materi</button>
|
|
<button data-nav="brain"><span data-icon="brain"></span>Brain & AI<span class="nav-count" id="source-count">0</span></button>
|
|
<button data-nav="results"><span data-icon="book"></span>Hasil<span class="nav-count" id="module-count">0</span></button>
|
|
</nav>
|
|
<div class="profile"><span class="avatar" id="avatar">U</span><div><b id="profile-name">-</b><small id="profile-sub">Development</small></div><button data-action="logout" class="icon-btn" aria-label="Keluar"><span data-icon="logout"></span></button></div>
|
|
</aside>
|
|
<div class="workspace-main">
|
|
<header class="topbar"><div class="breadcrumb">Ruang kerja <span>/</span> <b id="breadcrumb">Upload materi</b></div><div class="topbar-right"><span class="demo-indicator"><i></i> Engine learning-lab</span><span id="header-date"></span></div></header>
|
|
<div class="demo-strip"><span data-icon="info"></span><span>Fase development: terhubung ke engine learning-lab. Hasil AI perlu ditinjau sebelum dipakai.</span><span class="demo-strip-tag">DEV</span></div>
|
|
<main id="view-content" tabindex="-1"></main>
|
|
<footer class="app-footer">Learning Lab Express <span>by Bawana</span><span>Ruang kerja untuk pengetahuan yang terus berkembang.</span></footer>
|
|
</div>
|
|
</div>
|
|
<dialog id="modal" aria-labelledby="modal-title"><div id="modal-content"></div></dialog>
|
|
<div id="toast" class="toast" role="status" aria-live="polite"></div>
|
|
<input id="file-input" type="file" multiple hidden>
|
|
<script src="/config.js"></script>
|
|
<script src="engine.js"></script>
|
|
<script>(function(){
|
|
'use strict';
|
|
const $=s=>document.querySelector(s),E=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])),KEY='lle-results';
|
|
const icons={
|
|
book:'<path d="M3 5c3-1 6 0 9 2 3-2 6-3 9-2v14c-3-1-6 0-9 2-3-2-6-3-9-2z"/><path d="M12 7v14M6 9l3 1M15 10l3-1"/>',
|
|
home:'<path d="m3 10 9-7 9 7v10H3z"/><path d="M9 20v-7h6v7"/>',
|
|
folder:'<path d="M3 6h6l2 2h10v12H3z"/><path d="M3 6V4h6l2 2h9v2"/>',
|
|
spark:'<path d="m12 3 2.5 6.5L21 12l-6.5 2.5L12 21l-2.5-6.5L3 12l6.5-2.5z"/><path d="m20 2 .5 1.5L22 4l-1.5.5L20 6l-.5-1.5L18 4l1.5-.5z"/>',
|
|
calendar:'<rect x="3" y="5" width="18" height="16" rx="2"/><path d="M7 3v4M17 3v4M3 11h18M7 15h3M14 15h3"/>',
|
|
clock:'<circle cx="12" cy="12" r="9"/><path d="M12 7v6l4 2"/>',
|
|
layers:'<path d="m12 3 10 5-10 5L2 8zM2 12l10 5 10-5M2 16l10 5 10-5"/>',
|
|
download:'<path d="M12 3v12m-5-5 5 5 5-5M4 16v5h16v-5"/>',
|
|
upload:'<path d="M12 16V4m-5 5 5-5 5 5M4 16v5h16v-5"/>',
|
|
file:'<path d="M5 3h9l5 5v13H5zM14 3v6h5M8 13h8M8 17h6"/>',
|
|
'arrow-right':'<path d="M4 12h16m-6-6 6 6-6 6"/>',
|
|
chevron:'<path d="m7 10 5 5 5-5"/>',
|
|
search:'<circle cx="10" cy="10" r="6"/><path d="m15 15 5 5"/>',
|
|
eye:'<path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/>',
|
|
trash:'<path d="M3 6h18M9 3h6l1 3M6 6l1 15h10l1-15M10 10v7M14 10v7"/>',
|
|
close:'<path d="m6 6 12 12M18 6 6 18"/>',
|
|
info:'<circle cx="12" cy="12" r="9"/><path d="M12 11v6M12 7v.2"/>',
|
|
help:'<circle cx="12" cy="12" r="9"/><path d="M9 9a3 3 0 0 1 6 0c0 2-3 2-3 4M12 17v.2"/>',
|
|
check:'<path d="m5 12 4 4L19 6"/>',
|
|
edit:'<path d="m15 4 5 5M4 20l5-1L21 7l-4-4L5 15z"/>',
|
|
logout:'<path d="M10 4H4v16h6M10 12h11m-4-4 4 4-4 4"/>',
|
|
plus:'<path d="M12 4v16M4 12h16"/>'
|
|
};
|
|
icons.video='<rect x="3" y="5" width="18" height="14" rx="3"/><path d="m10 9 5 3-5 3z"/>';
|
|
icons.audio='<path d="M4 13v-2a8 8 0 0 1 16 0v2"/><rect x="3" y="11" width="4" height="8" rx="2"/><rect x="17" y="11" width="4" height="8" rx="2"/>';
|
|
icons.scorm='<path d="m12 3 9 5-9 5-9-5zM3 8v9l9 5 9-5V8M12 13v9"/>';
|
|
icons.brain='<path d="M12 5c-3-4-8-1-7 3-4 2-3 7 0 8-1 4 5 6 7 2M12 5c3-4 8-1 7 3 4 2 3 7 0 8 1 4-5 6-7 2M12 5v15M7 9l3 2M17 9l-3 2M6 15l3-1M18 15l-3-1"/>';
|
|
function I(name){return '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">'+(icons[name]||icons.file)+'</svg>';}
|
|
function fillIcons(root=document){root.querySelectorAll('[data-icon]').forEach(el=>el.innerHTML=I(el.dataset.icon));}
|
|
const types={text:{label:'Text',icon:'file'}};
|
|
const names={sources:'Upload materi',brain:'Brain & AI',results:'Hasil'};
|
|
let view='sources',tab='content',res={content:[],research:[]},docs=[],selected=new Set(),exts=new Set(),lastUpload=[],user=null,org=null,busy=false,pollT,toastTimer,query='';
|
|
let draft={mode:'generate',topic:'',prompt:'',urls:'',enabled:false,frequency:'daily',time:'09:00',weekday:1};
|
|
try{res=Object.assign(res,JSON.parse(localStorage.getItem(KEY)||'{}'));}catch{}
|
|
const save=()=>{try{localStorage.setItem(KEY,JSON.stringify({content:res.content.slice(0,50),research:res.research.slice(0,50)}));}catch{}};
|
|
const dt=v=>{try{return new Intl.DateTimeFormat('id-ID',{dateStyle:'medium',timeZone:'Asia/Jakarta'}).format(new Date(v));}catch{return '-';}};
|
|
function toast(m,error=false){const t=$('#toast');t.textContent=m;t.className='toast show'+(error?' error':'');clearTimeout(toastTimer);toastTimer=setTimeout(()=>t.classList.remove('show'),5000);}
|
|
const button=(text,action,style='primary',icon='plus',extra='')=>'<button type="button" class="btn '+style+'" data-action="'+action+'" '+extra+'>'+I(icon)+text+'</button>';
|
|
const head=(title,description,actions='')=>'<div class="page-head"><div><h1>'+title+'</h1><p>'+description+'</p></div><div class="head-actions">'+actions+'</div></div>';
|
|
const empty=(title,text)=>'<div class="empty"><span class="empty-icon">'+I('book')+'</span><h3>'+title+'</h3><p>'+text+'</p></div>';
|
|
const fileIcon=d=>'<span class="file-icon '+E(d.format.toLowerCase())+'">'+E(d.format.slice(0,4))+'</span>';
|
|
const statusOf=d=>d.status==='failed'?['draft','Gagal diproses']:d.status!=='completed'?['draft','Memproses '+(d.progress||0)+'%']:d.knowledge==='ready'?['ready','Knowledge base siap']:d.knowledge==='needs_credits'?['draft','Butuh kredit']:d.knowledge==='building'?['draft','Membangun KB']:['draft','Teks siap'];
|
|
const pool=()=>docs.filter(d=>!selected.size||selected.has(d.docId));
|
|
|
|
// ── modal ──
|
|
const modalHead=(title,sub='')=>'<div class="modal-head"><div><h2 id="modal-title">'+title+'</h2>'+(sub?'<p>'+sub+'</p>':'')+'</div><button class="icon-btn" data-action="close" aria-label="Tutup dialog">'+I('close')+'</button></div>';
|
|
function openModal(content,preview=false){const m=$('#modal');m.classList.toggle('preview',preview);$('#modal-content').innerHTML=content;fillIcons(m);if(!m.open)m.showModal();}
|
|
function progress(title,sub){openModal(modalHead(title,sub)+'<div class="progress-state"><span class="progress-orb">'+I('brain')+'</span><h3 id="progress-label">Menyiapkan…</h3><div class="progress-track"><i id="progress-bar"></i></div><small>Diproses oleh engine learning-lab</small></div>');}
|
|
const step=(text,pct)=>{if($('#progress-label'))$('#progress-label').textContent=text;if($('#progress-bar')&&pct!=null)$('#progress-bar').style.width=pct+'%';};
|
|
|
|
// ── views ──
|
|
function sourcesView(){
|
|
const last=lastUpload.map(id=>docs.find(d=>d.docId===id)).filter(Boolean);
|
|
return head('Upload materi','Tambahkan pengetahuan ke Brain. Anda bisa mengupload beberapa berkas sekaligus.')+
|
|
'<div id="drop-zone" class="upload-box"><span class="upload-symbol">'+I('upload')+'</span><h3>Mulai dari materi yang sudah Anda miliki</h3><p>Upload satu atau beberapa materi. Semuanya diproses engine dan tersimpan di Brain.</p>'+button('Pilih berkas','upload','primary','plus')+'<p class="upload-limit">'+(exts.size?[...exts].map(x=>x.slice(1).toUpperCase()).join(', '):'Memuat format…')+'<br>Maks. 200 MB per berkas</p></div>'+
|
|
(last.length?'<section class="card upload-success"><span>'+I('check')+'</span><div><h3>'+last.length+' materi ditambahkan ke Brain</h3><p>Engine sedang membaca isi materi. Knowledge base dibangun saat Anda meminta AI membuat konten.</p></div><button class="btn primary" data-nav="brain">Lihat Brain '+I('arrow-right')+'</button></section>':'')+
|
|
'<div class="notice-row">'+I('info')+'<span>Video, audio, dan SCORM belum tersedia di engine; format di atas adalah yang didukung saat ini.</span></div>';
|
|
}
|
|
function rows(){
|
|
const list=docs.filter(d=>(d.title+' '+d.format).toLowerCase().includes(query.toLowerCase()));
|
|
if(!list.length)return empty(docs.length?'Belum ada materi yang cocok':'Brain masih kosong','Tambahkan materi melalui halaman Upload materi.');
|
|
return list.map(d=>{const [cls,label]=statusOf(d);return '<div class="compact-source-row"><input class="brain-source-check" type="checkbox" aria-label="Pilih '+E(d.title)+'" value="'+d.docId+'" '+(selected.has(d.docId)?'checked':'')+'>'+fileIcon(d)+'<div class="compact-source-name"><b title="'+E(d.title)+'">'+E(d.title)+'</b><small><span class="status '+cls+'"><i class="dot"></i>'+E(label)+'</span></small></div><button class="icon-btn" data-action="source-delete" data-id="'+d.docId+'" aria-label="Hapus '+E(d.title)+'">'+I('trash')+'</button></div>';}).join('');
|
|
}
|
|
const opt=(list,cur)=>list.map(([v,l])=>'<option value="'+v+'" '+(String(cur)===String(v)?'selected':'')+'>'+l+'</option>').join('');
|
|
function brainView(){
|
|
const o=draft,n=pool().length;
|
|
return head('Brain & AI','Pilih materi, tentukan kebutuhan, lalu buat konten atau atur jadwal riset.')+
|
|
'<div class="unified-workspace"><section class="card compact-brain"><div class="card-head"><div><h3>Brain <span class="badge neutral">'+docs.length+' materi</span></h3><p>Knowledge base tim Anda.</p></div>'+I('brain')+'</div><div class="compact-brain-search"><div class="search">'+I('search')+'<input id="source-search" aria-label="Cari materi di Brain" placeholder="Cari materi..." value="'+E(query)+'"></div></div><div class="brain-selection"><label class="check-label"><input id="brain-select-all" type="checkbox" '+(docs.length&&docs.every(d=>selected.has(d.docId))?'checked':'')+'> Pilih semua</label><span id="brain-selection-label">'+(selected.size?selected.size+' dipilih':'Seluruh Brain digunakan')+'</span></div><div id="source-rows" class="compact-source-list">'+rows()+'</div><div class="table-note">Sumber pilihan menjadi acuan AI. Kosongkan pilihan untuk seluruh Brain.</div></section>'+
|
|
'<section class="card simple-ai"><div class="card-head"><div class="assistant-title"><span>'+I('spark')+'</span><div><h3>AI & jadwal</h3><p id="plan-source-label">'+n+' materi menjadi sumber AI</p></div></div><span class="badge blue">Engine</span></div>'+
|
|
'<form id="plan-form" class="simple-plan"><div class="field"><label for="ai-mode">Aktivitas</label><select id="ai-mode">'+opt([['generate','Buat konten teks'],['research','Riset topik (agen)']],o.mode)+'</select></div>'+
|
|
'<div class="field"><label for="ai-topic">Fokus topik</label><input id="ai-topic" maxlength="100" value="'+E(o.topic)+'" placeholder="Contoh: layanan pelanggan"></div>'+
|
|
'<div id="research-options" '+(o.mode==='generate'?'hidden':'')+'><div class="field"><label for="ai-prompt">Instruksi riset (opsional)</label><textarea id="ai-prompt" rows="2" maxlength="1600" placeholder="Apa yang perlu dicari?">'+E(o.prompt)+'</textarea></div><div class="field"><label for="research-urls">Referensi riset (opsional)</label><textarea id="research-urls" rows="2" maxlength="1200" placeholder="https://...">'+E(o.urls)+'</textarea></div></div>'+
|
|
'<div class="simple-schedule-toggle"><label class="check-label"><input id="schedule-enabled" type="checkbox" '+(o.enabled?'checked':'')+'> Jadwalkan riset otomatis</label><span>WIB</span></div>'+
|
|
'<div id="schedule-fields" '+(o.enabled?'':'hidden')+'><div class="field-grid"><div class="field"><label for="schedule-frequency">Frekuensi</label><select id="schedule-frequency">'+opt([['daily','Setiap hari'],['weekly','Setiap minggu']],o.frequency)+'</select></div><div class="field"><label for="schedule-time">Waktu</label><input id="schedule-time" type="time" value="'+E(o.time)+'" required></div></div><div class="field" id="weekday-field" '+(o.frequency==='weekly'?'':'hidden')+'><label for="schedule-weekday">Hari</label><select id="schedule-weekday">'+opt([[1,'Senin'],[2,'Selasa'],[3,'Rabu'],[4,'Kamis'],[5,'Jumat'],[6,'Sabtu'],[0,'Minggu']],o.weekday)+'</select></div></div>'+
|
|
'<div class="head-actions" style="margin-top:14px">'+button('Jalankan sekarang','run','primary','spark')+button('Simpan jadwal','save-schedule','light','calendar')+'</div><small>Konten teks memakai kredit workspace untuk membangun knowledge base. Riset dan jadwal memerlukan login Clerk dengan organisasi.</small></form></section></div>';
|
|
}
|
|
function contentCard(m){
|
|
return '<article class="content-card"><div class="content-cover text">'+I('file')+'<span>Text</span><small>DRAFT AI</small></div><div class="content-card-body"><div class="content-card-top"><span class="type-badge text">'+I('file')+'Text</span><span class="status draft"><i class="dot"></i>Draft</span></div><button class="content-title" data-action="open-content" data-id="'+m.id+'">'+E(m.title)+'</button><p>'+m.sources.length+' materi sumber · '+E(dt(m.createdAt))+'</p><div class="content-card-foot"><span>Permintaan AI</span><button class="text-btn" data-action="open-content" data-id="'+m.id+'">Buka konten '+I('arrow-right')+'</button></div></div></article>';
|
|
}
|
|
function researchRows(){
|
|
if(!res.research.length)return empty('Belum ada riset','Jalankan riset dari Brain & AI (perlu login Clerk dengan organisasi).');
|
|
return '<div class="research-list">'+res.research.map(r=>'<article class="research-row"><span>'+I('search')+'</span><div><span class="badge blue">Hasil riset agen</span><h3>'+E(r.title)+'</h3><p>'+r.sources.length+' sumber Brain · '+E(dt(r.createdAt))+' · '+r.findings.length+' temuan draf</p></div><button class="btn small" data-action="open-research" data-id="'+r.id+'">Lihat hasil</button></article>').join('')+'</div>';
|
|
}
|
|
function resultsView(){
|
|
const list=res.content.filter(m=>m.title.toLowerCase().includes(query.toLowerCase()));
|
|
return head('Hasil','Konten dan hasil riset yang sudah dibuat.')+'<div class="result-tabs"><button class="'+(tab==='content'?'active':'')+'" data-action="result-tab" data-tab="content">Konten <b>'+res.content.length+'</b></button><button class="'+(tab==='research'?'active':'')+'" data-action="result-tab" data-tab="research">Riset <b>'+res.research.length+'</b></button></div>'+
|
|
'<section class="card"><div class="toolbar"><h3>'+(tab==='research'?'Hasil riset':'Semua konten')+' <span class="badge neutral">'+(tab==='research'?res.research.length:res.content.length)+'</span></h3>'+(tab==='content'?'<div class="toolbar-controls"><div class="search">'+I('search')+'<input id="result-search" aria-label="Cari konten" placeholder="Cari judul konten..." value="'+E(query)+'"></div></div>':'')+'</div><div id="result-rows">'+(tab==='research'?researchRows():list.length?'<div class="content-grid">'+list.map(contentCard).join('')+'</div>':empty(res.content.length?'Tidak ada konten yang cocok':'Konten baru Anda akan muncul di sini','Buat konten dari Brain & AI.'))+'</div><div class="table-note">Hasil tersimpan di browser ini. Temuan riset berupa draf sumber yang perlu ditinjau.</div></section>';
|
|
}
|
|
function render(){
|
|
$('#login-view').hidden=!!user;$('#app').hidden=!user;fillIcons();
|
|
if(!user)return;
|
|
$('#profile-name').textContent=user.name||user.email||'-';$('#avatar').textContent=(user.name||user.email||'U')[0].toUpperCase();
|
|
$('#profile-sub').textContent=org?'Organisasi · '+(org.name||''):'Akun pribadi';$('#workspace-name').textContent=org?org.name:'Akun pribadi';
|
|
$('#header-date').textContent=dt(new Date());$('#breadcrumb').textContent=names[view];
|
|
$('#source-count').textContent=docs.length;$('#module-count').textContent=res.content.length;
|
|
document.querySelectorAll('nav [data-nav]').forEach(b=>{b.classList.toggle('active',b.dataset.nav===view);b.setAttribute('aria-current',b.dataset.nav===view?'page':'false');});
|
|
$('#view-content').innerHTML=({sources:sourcesView,brain:brainView,results:resultsView}[view])();fillIcons($('#view-content'));
|
|
}
|
|
function go(next){view=next;query='';render();window.scrollTo({top:0});}
|
|
|
|
// ── data ──
|
|
async function refresh(){
|
|
clearTimeout(pollT);
|
|
try{docs=await Engine.listDocuments();}catch(e){if(e.status===401)return signOut();return toast(e.message,true);}
|
|
selected=new Set([...selected].filter(id=>docs.some(d=>d.docId===id)));
|
|
$('#source-count').textContent=docs.length;
|
|
if(view==='brain'&&$('#source-rows')){$('#source-rows').innerHTML=rows();fillIcons($('#source-rows'));syncSel();}
|
|
if(docs.some(d=>d.status!=='completed'&&d.status!=='failed'))pollT=setTimeout(refresh,4000);
|
|
}
|
|
function syncSel(){
|
|
if(!$('#brain-selection-label'))return;
|
|
$('#brain-selection-label').textContent=selected.size?selected.size+' dipilih':'Seluruh Brain digunakan';
|
|
$('#plan-source-label').textContent=pool().length+' materi menjadi sumber AI';
|
|
$('#brain-select-all').checked=docs.length>0&&docs.every(d=>selected.has(d.docId));
|
|
}
|
|
function readForm(){
|
|
if(!$('#ai-mode'))return;
|
|
draft={mode:$('#ai-mode').value,topic:$('#ai-topic').value.trim(),prompt:$('#ai-prompt').value.trim(),urls:$('#research-urls').value.trim(),enabled:$('#schedule-enabled').checked,frequency:$('#schedule-frequency').value,time:$('#schedule-time').value||'09:00',weekday:Number($('#schedule-weekday').value)};
|
|
}
|
|
async function guarded(fn){
|
|
if(busy)return toast('Proses sebelumnya masih berlangsung.');
|
|
busy=true;
|
|
try{await fn();}catch(e){const m=$('#modal');if(m.open)m.close();toast(e.message||'Proses belum berhasil.',true);if(e.status===401)signOut();}
|
|
finally{busy=false;}
|
|
}
|
|
async function upload(files){
|
|
if(!files.length)return;
|
|
await guarded(async()=>{
|
|
if(!exts.size)exts=await Engine.supportedExtensions();
|
|
const ok=[],issues=[];
|
|
for(const f of files){
|
|
const ext='.'+f.name.split('.').pop().toLowerCase();
|
|
if(!exts.has(ext)){issues.push(f.name+': format tidak didukung');continue;}
|
|
if(!f.size){issues.push(f.name+': berkas kosong');continue;}
|
|
if(f.size>200*1024*1024){issues.push(f.name+': melebihi 200 MB');continue;}
|
|
try{ok.push((await Engine.upload(f)).id);}catch(e){issues.push(f.name+': '+e.message);}
|
|
}
|
|
lastUpload=ok;await refresh();
|
|
if(issues.length)openModal(modalHead('Sebagian materi belum ditambahkan')+'<div class="modal-body"><ul class="upload-issues">'+issues.map(x=>'<li>'+E(x)+'</li>').join('')+'</ul></div><div class="modal-foot">'+(ok.length?button('Lihat Brain','close-brain','primary','spark'):button('Tutup','close','','close'))+'</div>');
|
|
else if(ok.length){go('brain');toast(ok.length+' materi ditambahkan ke Brain.');}
|
|
});
|
|
}
|
|
async function runText(){
|
|
const sel=pool();if(!sel.length)throw new Error('Upload materi terlebih dahulu.');
|
|
progress('Membuat konten teks','Engine membaca materi lalu menyusun ringkasan terstruktur.');
|
|
for(const [i,d] of sel.entries()){
|
|
step('Menyiapkan “'+d.title+'” (knowledge base memakai kredit)',10+i*40/sel.length);
|
|
await Engine.buildKnowledge(d.docId);
|
|
await Engine.waitReady(d.docId,s=>step('Membaca “'+d.title+'” · '+(s.processing_stage||s.knowledge_status)));
|
|
}
|
|
step('Menyusun konten teks',60);
|
|
const {summary}=await Engine.generateText(sel.map(d=>d.docId),draft.topic||'Konten '+dt(new Date()));
|
|
const sc=summary.structured_content||{},sections=[];
|
|
if(sc.executive_summary)sections.push({title:'Ringkasan',body:sc.executive_summary});
|
|
(sc.sections||[]).forEach(s=>sections.push({title:s.title,body:[s.summary,...(s.key_points||[]).map(p=>'• '+p)].filter(Boolean).join('\n')}));
|
|
if(!sections.length)sections.push({title:summary.title||'Ringkasan',body:summary.content});
|
|
res.content.unshift({id:'c'+Date.now(),title:summary.title||draft.topic||'Konten teks',sources:sel.map(d=>({id:d.docId,title:d.title})),sections,createdAt:new Date().toISOString()});
|
|
save();tab='content';$('#modal').close();go('results');toast('Konten teks selesai dibuat.');
|
|
}
|
|
async function needOrg(){if(!Engine.clerkEnabled()||!(await Engine.agentsAvailable()))throw new Error('Riset dan jadwal memerlukan login Clerk dengan akun yang tergabung dalam organisasi.');}
|
|
async function runResearch(){
|
|
await needOrg();
|
|
const sel=pool(),urls=draft.urls.split(/\s+/).filter(Boolean);
|
|
progress('Menjalankan riset','Agen learning-lab mencari sumber untuk topik Anda.');step('Menyiapkan agen',10);
|
|
const {run,drafts}=await Engine.research({topic:draft.topic,prompt:draft.prompt,urls,docIds:sel.map(d=>d.docId)},r=>step('Agen riset · '+r.status,50));
|
|
res.research.unshift({id:'r'+run.id,runId:run.id,title:'Riset: '+(draft.topic||'umum'),topic:draft.topic,prompt:draft.prompt,urls,sources:sel.map(d=>({id:d.docId,title:d.title})),findings:drafts.map(d=>({title:d.title,url:d.source_url,preview:d.preview})),note:'Run #'+run.id+' · '+run.status+(run.source_outcome?' · '+run.source_outcome:''),createdAt:run.created_at||new Date().toISOString()});
|
|
save();tab='research';$('#modal').close();go('results');toast('Riset selesai: '+drafts.length+' temuan.');
|
|
}
|
|
async function saveSchedule(){
|
|
await needOrg();
|
|
const a=await Engine.setSchedule({enabled:draft.enabled,frequency:draft.frequency,time:draft.time,weekday:draft.weekday});
|
|
toast(draft.enabled?'Jadwal riset tersimpan'+(a.next_run_at?' · berikutnya '+new Date(a.next_run_at).toLocaleString('id-ID'):'')+'.':'Jadwal riset dinonaktifkan.');
|
|
}
|
|
function openContent(id){
|
|
const m=res.content.find(x=>x.id===id);if(!m)return;
|
|
openModal(modalHead('Pratinjau Text','Hasil engine learning-lab. Tinjau sebelum digunakan.')+'<div class="modal-body"><article class="prose"><h1>'+E(m.title)+'</h1>'+m.sections.map(s=>'<h2>'+E(s.title)+'</h2><p style="white-space:pre-wrap">'+E(s.body)+'</p>').join('')+'<p class="ref-line">Sumber: '+m.sources.map(s=>E(s.title)).join(' · ')+'</p></article></div><div class="modal-foot">'+button('Unduh TXT','download','primary','download','data-id="'+m.id+'"')+'</div>',true);
|
|
}
|
|
function openResearch(id){
|
|
const r=res.research.find(x=>x.id===id);if(!r)return;
|
|
openModal(modalHead('Hasil riset',E(r.note||''))+'<div class="modal-body"><div class="prose"><h1>'+E(r.title)+'</h1>'+(r.prompt?'<h2>Instruksi</h2><p>'+E(r.prompt)+'</p>':'')+'<h2>Sumber internal Brain</h2><ul>'+(r.sources.map(s=>'<li>'+E(s.title)+'</li>').join('')||'<li>Seluruh Brain</li>')+'</ul><h2>Temuan</h2>'+(r.findings.length?'<ul>'+r.findings.map(f=>'<li><b>'+E(f.title)+'</b>'+(f.url?' · '+E(f.url):'')+(f.preview?'<br><small>'+E(f.preview)+'</small>':'')+'</li>').join('')+'</ul>':'<p>Agen tidak menemukan sumber baru untuk topik ini.</p>')+'</div></div>',true);
|
|
}
|
|
function download(id){
|
|
const m=res.content.find(x=>x.id===id);if(!m)return;
|
|
const url=URL.createObjectURL(new Blob([m.title+'\n\n'+m.sections.map(s=>s.title+'\n'+s.body).join('\n\n')],{type:'text/plain'})),a=document.createElement('a');
|
|
a.href=url;a.download=m.title.replace(/[^\w-]+/g,'-').slice(0,60)+'.txt';a.click();URL.revokeObjectURL(url);
|
|
}
|
|
|
|
// ── auth ──
|
|
function setUser(u){user=u;if(u){render();refresh();Engine.supportedExtensions().then(x=>{exts=x;if(view==='sources')render();});}else render();}
|
|
async function signOut(){clearTimeout(pollT);await Engine.logout();org=null;docs=[];user=null;view='sources';render();}
|
|
function onClerk(){
|
|
const u=Engine.clerkUser();if(!u)return;
|
|
if(!user||user.email!==u.email)setUser({email:u.email,name:u.name});
|
|
Engine.ensureOrg().then(o=>{org=o;render();if(!o)toast('Akun Clerk ini belum tergabung dalam organisasi; riset dan jadwal belum aktif.',true);}).catch(e=>toast(e.message,true));
|
|
}
|
|
|
|
// ── events ──
|
|
document.addEventListener('click',e=>{
|
|
const nav=e.target.closest('[data-nav]');if(nav){e.preventDefault();$('#modal').open&&$('#modal').close();return go(nav.dataset.nav);}
|
|
const b=e.target.closest('[data-action]');if(!b)return;
|
|
const a=b.dataset.action,id=b.dataset.id;
|
|
if(a==='close')$('#modal').close();
|
|
else if(a==='close-brain'){$('#modal').close();go('brain');}
|
|
else if(a==='logout')signOut();
|
|
else if(a==='clerk-login')Engine.clerkSignIn();
|
|
else if(a==='toggle-password'){const i=$('#login-password');i.type=i.type==='password'?'text':'password';}
|
|
else if(a==='upload')$('#file-input').click();
|
|
else if(a==='source-delete'){const d=docs.find(x=>x.docId===Number(id));if(d&&confirm('Hapus “'+d.title+'” dari Brain?'))guarded(async()=>{await Engine.deleteDocument(d.docId);selected.delete(d.docId);await refresh();render();toast('Materi dihapus.');});}
|
|
else if(a==='run'){readForm();guarded(draft.mode==='research'?runResearch:runText);}
|
|
else if(a==='save-schedule'){readForm();guarded(saveSchedule);}
|
|
else if(a==='result-tab'){tab=b.dataset.tab;query='';render();}
|
|
else if(a==='open-content')openContent(id);
|
|
else if(a==='open-research')openResearch(id);
|
|
else if(a==='download')download(id);
|
|
});
|
|
document.addEventListener('change',e=>{
|
|
if(e.target.id==='file-input'){const f=[...e.target.files];e.target.value='';upload(f);}
|
|
else if(e.target.classList.contains('brain-source-check')){const id=Number(e.target.value);e.target.checked?selected.add(id):selected.delete(id);syncSel();}
|
|
else if(e.target.id==='brain-select-all'){selected=e.target.checked?new Set(docs.map(d=>d.docId)):new Set();document.querySelectorAll('.brain-source-check').forEach(c=>{c.checked=selected.has(Number(c.value));});syncSel();}
|
|
else if(e.target.closest('#plan-form')){readForm();$('#research-options').hidden=draft.mode==='generate';$('#schedule-fields').hidden=!draft.enabled;$('#weekday-field').hidden=draft.frequency!=='weekly';}
|
|
});
|
|
document.addEventListener('input',e=>{
|
|
if(e.target.id==='source-search'){query=e.target.value;$('#source-rows').innerHTML=rows();fillIcons($('#source-rows'));}
|
|
else if(e.target.id==='result-search'){query=e.target.value;render();$('#result-search').focus();}
|
|
});
|
|
document.addEventListener('submit',e=>{
|
|
e.preventDefault();
|
|
if(e.target.id!=='login-form')return;
|
|
$('#login-error').textContent='';
|
|
Engine.login($('#login-email').value.trim(),$('#login-password').value).then(u=>setUser({email:u.email,name:u.full_name})).catch(err=>{$('#login-error').textContent=err.message;});
|
|
});
|
|
$('#modal').addEventListener('click',e=>{if(e.target===$('#modal'))$('#modal').close();});
|
|
|
|
// ── boot ──
|
|
render();
|
|
Engine.initClerk().then(ok=>{if(!ok)return;$('#clerk-login').hidden=false;Engine.onClerkChange(onClerk);onClerk();}).catch(err=>console.warn(err.message));
|
|
if(!user&&Engine.hasSession())Engine.me().then(u=>setUser({email:u.email,name:u.full_name})).catch(()=>{});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|