Created
March 23, 2026 19:57
-
-
Save 23maverick23/942f7181f67c831b1dfeac70387c262f to your computer and use it in GitHub Desktop.
SCLS: AI & Agents Quiz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>NetSuite AI & Agentic Workflows — Training Quiz</title> | |
| <style> | |
| *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } | |
| :root { | |
| --bg: #f4f6f8; | |
| --surface: #ffffff; | |
| --surface2: #f0f3f6; | |
| --border: rgba(0,0,0,0.09); | |
| --border-hover: rgba(0,0,0,0.18); | |
| --text: #0f1923; | |
| --text-muted: #4a6070; | |
| --text-dim: #8da0b0; | |
| --teal: #0f7a5a; | |
| --teal-light: #0f7a5a; | |
| --teal-bg: #e6f5f0; | |
| --teal-border: rgba(15,122,90,0.3); | |
| --amber: #a06c00; | |
| --amber-light: #a06c00; | |
| --amber-bg: #fef8e7; | |
| --amber-border: rgba(160,108,0,0.3); | |
| --red: #b92b1a; | |
| --red-light: #b92b1a; | |
| --red-bg: #fdecea; | |
| --red-border: rgba(185,43,26,0.3); | |
| --blue: #1256a0; | |
| --blue-light: #1256a0; | |
| --blue-bg: #e8f0fb; | |
| --blue-border: rgba(18,86,160,0.3); | |
| --purple: #5b3fa0; | |
| --purple-light: #5b3fa0; | |
| --purple-bg: #f0ecfb; | |
| --purple-border: rgba(91,63,160,0.3); | |
| --radius: 10px; | |
| --radius-sm: 6px; | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; | |
| background: var(--bg); | |
| color: var(--text); | |
| min-height: 100vh; | |
| line-height: 1.6; | |
| } | |
| /* ── Layout ── */ | |
| .shell { | |
| max-width: 740px; | |
| margin: 0 auto; | |
| padding: 2rem 1.5rem 4rem; | |
| } | |
| /* ── Brand header ── */ | |
| .brand { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 2.5rem; | |
| } | |
| .brand-logo { | |
| width: 32px; | |
| height: 32px; | |
| } | |
| .brand-name { | |
| font-size: 13px; | |
| font-weight: 600; | |
| color: var(--text-muted); | |
| letter-spacing: .05em; | |
| text-transform: uppercase; | |
| } | |
| /* ── Home screen ── */ | |
| #screen-home { display: block; } | |
| #screen-quiz { display: none; } | |
| #screen-results { display: none; } | |
| #screen-cert { display: none; } | |
| .home-hero { | |
| text-align: center; | |
| padding: 1rem 0 2.5rem; | |
| } | |
| .home-hero h1 { | |
| font-size: 28px; | |
| font-weight: 700; | |
| color: var(--text); | |
| margin-bottom: .5rem; | |
| line-height: 1.25; | |
| } | |
| .home-hero p { | |
| font-size: 15px; | |
| color: var(--text-muted); | |
| margin-bottom: 2rem; | |
| } | |
| .topic-chips { | |
| display: flex; | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| gap: 8px; | |
| margin-bottom: 2.5rem; | |
| } | |
| .chip { | |
| padding: 5px 12px; | |
| border-radius: 20px; | |
| font-size: 12px; | |
| font-weight: 500; | |
| border: 1px solid; | |
| } | |
| .chip-teal { background: var(--teal-bg); border-color: var(--teal-border); color: var(--teal); } | |
| .chip-blue { background: var(--blue-bg); border-color: var(--blue-border); color: var(--blue); } | |
| .chip-amber { background: var(--amber-bg); border-color: var(--amber-border); color: var(--amber); } | |
| .chip-purple{ background: var(--purple-bg); border-color: var(--purple-border); color: var(--purple); } | |
| .name-block { | |
| max-width: 340px; | |
| margin: 0 auto 1.75rem; | |
| } | |
| .name-block label { | |
| display: block; | |
| font-size: 12px; | |
| font-weight: 500; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| letter-spacing: .08em; | |
| margin-bottom: 8px; | |
| text-align: left; | |
| } | |
| .name-block input { | |
| width: 100%; | |
| padding: 10px 14px; | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| color: var(--text); | |
| font-size: 15px; | |
| outline: none; | |
| transition: border-color .15s; | |
| } | |
| .name-block input:focus { border-color: var(--teal); } | |
| .name-block input::placeholder { color: var(--text-dim); } | |
| .btn-row { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .btn { | |
| padding: 11px 28px; | |
| border-radius: var(--radius-sm); | |
| border: 1px solid; | |
| font-size: 14px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: opacity .15s, transform .1s; | |
| min-width: 260px; | |
| text-align: center; | |
| } | |
| .btn:hover { opacity: .85; } | |
| .btn:active { transform: scale(.98); } | |
| .btn-primary { | |
| background: var(--teal); | |
| border-color: var(--teal); | |
| color: #fff; | |
| } | |
| .btn-warn { | |
| background: var(--amber-bg); | |
| border-color: var(--amber-border); | |
| color: var(--amber); | |
| } | |
| .btn-ghost { | |
| background: transparent; | |
| border-color: var(--border-hover); | |
| color: var(--text-muted); | |
| } | |
| .btn-danger { | |
| background: transparent; | |
| border-color: var(--red-border); | |
| color: var(--red-light); | |
| } | |
| .home-meta { | |
| font-size: 12px; | |
| color: var(--text-dim); | |
| text-align: center; | |
| margin-top: 1.25rem; | |
| } | |
| /* ── Quiz header ── */ | |
| .quiz-bar { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 1.5rem; | |
| } | |
| .quiz-mode-tag { | |
| font-size: 11px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: .1em; | |
| color: var(--text-muted); | |
| } | |
| .quiz-progress { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .prog-track { | |
| width: 120px; | |
| height: 3px; | |
| background: var(--border); | |
| border-radius: 2px; | |
| overflow: hidden; | |
| } | |
| .prog-fill { | |
| height: 100%; | |
| background: var(--teal); | |
| border-radius: 2px; | |
| transition: width .35s ease; | |
| } | |
| .prog-label { font-size: 12px; color: var(--text-muted); min-width: 44px; text-align: right; } | |
| .live-score { font-size: 13px; font-weight: 600; color: var(--text); min-width: 40px; text-align: right; } | |
| /* ── Retake banner ── */ | |
| .retake-banner { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| background: var(--amber-bg); | |
| border: 1px solid var(--amber-border); | |
| border-radius: var(--radius-sm); | |
| padding: 9px 14px; | |
| font-size: 13px; | |
| color: var(--amber); | |
| margin-bottom: 1rem; | |
| } | |
| .retake-banner button { | |
| background: transparent; | |
| border: none; | |
| color: var(--amber); | |
| font-size: 12px; | |
| cursor: pointer; | |
| opacity: .7; | |
| text-decoration: underline; | |
| } | |
| /* ── Question card ── */ | |
| .q-card { | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius); | |
| padding: 1.5rem 1.75rem; | |
| margin-bottom: 1rem; | |
| } | |
| .q-num { | |
| font-size: 11px; | |
| font-weight: 500; | |
| color: var(--text-dim); | |
| text-transform: uppercase; | |
| letter-spacing: .08em; | |
| margin-bottom: .5rem; | |
| } | |
| .q-topic-badge { | |
| display: inline-block; | |
| font-size: 10px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: .08em; | |
| padding: 2px 8px; | |
| border-radius: 20px; | |
| margin-bottom: .75rem; | |
| border: 1px solid; | |
| } | |
| .q-text { | |
| font-size: 17px; | |
| font-weight: 600; | |
| color: var(--text); | |
| line-height: 1.5; | |
| margin-bottom: 1.25rem; | |
| } | |
| .q-options { display: flex; flex-direction: column; gap: 8px; } | |
| .q-opt { | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 12px; | |
| padding: 12px 14px; | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| cursor: pointer; | |
| transition: border-color .12s, background .12s; | |
| background: var(--surface2); | |
| } | |
| .q-opt:hover:not(.locked) { | |
| border-color: var(--teal-border); | |
| background: var(--teal-bg); | |
| } | |
| .q-opt.sel { | |
| border-color: var(--blue); | |
| border-width: 2px; | |
| background: var(--blue-bg); | |
| } | |
| .q-opt.ok { | |
| border-color: var(--teal-border); | |
| background: var(--teal-bg); | |
| } | |
| .q-opt.bad { | |
| border-color: var(--red-border); | |
| background: var(--red-bg); | |
| } | |
| .q-opt.show-ok { | |
| border-color: var(--teal-border); | |
| background: var(--teal-bg); | |
| } | |
| .q-opt.locked { cursor: default; } | |
| .opt-letter { | |
| width: 26px; | |
| height: 26px; | |
| min-width: 26px; | |
| border-radius: 50%; | |
| background: #e8edf2; | |
| border: 1px solid rgba(0,0,0,0.15); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 11px; | |
| font-weight: 700; | |
| color: var(--text-muted); | |
| margin-top: 1px; | |
| } | |
| .q-opt.sel .opt-letter { | |
| background: var(--blue); | |
| border-color: var(--blue); | |
| color: #fff; | |
| } | |
| .q-opt.ok .opt-letter, | |
| .q-opt.show-ok .opt-letter { | |
| background: var(--teal); | |
| border-color: var(--teal); | |
| color: #fff; | |
| } | |
| .q-opt.bad .opt-letter { | |
| background: var(--red); | |
| border-color: var(--red); | |
| color: #fff; | |
| } | |
| .opt-text { font-size: 14px; color: var(--text); line-height: 1.5; } | |
| /* ── Feedback ── */ | |
| .q-feedback { | |
| margin-top: 1rem; | |
| padding: 12px 14px; | |
| border-radius: var(--radius-sm); | |
| font-size: 13px; | |
| line-height: 1.55; | |
| border: 1px solid; | |
| } | |
| .q-feedback.ok { background: var(--teal-bg); border-color: var(--teal-border); color: #0a5c42; } | |
| .q-feedback.bad { background: var(--red-bg); border-color: var(--red-border); color: #8c1a0e; } | |
| /* ── Why it matters context box ── */ | |
| .q-context { | |
| margin-top: 8px; | |
| padding: 11px 14px; | |
| border-radius: var(--radius-sm); | |
| font-size: 13px; | |
| line-height: 1.55; | |
| background: var(--blue-bg); | |
| border: 1px solid var(--blue-border); | |
| color: var(--blue); | |
| } | |
| .q-context-label { | |
| font-size: 10px; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| letter-spacing: .1em; | |
| color: var(--blue); | |
| opacity: .7; | |
| margin-bottom: 4px; | |
| } | |
| /* ── Actions ── */ | |
| .q-actions { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-top: 1rem; | |
| } | |
| .q-tally { font-size: 12px; color: var(--text-dim); } | |
| /* ── Results ── */ | |
| .results-wrap { padding: 1rem 0; } | |
| .ring-wrap { | |
| width: 120px; | |
| height: 120px; | |
| position: relative; | |
| margin: 0 auto 1.25rem; | |
| } | |
| .ring-wrap svg { transform: rotate(-90deg); } | |
| .ring-label { | |
| position: absolute; | |
| top: 50%; left: 50%; | |
| transform: translate(-50%,-50%); | |
| font-size: 26px; | |
| font-weight: 700; | |
| color: var(--text); | |
| } | |
| .result-title { | |
| font-size: 22px; | |
| font-weight: 700; | |
| text-align: center; | |
| color: var(--text); | |
| margin-bottom: .35rem; | |
| } | |
| .result-sub { | |
| font-size: 14px; | |
| color: var(--text-muted); | |
| text-align: center; | |
| margin-bottom: 1.75rem; | |
| } | |
| .stat-grid { | |
| display: grid; | |
| grid-template-columns: repeat(3, minmax(0,1fr)); | |
| gap: 10px; | |
| margin-bottom: 1.75rem; | |
| } | |
| .stat-box { | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| padding: 14px; | |
| text-align: center; | |
| } | |
| .stat-val { font-size: 22px; font-weight: 700; color: var(--text); } | |
| .stat-lbl { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .07em; margin-top: 3px; } | |
| .summary-list { margin-bottom: 1.75rem; } | |
| .sum-item { | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 10px; | |
| padding: 10px 14px; | |
| border-radius: var(--radius-sm); | |
| border: 1px solid var(--border); | |
| margin-bottom: 6px; | |
| font-size: 13px; | |
| } | |
| .sum-item.pass { border-color: var(--teal-border); background: var(--teal-bg); } | |
| .sum-item.fail { border-color: var(--red-border); background: var(--red-bg); } | |
| .sum-dot { | |
| width: 8px; height: 8px; min-width: 8px; | |
| border-radius: 50%; | |
| margin-top: 5px; | |
| } | |
| .sum-dot.pass { background: var(--teal); } | |
| .sum-dot.fail { background: var(--red); } | |
| .sum-q { font-weight: 600; color: var(--text); margin-bottom: 2px; } | |
| .sum-ans { color: var(--text-muted); font-size: 12px; } | |
| .results-btns { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; } | |
| .results-note { font-size: 12px; color: var(--text-dim); text-align: center; margin-top: 1rem; } | |
| /* ── Certificate ── */ | |
| .cert-outer { | |
| background: var(--surface); | |
| border: 1px solid var(--border-hover); | |
| border-radius: var(--radius); | |
| padding: 2.5rem 2rem 2rem; | |
| position: relative; | |
| text-align: center; | |
| margin-bottom: 1.5rem; | |
| } | |
| .cert-inner-border { | |
| position: absolute; | |
| inset: 8px; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| pointer-events: none; | |
| } | |
| .cert-icon { | |
| width: 48px; height: 48px; | |
| border-radius: 50%; | |
| background: var(--teal-bg); | |
| border: 1px solid var(--teal-border); | |
| display: flex; align-items: center; justify-content: center; | |
| margin: 0 auto 1rem; | |
| } | |
| .cert-icon svg { width: 24px; height: 24px; } | |
| .cert-eyebrow { | |
| font-size: 11px; | |
| font-weight: 600; | |
| letter-spacing: .14em; | |
| text-transform: uppercase; | |
| color: var(--text-dim); | |
| margin-bottom: .5rem; | |
| } | |
| .cert-title { | |
| font-size: 20px; | |
| font-weight: 700; | |
| color: var(--text); | |
| margin-bottom: .25rem; | |
| } | |
| .cert-subtitle { | |
| font-size: 13px; | |
| color: var(--text-muted); | |
| margin-bottom: .9rem; | |
| } | |
| .cert-presented { | |
| font-size: 12px; | |
| color: var(--text-dim); | |
| margin-bottom: .5rem; | |
| } | |
| .cert-name-line { | |
| display: inline-block; | |
| font-size: 26px; | |
| font-weight: 700; | |
| color: var(--teal); | |
| padding-bottom: .5rem; | |
| border-bottom: 1px solid var(--border-hover); | |
| margin-bottom: .9rem; | |
| min-width: 260px; | |
| } | |
| .cert-course { | |
| font-size: 14px; | |
| color: var(--text-muted); | |
| margin-bottom: 1.5rem; | |
| } | |
| .cert-stats { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| gap: 2.5rem; | |
| margin-bottom: 1.5rem; | |
| } | |
| .cert-stat-val { font-size: 22px; font-weight: 700; color: var(--text); } | |
| .cert-stat-lbl { font-size: 10px; text-transform: uppercase; letter-spacing: .1em; color: var(--text-dim); margin-top: 2px; } | |
| .cert-divider { width: 1px; height: 40px; background: var(--border-hover); } | |
| .cert-hist-title { | |
| font-size: 10px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: .1em; | |
| color: var(--text-dim); | |
| margin-bottom: .5rem; | |
| } | |
| .cert-hist-table { width: 100%; border-collapse: collapse; margin-bottom: 1.5rem; } | |
| .cert-hist-table td { | |
| padding: 6px 8px; | |
| font-size: 12px; | |
| border-bottom: 1px solid var(--border); | |
| color: var(--text-muted); | |
| } | |
| .cert-hist-table tr:last-child td { border-bottom: none; } | |
| .cert-hist-table .col-n { color: var(--text-dim); } | |
| .cert-hist-table .col-pct { font-weight: 700; } | |
| .cert-hist-table .col-mode { font-size: 11px; } | |
| .col-pass { color: var(--teal); } | |
| .col-warn { color: var(--amber); } | |
| .col-fail { color: var(--red); } | |
| .cert-seal { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 10px; | |
| margin-top: .5rem; | |
| } | |
| .seal-line { flex: 1; max-width: 80px; height: 1px; background: var(--border-hover); } | |
| .seal-txt { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); } | |
| /* ── Print ── */ | |
| @media print { | |
| body { background: #fff; color: #111; } | |
| .no-print { display: none !important; } | |
| .cert-outer { | |
| background: #fff; | |
| border: 2px solid #333; | |
| color: #111; | |
| -webkit-print-color-adjust: exact; | |
| print-color-adjust: exact; | |
| } | |
| .cert-name-line { color: #1d9e75; } | |
| .cert-title, .cert-stat-val { color: #111; } | |
| .cert-subtitle, .cert-course, .cert-presented { color: #555; } | |
| .cert-hist-table td { color: #555; border-color: #ccc; } | |
| .col-pass { color: #1d9e75; } | |
| .col-warn { color: #d4a017; } | |
| .col-fail { color: #c0392b; } | |
| .cert-icon { background: #e8f7f1; border-color: #1d9e75; } | |
| .brand, #screen-home, #screen-quiz, #screen-results { display: none !important; } | |
| #screen-cert { display: block !important; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="shell"> | |
| <!-- Brand --> | |
| <div class="brand no-print"> | |
| <svg class="brand-logo" viewBox="0 0 40 40" fill="none"> | |
| <rect width="40" height="40" rx="8" fill="#0f7a5a" opacity=".12"/> | |
| <path d="M10 20 C10 14 14 10 20 10 C26 10 30 14 30 20" stroke="#0f7a5a" stroke-width="2.5" stroke-linecap="round" fill="none"/> | |
| <path d="M10 20 C10 26 14 30 20 30 C26 30 30 26 30 20" stroke="#0f7a5a" stroke-width="2.5" stroke-linecap="round" fill="none"/> | |
| <circle cx="20" cy="20" r="3" fill="#0f7a5a"/> | |
| </svg> | |
| <span class="brand-name">Oracle NetSuite — Training Quiz</span> | |
| </div> | |
| <!-- ═══════════ HOME ═══════════ --> | |
| <div id="screen-home"> | |
| <div class="home-hero"> | |
| <h1>AI & Agentic Workflows</h1> | |
| <p>Test your knowledge from Session 1. Questions are randomized and answer choices shuffled on every attempt.</p> | |
| <div class="topic-chips"> | |
| <span class="chip chip-teal">AI Fundamentals</span> | |
| <span class="chip chip-blue">The 4-Layer Stack</span> | |
| <span class="chip chip-amber">Agentic Levels</span> | |
| <span class="chip chip-purple">MCP & SuiteAgents</span> | |
| <span class="chip chip-teal">HITL & Governance</span> | |
| <span class="chip chip-blue">Workflow Spectrum</span> | |
| </div> | |
| </div> | |
| <div class="name-block"> | |
| <label for="name-input">Your name (for certificate)</label> | |
| <input id="name-input" type="text" placeholder="Enter your name" autocomplete="off"/> | |
| </div> | |
| <div class="btn-row"> | |
| <button class="btn btn-primary" onclick="startQuiz('full')">Start full quiz</button> | |
| <button class="btn btn-warn" id="btn-retake" style="display:none" onclick="startQuiz('retake')">Retake missed questions <span id="retake-count"></span></button> | |
| <button class="btn btn-ghost" id="btn-cert-home" style="display:none" onclick="showCert()">View completion certificate</button> | |
| </div> | |
| <div class="home-meta" id="home-meta"></div> | |
| </div> | |
| <!-- ═══════════ QUIZ ═══════════ --> | |
| <div id="screen-quiz"> | |
| <div id="retake-banner" class="retake-banner" style="display:none"> | |
| <span id="retake-banner-txt"></span> | |
| <button onclick="goHome()">Exit retake</button> | |
| </div> | |
| <div class="quiz-bar"> | |
| <span class="quiz-mode-tag" id="quiz-mode-label"></span> | |
| <div class="quiz-progress"> | |
| <span class="live-score" id="live-score"></span> | |
| <div class="prog-track"><div class="prog-fill" id="prog-fill"></div></div> | |
| <span class="prog-label" id="prog-label"></span> | |
| </div> | |
| </div> | |
| <div class="q-card" id="q-card"> | |
| <div class="q-num" id="q-num"></div> | |
| <div id="q-topic-badge" class="q-topic-badge chip-teal"></div> | |
| <div class="q-text" id="q-text"></div> | |
| <div class="q-options" id="q-options"></div> | |
| <div id="q-feedback"></div> | |
| </div> | |
| <div class="q-actions"> | |
| <span class="q-tally" id="q-tally"></span> | |
| <button class="btn btn-primary" id="action-btn" onclick="handleAction()"></button> | |
| </div> | |
| </div> | |
| <!-- ═══════════ RESULTS ═══════════ --> | |
| <div id="screen-results"> | |
| <div class="results-wrap"> | |
| <div class="ring-wrap"> | |
| <svg width="120" height="120" viewBox="0 0 120 120" id="ring-svg"> | |
| <circle cx="60" cy="60" r="50" fill="none" stroke="rgba(0,0,0,0.08)" stroke-width="9"/> | |
| <circle cx="60" cy="60" r="50" fill="none" stroke="#0f7a5a" stroke-width="9" | |
| stroke-dasharray="0 314" stroke-linecap="round" id="ring-arc"/> | |
| </svg> | |
| <div class="ring-label" id="ring-pct"></div> | |
| </div> | |
| <div class="result-title" id="result-title"></div> | |
| <div class="result-sub" id="result-sub"></div> | |
| <div class="stat-grid"> | |
| <div class="stat-box"><div class="stat-val" id="stat-correct"></div><div class="stat-lbl">Correct</div></div> | |
| <div class="stat-box"><div class="stat-val" id="stat-missed"></div><div class="stat-lbl">Missed</div></div> | |
| <div class="stat-box"><div class="stat-val" id="stat-saved"></div><div class="stat-lbl">Saved for retake</div></div> | |
| </div> | |
| <div class="summary-list" id="summary-list"></div> | |
| <div class="results-btns"> | |
| <button class="btn btn-primary" onclick="showCert()">View certificate</button> | |
| <button class="btn btn-ghost" onclick="startQuiz('full')">Full quiz again</button> | |
| <button class="btn btn-warn" id="btn-res-retake" style="display:none" onclick="startQuiz('retake')">Retake missed</button> | |
| </div> | |
| <div class="results-note" id="results-note"></div> | |
| </div> | |
| </div> | |
| <!-- ═══════════ CERTIFICATE ═══════════ --> | |
| <div id="screen-cert"> | |
| <div class="cert-outer" id="cert-card"> | |
| <div class="cert-inner-border"></div> | |
| <div class="cert-icon"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="#0f7a5a" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"> | |
| <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/> | |
| </svg> | |
| </div> | |
| <div class="cert-eyebrow">Certificate of Completion</div> | |
| <div class="cert-title">NetSuite SCLS Training</div> | |
| <div class="cert-subtitle">AI & Agentic Workflows — Session 1</div> | |
| <div class="cert-presented">This certifies that</div> | |
| <div><span class="cert-name-line" id="cert-name">—</span></div> | |
| <div class="cert-course">has completed the AI & Agentic Workflows knowledge assessment</div> | |
| <div class="cert-stats"> | |
| <div> | |
| <div style="position:relative;width:80px;height:80px;margin:0 auto 4px"> | |
| <svg width="80" height="80" viewBox="0 0 80 80" id="cert-ring-svg" style="transform:rotate(-90deg)"> | |
| <circle cx="40" cy="40" r="32" fill="none" stroke="rgba(0,0,0,0.08)" stroke-width="6"/> | |
| <circle cx="40" cy="40" r="32" fill="none" stroke="#0f7a5a" stroke-width="6" | |
| stroke-dasharray="0 201" id="cert-ring-arc" stroke-linecap="round"/> | |
| </svg> | |
| <div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:16px;font-weight:700;color:var(--text)" id="cert-ring-pct"></div> | |
| </div> | |
| <div class="cert-stat-lbl">Best score</div> | |
| </div> | |
| <div class="cert-divider"></div> | |
| <div style="text-align:center"> | |
| <div class="cert-stat-val" id="cert-best-raw"></div> | |
| <div class="cert-stat-lbl">Best result</div> | |
| </div> | |
| <div class="cert-divider"></div> | |
| <div style="text-align:center"> | |
| <div class="cert-stat-val" id="cert-attempts"></div> | |
| <div class="cert-stat-lbl">Attempts</div> | |
| </div> | |
| </div> | |
| <div class="cert-hist-title">Attempt history</div> | |
| <table class="cert-hist-table" id="cert-hist-table"></table> | |
| <div class="cert-seal"> | |
| <div class="seal-line"></div> | |
| <div class="seal-txt" id="cert-issued">Issued —</div> | |
| <div class="seal-line"></div> | |
| </div> | |
| </div> | |
| <div class="btn-row no-print"> | |
| <button class="btn btn-ghost" onclick="goHome()">Back to home</button> | |
| <button class="btn btn-danger" id="btn-clear-hist" onclick="clearHistory()">Clear history</button> | |
| </div> | |
| </div> | |
| </div><!-- /shell --> | |
| <script> | |
| /* ════════════════════════════════════════════ | |
| QUESTION BANK — edit freely | |
| answer: 0-based index of correct option | |
| ════════════════════════════════════════════ */ | |
| const QUESTIONS = [ | |
| /* ── AI Fundamentals & Key Terms ── */ | |
| { | |
| id: 1, | |
| topic: "AI Fundamentals", | |
| topicClass: "chip-teal", | |
| question: "What is the key difference between deterministic and non-deterministic AI systems?", | |
| options: [ | |
| "Deterministic systems are faster; non-deterministic systems are slower", | |
| "Deterministic systems always produce the same output from the same input; non-deterministic systems may produce different outputs", | |
| "Deterministic systems use LLMs; non-deterministic systems use rule engines", | |
| "Deterministic systems require cloud infrastructure; non-deterministic systems run on-premise" | |
| ], | |
| answer: 1, | |
| explanation: "Deterministic = same input, same output, every time. Non-deterministic (LLM-based) systems are probabilistic — context-aware and flexible, but outputs may vary.", | |
| context: "This comes up constantly. Prospects ask: 'Can I trust what the AI does with my financial data?' Being able to explain that NetSuite wraps deterministic controls around probabilistic AI reasoning directly answers their governance and audit concerns." | |
| }, | |
| { | |
| id: 2, | |
| topic: "AI Fundamentals", | |
| topicClass: "chip-teal", | |
| question: "Which of the following NetSuite capabilities is an example of a deterministic system?", | |
| options: [ | |
| "Ask Oracle natural language queries", | |
| "AI-generated invoice exception summaries", | |
| "SuiteFlow approval workflow routing rules", | |
| "GenAI API text generation" | |
| ], | |
| answer: 2, | |
| explanation: "SuiteFlow routing rules are rules-based and produce the same output for the same input every time — deterministic by design. LLM-powered features like Ask Oracle and AI exception summaries are non-deterministic.", | |
| context: "Customers in regulated industries or with audit requirements will ask which parts of NetSuite AI are 'safe' to automate without review. Knowing which capabilities are deterministic vs. probabilistic lets you answer that with confidence." | |
| }, | |
| { | |
| id: 3, | |
| topic: "AI Fundamentals", | |
| topicClass: "chip-teal", | |
| question: "In the context of large language models, a 'token' is best described as:", | |
| options: [ | |
| "A security credential used to authenticate API calls", | |
| "A unit of text — roughly one word — that determines cost and response speed", | |
| "A single HTTP request sent to a model endpoint", | |
| "A compressed package of model training weights" | |
| ], | |
| answer: 1, | |
| explanation: "Tokens are the unit of measure for LLMs — roughly one word each. Every input and output is billed and timed in tokens. More tokens = higher cost and slower responses.", | |
| context: "When a technical buyer or IT leader asks about the cost model for AI features, or why a particular workflow is slower than expected, tokens are usually the answer. Understanding this lets you set realistic expectations rather than being caught off guard." | |
| }, | |
| { | |
| id: 4, | |
| topic: "AI Fundamentals", | |
| topicClass: "chip-teal", | |
| question: "What does 'inference' mean in the context of AI systems?", | |
| options: [ | |
| "Retraining the model on a customer's historical data", | |
| "A human reviewing and approving a suggested AI output", | |
| "The moment the model processes an input and generates a response", | |
| "Indexing documents into a knowledge base for future retrieval" | |
| ], | |
| answer: 2, | |
| explanation: "Inference is when the model 'thinks' — it reads input, reasons, and produces output. It happens on every single call and is the primary driver of latency, cost, and governance overhead.", | |
| context: "Prospects sometimes confuse 'training' with 'inference' and worry that NetSuite is training on their data. Being clear that inference is just the model responding — not learning from their data — addresses a very common data privacy objection." | |
| }, | |
| { | |
| id: 5, | |
| topic: "AI Fundamentals", | |
| topicClass: "chip-teal", | |
| question: "Retrieval-Augmented Generation (RAG) is primarily used to:", | |
| options: [ | |
| "Train a custom model on proprietary enterprise data", | |
| "Reduce AI hallucination by grounding responses in retrieved source data before generating", | |
| "Route agentic tasks across multiple connected systems", | |
| "Compress prompts to reduce token usage and cost" | |
| ], | |
| answer: 1, | |
| explanation: "RAG fetches relevant data from a specific source before the model generates its response. This grounds the output in real information, dramatically reducing hallucination.", | |
| context: "Hallucination is one of the top concerns prospects raise about AI in ERP. When a customer asks 'How do you make sure the AI doesn't make things up?', RAG is a core part of the answer — especially for features that draw on NetSuite knowledge bases or customer records." | |
| }, | |
| { | |
| id: 6, | |
| topic: "AI Fundamentals", | |
| topicClass: "chip-teal", | |
| question: "An AI model's 'context window' refers to:", | |
| options: [ | |
| "The UI panel where AI-generated suggestions appear to the end user", | |
| "The maximum amount of text the model can read and consider in a single response", | |
| "The timeframe during which an agent is permitted to take autonomous actions", | |
| "The approved list of tools and APIs an agent is allowed to call" | |
| ], | |
| answer: 1, | |
| explanation: "The context window is the model's working memory — everything it can see and reason on in one response. Bigger windows allow richer reasoning but cost more tokens.", | |
| context: "This matters when prospects ask why AI responses seem to 'forget' earlier parts of a long conversation, or why complex multi-step tasks require multiple calls. It's also relevant when discussing cost optimization for high-volume AI workflows." | |
| }, | |
| { | |
| id: 7, | |
| topic: "AI Fundamentals", | |
| topicClass: "chip-teal", | |
| question: "Why is structured data — like records in an ERP — particularly well-suited for AI-powered workflows?", | |
| options: [ | |
| "Cloud-hosted ERP data has lower latency than on-premise alternatives", | |
| "Structured data has defined schemas and fields, making AI outputs grounded, auditable, and traceable to source records", | |
| "AI systems cannot process unstructured data at all", | |
| "ERP vendors automatically apply compliance guardrails to all AI interactions" | |
| ], | |
| answer: 1, | |
| explanation: "Structured ERP data — rows, schemas, defined fields — gives AI a factual foundation. Outputs can be traced back to source records, making them auditable. Unstructured inputs like emails require more inference and introduce more uncertainty.", | |
| context: "This is a strong differentiator for NetSuite. When a prospect asks why AI in an ERP is more reliable than a general-purpose AI tool, the answer is grounding: the AI is working from structured, verified business data — not generating answers from scratch." | |
| }, | |
| /* ── The AI Stack ── */ | |
| { | |
| id: 8, | |
| topic: "The AI Stack", | |
| topicClass: "chip-blue", | |
| question: "In a layered AI architecture, which layer handles task execution, orchestration, and guardrails — and is where agents operate?", | |
| options: [ | |
| "The data and systems layer — where ERP and CRM records live", | |
| "The tools and APIs layer — where connectors and services are exposed", | |
| "The reasoning and models layer — where LLMs generate output", | |
| "The AI automation layer — responsible for multi-step task coordination" | |
| ], | |
| answer: 3, | |
| explanation: "The AI automation layer is where agents live. It sits above the data, tools, and model layers — using all three as building blocks to execute, orchestrate, and govern multi-step work.", | |
| context: "When a prospect asks 'Where does the AI actually live in your architecture?', walking through the layers is a credible, structured answer. It also helps position why NetSuite's ERP data foundation is an advantage — agents are only as good as the data layer beneath them." | |
| }, | |
| { | |
| id: 9, | |
| topic: "The AI Stack", | |
| topicClass: "chip-blue", | |
| question: "In an AI system architecture, 'tools and APIs' refers to:", | |
| options: [ | |
| "The databases and business systems that hold source data", | |
| "The interfaces — scripts, connectors, and services — that the AI model can call to read or act on data", | |
| "The LLMs and reasoning engines that generate responses", | |
| "The orchestration layer that sequences agentic tasks" | |
| ], | |
| answer: 1, | |
| explanation: "Tools and APIs are what the model can call — SuiteScript, connectors, MCP-exposed services. They bridge the AI's reasoning to real actions in real systems.", | |
| context: "Technical buyers will ask: 'How does the AI actually do something in NetSuite — not just answer questions?' The tools layer is the answer. This is also where the AI Connector and MCP fit in the broader picture." | |
| }, | |
| { | |
| id: 10, | |
| topic: "The AI Stack", | |
| topicClass: "chip-blue", | |
| question: "Why is the data and systems layer — ERP, CRM, HCM — considered the most important foundation for enterprise AI?", | |
| options: [ | |
| "It is the fastest layer in the stack and reduces latency", | |
| "It is the source of truth — all AI reasoning, actions, and outputs must ultimately be grounded in real business data", | |
| "It handles guardrails and ensures compliance automatically", | |
| "It provides the LLM with pre-trained knowledge about the customer's industry" | |
| ], | |
| answer: 1, | |
| explanation: "The data layer is the source of truth. An AI agent is only as reliable as the data it reads from and writes back to. Without clean, structured, trustworthy ERP data, AI outputs are ungrounded guesses.", | |
| context: "This reframes why having a single, unified ERP platform matters in an AI conversation. A prospect with fragmented data across multiple systems has a real problem — their AI has no reliable foundation. NetSuite's unified data model is a genuine AI advantage, not just a standard ERP pitch." | |
| }, | |
| /* ── MCP ── */ | |
| { | |
| id: 11, | |
| topic: "MCP", | |
| topicClass: "chip-purple", | |
| question: "What is the Model Context Protocol (MCP)?", | |
| options: [ | |
| "A proprietary NetSuite framework that replaces SuiteScript for AI-powered integrations", | |
| "An open, industry-standard interface that allows AI models to connect to external tools and services consistently", | |
| "A built-in NetSuite agent that manages multi-step finance workflows autonomously", | |
| "A compliance standard governing how AI models must handle regulated financial data" | |
| ], | |
| answer: 1, | |
| explanation: "MCP is an open, industry-standard protocol — not proprietary to any vendor — that gives AI models a consistent way to discover and call external tools and services.", | |
| context: "Customers often assume MCP is something NetSuite invented, which can trigger vendor lock-in concerns. Knowing it's an open standard you can use to reassure them: NetSuite's AI ecosystem is built on broadly-adopted infrastructure, not a proprietary walled garden." | |
| }, | |
| { | |
| id: 12, | |
| topic: "MCP", | |
| topicClass: "chip-purple", | |
| question: "Which of the following statements about MCP is FALSE?", | |
| options: [ | |
| "MCP provides a standardized way to expose tools to AI models", | |
| "MCP serves as the connectivity foundation for the NetSuite AI Connector ecosystem", | |
| "MCP is itself an autonomous agent with its own reasoning and decision-making capability", | |
| "MCP is not required in order to use AI features within NetSuite" | |
| ], | |
| answer: 2, | |
| explanation: "MCP is the plug — not the thinking. It provides the connection interface; all reasoning and decision-making happens in the model layer. MCP on its own cannot plan, decide, or act.", | |
| context: "The plug vs. thinking distinction is important when a customer conflates MCP with an agent. If someone says 'We already have MCP set up — does that mean we have agentic AI?', you need to clearly explain that the plumbing and the reasoning engine are separate things." | |
| }, | |
| { | |
| id: 13, | |
| topic: "MCP", | |
| topicClass: "chip-purple", | |
| question: "A prospect asks whether adopting NetSuite's MCP-based AI Connector ecosystem will lock them into Oracle's AI infrastructure. The best response is:", | |
| options: [ | |
| "Yes — MCP is Oracle-proprietary, so switching would require rebuilding integrations", | |
| "No — MCP is an open industry standard, so connections built on it are portable across platforms that support it", | |
| "Yes — but Oracle offers contractual protections against changes to the MCP specification", | |
| "No — but customers must sign up for Oracle Cloud to use MCP-based integrations" | |
| ], | |
| answer: 1, | |
| explanation: "MCP is an open standard, not an Oracle or NetSuite invention. Integrations built on it are not tied to a single vendor's ecosystem, which is a meaningful answer to lock-in objections.", | |
| context: "Vendor lock-in is a real concern for mid-market buyers making long-term platform decisions. Being able to confirm that NetSuite's AI integration layer is built on open standards — not proprietary protocols — is a credibility-building answer, especially with technical evaluators." | |
| }, | |
| /* ── Agentic Levels ── */ | |
| { | |
| id: 14, | |
| topic: "Agentic Levels", | |
| topicClass: "chip-amber", | |
| question: "On the AI capability maturity spectrum — from answering questions to fully coordinating multi-system workflows — where does SuiteAgents primarily operate?", | |
| options: [ | |
| "Answering — responding to questions and retrieving knowledge", | |
| "Assisting — drafting content and surfacing suggestions for human review", | |
| "Acting — using tools to write data back to systems or trigger transactions", | |
| "Coordinating — orchestrating multi-step workflows across multiple systems" | |
| ], | |
| answer: 3, | |
| explanation: "SuiteAgents operates at the Coordinating level — where an agent plans and executes multi-step workflows spanning multiple systems, not just a single action or suggestion.", | |
| context: "When a customer asks 'What can SuiteAgents actually do?', framing it on the maturity spectrum helps set the right expectations. It also helps differentiate SuiteAgents from simpler AI features — and avoids either over-promising full autonomy or underselling its capability." | |
| }, | |
| { | |
| id: 15, | |
| topic: "Agentic Levels", | |
| topicClass: "chip-amber", | |
| question: "What is the most important question to ask a customer who says 'We want agentic AI'?", | |
| options: [ | |
| "'What is your budget for AI licensing?'", | |
| "'What specific problem are you trying to solve?'", | |
| "'Do you have a dedicated AI implementation team?'", | |
| "'Have you already evaluated competing agentic platforms?'" | |
| ], | |
| answer: 1, | |
| explanation: "'Agentic AI' is a broad buzzword. The real need behind it is almost always a specific business problem — exception handling, routing, data entry reduction. Anchoring to the problem before discussing the solution avoids overpromising.", | |
| context: "This is one of the most practical skills in an AI conversation. Customers who lead with 'I want agentic AI' often mean 'I want my team to stop doing repetitive work.' Asking what problem they're solving reframes the conversation around outcomes — where NetSuite has a concrete story to tell." | |
| }, | |
| { | |
| id: 16, | |
| topic: "Agentic Levels", | |
| topicClass: "chip-amber", | |
| question: "Which analogy best describes the difference between a traditional workflow, an AI-enhanced workflow, and a fully agentic workflow?", | |
| options: [ | |
| "Walking, jogging, and running — the same path, just at different speeds", | |
| "A train on fixed tracks, a GPS navigation app, and a self-driving car", | |
| "A calculator, a spreadsheet, and a database — increasing data capacity", | |
| "Email, chat, and video — different communication channels with the same function" | |
| ], | |
| answer: 1, | |
| explanation: "Train = fixed rules, no deviation. GPS = fixed destination, adapts the route. Self-driving car = you set the goal, it handles everything. Each level adds reasoning and adaptability, not just speed.", | |
| context: "This analogy is universally understood and works for both business and technical audiences. Use it when a customer is struggling to understand why 'just adding AI to our current workflow' isn't the same as an agentic approach." | |
| }, | |
| { | |
| id: 17, | |
| topic: "Agentic Levels", | |
| topicClass: "chip-amber", | |
| question: "What is the core capability that makes an agentic workflow fundamentally different from an AI-enhanced workflow?", | |
| options: [ | |
| "Agentic workflows run faster because they skip the human review step", | |
| "Agentic workflows use more expensive AI models with larger context windows", | |
| "The agent decides what to do next at runtime, rather than following a pre-defined sequence", | |
| "Agentic workflows can only operate inside a single system, while AI workflows span multiple" | |
| ], | |
| answer: 2, | |
| explanation: "In an AI-enhanced workflow, the sequence is still pre-defined — AI handles specific steps within a fixed structure. In an agentic workflow, the agent reasons about what to do next at runtime, dynamically adapting to context.", | |
| context: "This distinction matters when customers ask 'We already use SuiteFlow with some AI steps — is that agentic?' The honest answer is no — and explaining why helps them understand the genuine value jump that SuiteAgents represents, without dismissing what they already have." | |
| }, | |
| { | |
| id: 18, | |
| topic: "Agentic Levels", | |
| topicClass: "chip-amber", | |
| question: "A company's support team currently routes incoming cases using a fixed SuiteFlow rule: 'If category = Billing, send to AR queue.' What would an AI agent do differently?", | |
| options: [ | |
| "Apply the same routing rule, but execute it in parallel across all queues simultaneously", | |
| "Ask the case submitter to re-categorize their request before routing", | |
| "Read the case content, infer urgency and context, and route based on current queue load, customer tier, and SLA — not a fixed rule", | |
| "Escalate all cases to a supervisor for manual review before routing" | |
| ], | |
| answer: 2, | |
| explanation: "A fixed rule only matches on a defined field value. An agent reads the actual case content, understands context, and makes a routing decision informed by real-time conditions — something no coded rule can replicate.", | |
| context: "Use this when a customer says 'We already have automated routing in NetSuite.' It's a concrete illustration of the gap between rule-based automation and genuine intelligence — without requiring any product-specific slide reference." | |
| }, | |
| /* ── Human-in-the-Loop (HITL) ── */ | |
| { | |
| id: 19, | |
| topic: "HITL & Governance", | |
| topicClass: "chip-teal", | |
| question: "Which of the following actions represents the highest risk category — where AI should never act without explicit human approval?", | |
| options: [ | |
| "Categorizing a vendor invoice by expense type", | |
| "Flagging a potential duplicate customer record", | |
| "Changing an employee's bank account details or overriding a GL posting", | |
| "Routing an inbound support ticket to the appropriate queue" | |
| ], | |
| answer: 2, | |
| explanation: "High-stakes, hard-to-reverse actions — employee data changes, bank details, GL overrides, compliance decisions — must always have a human in the approval chain. AI should flag and recommend, never execute alone.", | |
| context: "This is the single most important governance concept in any AI conversation with a CFO, Controller, or Head of Finance. They will ask: 'What stops the AI from doing something wrong with my books?' Being able to articulate a clear HITL framework builds trust immediately." | |
| }, | |
| { | |
| id: 20, | |
| topic: "HITL & Governance", | |
| topicClass: "chip-teal", | |
| question: "In a human-in-the-loop (HITL) framework, what does 'Suggest and Confirm' mean in practice?", | |
| options: [ | |
| "The AI executes the action immediately and sends the human a notification afterward", | |
| "The AI generates a recommendation or draft, and no action is taken until a human explicitly approves it", | |
| "Two separate humans must each confirm an action before it can execute", | |
| "The AI waits a set period of time before executing, giving humans a window to intervene" | |
| ], | |
| answer: 1, | |
| explanation: "Suggest and Confirm means the AI does the thinking — draft a reply, recommend a GL code, suggest a PO match — and a human makes the final call before anything is committed.", | |
| context: "Many customers assume AI automation means removing humans from the process. 'Suggest and Confirm' is a useful frame for showing them there's a middle ground — you get the efficiency of AI reasoning without losing the control that finance and compliance teams require." | |
| }, | |
| { | |
| id: 21, | |
| topic: "HITL & Governance", | |
| topicClass: "chip-teal", | |
| question: "Which type of task is generally safe to fully automate — allowing AI to act without human review?", | |
| options: [ | |
| "Releasing a payment batch to vendors", | |
| "Updating an employee's compensation record", | |
| "Categorizing an incoming invoice or flagging a probable duplicate record", | |
| "Granting a user a new role or permission set in the system" | |
| ], | |
| answer: 2, | |
| explanation: "Low-stakes, easily reversible, and high-volume classification tasks — like categorizing invoices or flagging duplicates — are good candidates for full automation. The cost of an error is low and the volume benefit is high.", | |
| context: "When sizing an AI implementation, customers need help distinguishing what to automate fully versus what to keep humans involved in. This framework helps them prioritize quick wins (high-volume, low-risk tasks) while protecting sensitive areas — a conversation that builds confidence in a phased approach." | |
| }, | |
| /* ── SuiteAgents & Positioning ── */ | |
| { | |
| id: 22, | |
| topic: "SuiteAgents", | |
| topicClass: "chip-purple", | |
| question: "A prospect says: 'We want agentic AI in our ERP.' What is the most effective first response?", | |
| options: [ | |
| "Immediately demo SuiteAgents to show what full agentic automation looks like", | |
| "Explain that agentic AI is not yet production-ready anywhere in the market", | |
| "Ask what specific business problem or manual process they are trying to solve", | |
| "Confirm that NetSuite has agents and schedule a technical deep-dive" | |
| ], | |
| answer: 2, | |
| explanation: "'Agentic AI' is a spectrum and a buzzword. The real business need is almost always specific — reducing manual exceptions, faster approvals, smarter routing. Anchoring to the problem first prevents overpromising and leads to a more credible conversation.", | |
| context: "This is a discipline question as much as a knowledge question. It's easy to get excited and jump to the product. But customers who feel heard — whose specific problem was understood before a solution was pitched — convert at significantly higher rates and have more realistic expectations post-implementation." | |
| }, | |
| { | |
| id: 23, | |
| topic: "SuiteAgents", | |
| topicClass: "chip-purple", | |
| question: "SuiteAgents operates within a human-in-the-loop framework. Which of the following best illustrates how this works in practice?", | |
| options: [ | |
| "The agent reads data, builds a complete action plan, and executes all steps without pause", | |
| "The agent reads data and generates insights, but a human must manually trigger every subsequent step", | |
| "The agent autonomously gathers data, synthesizes a recommendation, and then asks for confirmation before taking any irreversible action", | |
| "The agent submits a ticket to the IT team who then performs the requested action" | |
| ], | |
| answer: 2, | |
| explanation: "SuiteAgents can autonomously gather data and reason, but requests human confirmation before executing consequential actions — like sending emails or initiating transactions. Read actions are autonomous; write and send actions require a human gate.", | |
| context: "Customers worry that agentic AI will 'go rogue' — making changes they didn't approve. This pattern — autonomous for read, confirmed for write — is the concrete reassurance. It also differentiates NetSuite's approach from vendors who oversell full autonomy without addressing the governance question." | |
| }, | |
| { | |
| id: 24, | |
| topic: "SuiteAgents", | |
| topicClass: "chip-purple", | |
| question: "Within an AI agent's toolset, what is the practical difference between a 'read' tool and an 'action' tool?", | |
| options: [ | |
| "Read tools are faster; action tools require more tokens to execute", | |
| "Read tools retrieve data for the agent to reason on; action tools write data, send communications, or trigger transactions", | |
| "Read tools are available to all users; action tools require administrator permissions to configure", | |
| "Read tools work on structured data; action tools only process unstructured inputs like emails and documents" | |
| ], | |
| answer: 1, | |
| explanation: "Read tools let the agent gather information — balances, records, forecasts. Action tools change state — sending an email, updating a record, releasing a payment. The distinction is what drives where human confirmation is required.", | |
| context: "Understanding this distinction is key to designing trustworthy agentic workflows. When walking a customer through what an agent does, being explicit about which steps are read-only versus which ones change data or trigger communications gives them the control framework they need to feel comfortable approving a rollout." | |
| }, | |
| { | |
| id: 25, | |
| topic: "SuiteAgents", | |
| topicClass: "chip-purple", | |
| question: "When a customer asks 'Does NetSuite have AI agents available today?', which response best balances honesty with a strong commercial position?", | |
| options: [ | |
| "Tell them SuiteAgents is fully live and ready to deploy across all workflows immediately", | |
| "Explain that NetSuite has no agentic capabilities yet and direct them to evaluate in 12–18 months", | |
| "Acknowledge that AI-powered workflows acting on data exist today via the AI Connector, SuiteAgents is coming soon, and be upfront about where human oversight is still required", | |
| "Redirect the conversation to NetSuite's existing automation tools and avoid discussing agents" | |
| ], | |
| answer: 2, | |
| explanation: "The honest, credible answer: AI Connector enables custom agentic-style workflows today. SuiteAgents is coming. Wherever actions are taken, human-in-the-loop controls are part of the design. Don't oversell autonomy.", | |
| context: "Overpromising AI availability is one of the fastest ways to damage trust — and deals. Being accurate about what's live versus what's coming soon, while showing a clear roadmap, is consistently more effective than overstating readiness. Customers respect the honesty and remember it." | |
| }, | |
| /* ── Workflow Spectrum ── */ | |
| { | |
| id: 26, | |
| topic: "Workflow Spectrum", | |
| topicClass: "chip-blue", | |
| question: "A customer's current process uses a coded rule to classify incoming support cases: 'If subject line contains the word billing, route to AR.' What can an AI step do that this rule cannot?", | |
| options: [ | |
| "Execute the same rule faster by parallelizing the routing decision", | |
| "Read the full case content and infer the true category, urgency, and sentiment — even when the subject line is vague or missing", | |
| "Automatically close cases that match a known resolution pattern", | |
| "Assign cases to the team member with the most availability based on their calendar" | |
| ], | |
| answer: 1, | |
| explanation: "A coded rule only matches on pre-defined field values. An AI step reads the actual content and understands meaning, tone, and context — enabling accurate classification even on messy, unstructured input.", | |
| context: "This is a powerful concrete example to use with operations or support team leaders. It shows why 'we already have automated routing' is not the same as 'we have AI-powered routing' — and creates a natural opening to discuss where AI genuinely adds value beyond what rule engines can do." | |
| }, | |
| { | |
| id: 27, | |
| topic: "Workflow Spectrum", | |
| topicClass: "chip-blue", | |
| question: "When AI steps are added to an existing workflow engine like SuiteFlow, what remains unchanged compared to a fully agentic workflow?", | |
| options: [ | |
| "The AI model used to generate outputs", | |
| "The overall sequence and structure of the workflow — AI handles specific steps, but the flow itself is still pre-defined", | |
| "The human review gates, which are removed when AI is introduced", | |
| "The data sources the workflow reads from" | |
| ], | |
| answer: 1, | |
| explanation: "Adding AI to a workflow makes certain steps smarter, but the workflow itself is still pre-scripted from start to finish. An agentic workflow, by contrast, determines its own sequence at runtime based on context.", | |
| context: "This matters for customers who want to upgrade their automation maturity gradually. You can frame it as: 'What you have today is a great foundation — AI steps inside SuiteFlow give you a meaningful improvement now, and SuiteAgents gives you the next level when you're ready.' It's an honest, incremental roadmap." | |
| }, | |
| { | |
| id: 28, | |
| topic: "Workflow Spectrum", | |
| topicClass: "chip-blue", | |
| question: "Which positioning statement most accurately describes how enterprise-grade AI should handle the tension between AI flexibility and business control requirements?", | |
| options: [ | |
| "AI should replace deterministic rules entirely to unlock its full potential", | |
| "Deterministic controls should wrap probabilistic AI reasoning — keeping flexibility where it helps, and governance where it matters", | |
| "AI should only be used for reporting and insights, never for workflow automation", | |
| "All AI decisions should be fully autonomous to realize efficiency gains" | |
| ], | |
| answer: 1, | |
| explanation: "The right model is deterministic controls around probabilistic reasoning. AI provides the contextual intelligence; rules-based guardrails ensure auditability, compliance, and predictability where the business requires it.", | |
| context: "This is the most important positioning concept in the entire session. When a CFO, auditor, or risk team challenges whether AI belongs in financial workflows, this framing directly addresses their concern: the system isn't choosing between AI power and control — it's designed to have both." | |
| } | |
| ]; | |
| /* ════════════════════════════════════════════ | |
| STORAGE | |
| ════════════════════════════════════════════ */ | |
| const SK_MISSED = 'ns_quiz_missed'; | |
| const SK_HISTORY = 'ns_quiz_history'; | |
| const SK_NAME = 'ns_quiz_name'; | |
| function getMissed() { try { return JSON.parse(localStorage.getItem(SK_MISSED) || '[]'); } catch { return []; } } | |
| function getHistory() { try { return JSON.parse(localStorage.getItem(SK_HISTORY) || '[]'); } catch { return []; } } | |
| function getName() { try { return localStorage.getItem(SK_NAME) || ''; } catch { return ''; } } | |
| function saveMissed(v) { try { localStorage.setItem(SK_MISSED, JSON.stringify(v)); } catch {} } | |
| function saveHistory(v) { try { localStorage.setItem(SK_HISTORY, JSON.stringify(v)); } catch {} } | |
| function saveName(v) { try { localStorage.setItem(SK_NAME, v); } catch {} } | |
| function fmtDate(ts) { return new Date(ts).toLocaleDateString(undefined, { year:'numeric', month:'short', day:'numeric' }); } | |
| function fmtDateLong(ts) { return new Date(ts).toLocaleDateString(undefined, { year:'numeric', month:'long', day:'numeric' }); } | |
| /* ════════════════════════════════════════════ | |
| UTILS | |
| ════════════════════════════════════════════ */ | |
| function shuffle(arr) { | |
| const a = [...arr]; | |
| for (let i = a.length - 1; i > 0; i--) { | |
| const j = Math.floor(Math.random() * (i + 1)); | |
| [a[i], a[j]] = [a[j], a[i]]; | |
| } | |
| return a; | |
| } | |
| function shuffleOptions(q) { | |
| const indexed = q.options.map((o, i) => ({ text: o, orig: i })); | |
| const shuf = shuffle(indexed); | |
| return { ...q, options: shuf.map(o => o.text), answer: shuf.findIndex(o => o.orig === q.answer) }; | |
| } | |
| function buildSession(mode) { | |
| let pool; | |
| if (mode === 'retake') { | |
| const missed = getMissed(); | |
| pool = QUESTIONS.filter(q => missed.includes(q.id)); | |
| if (!pool.length) pool = QUESTIONS.slice(); | |
| } else { | |
| pool = QUESTIONS.slice(); | |
| } | |
| return shuffle(pool).map(q => shuffleOptions(q)); | |
| } | |
| /* ════════════════════════════════════════════ | |
| STATE | |
| ════════════════════════════════════════════ */ | |
| let S = { | |
| mode: 'full', | |
| questions: [], | |
| current: 0, | |
| selected: null, | |
| submitted: false, | |
| answers: [], | |
| screen: 'home' | |
| }; | |
| const LETTERS = ['A','B','C','D']; | |
| /* ════════════════════════════════════════════ | |
| SCREEN HELPERS | |
| ════════════════════════════════════════════ */ | |
| function showScreen(id) { | |
| ['home','quiz','results','cert'].forEach(s => { | |
| document.getElementById('screen-' + s).style.display = (s === id) ? 'block' : 'none'; | |
| }); | |
| S.screen = id; | |
| } | |
| /* ════════════════════════════════════════════ | |
| HOME | |
| ════════════════════════════════════════════ */ | |
| function initHome() { | |
| const nameEl = document.getElementById('name-input'); | |
| nameEl.value = getName(); | |
| nameEl.addEventListener('input', () => saveName(nameEl.value.trim())); | |
| const missed = getMissed(); | |
| const history = getHistory(); | |
| const btnRetake = document.getElementById('btn-retake'); | |
| const btnCert = document.getElementById('btn-cert-home'); | |
| const homeMeta = document.getElementById('home-meta'); | |
| if (missed.length > 0) { | |
| btnRetake.style.display = ''; | |
| document.getElementById('retake-count').textContent = '(' + missed.length + ')'; | |
| } else { | |
| btnRetake.style.display = 'none'; | |
| } | |
| if (history.length > 0) { | |
| btnCert.style.display = ''; | |
| homeMeta.textContent = history.length + ' attempt' + (history.length !== 1 ? 's' : '') + ' on record'; | |
| } else { | |
| btnCert.style.display = 'none'; | |
| homeMeta.textContent = QUESTIONS.length + ' questions across 6 topic areas'; | |
| } | |
| showScreen('home'); | |
| } | |
| function goHome() { initHome(); } | |
| /* ════════════════════════════════════════════ | |
| QUIZ | |
| ════════════════════════════════════════════ */ | |
| function startQuiz(mode) { | |
| S = { | |
| mode, | |
| questions: buildSession(mode), | |
| current: 0, | |
| selected: null, | |
| submitted: false, | |
| answers: [], | |
| screen: 'quiz' | |
| }; | |
| renderQuestion(); | |
| showScreen('quiz'); | |
| } | |
| function renderQuestion() { | |
| const q = S.questions[S.current]; | |
| const total = S.questions.length; | |
| const answered = S.answers.length; | |
| const correct = S.answers.filter(a => a.correct).length; | |
| const pct = total > 0 ? Math.round((answered / total) * 100) : 0; | |
| // Mode label & retake banner | |
| document.getElementById('quiz-mode-label').textContent = S.mode === 'retake' ? 'Retake mode' : 'Full quiz'; | |
| const banner = document.getElementById('retake-banner'); | |
| if (S.mode === 'retake') { | |
| banner.style.display = 'flex'; | |
| document.getElementById('retake-banner-txt').textContent = | |
| 'Retake — ' + total + ' missed question' + (total !== 1 ? 's' : '') + ' from your last session'; | |
| } else { | |
| banner.style.display = 'none'; | |
| } | |
| // Progress | |
| document.getElementById('prog-fill').style.width = pct + '%'; | |
| document.getElementById('prog-label').textContent = (S.current + 1) + ' / ' + total; | |
| document.getElementById('live-score').textContent = answered > 0 ? Math.round((correct / answered) * 100) + '%' : ''; | |
| document.getElementById('q-tally').textContent = answered + ' answered' + (answered > 0 ? ' · ' + correct + ' correct' : ''); | |
| // Question content | |
| document.getElementById('q-num').textContent = 'Question ' + (S.current + 1); | |
| document.getElementById('q-text').textContent = q.question; | |
| const badge = document.getElementById('q-topic-badge'); | |
| badge.textContent = q.topic; | |
| badge.className = 'q-topic-badge chip ' + q.topicClass; | |
| // Options | |
| const optWrap = document.getElementById('q-options'); | |
| optWrap.innerHTML = ''; | |
| q.options.forEach((opt, i) => { | |
| const div = document.createElement('div'); | |
| let cls = 'q-opt'; | |
| if (S.submitted) { | |
| cls += ' locked'; | |
| if (i === q.answer) cls += ' show-ok'; | |
| else if (i === S.selected) cls += ' bad'; | |
| } else if (i === S.selected) { | |
| cls += ' sel'; | |
| } | |
| div.className = cls; | |
| div.innerHTML = '<div class="opt-letter">' + LETTERS[i] + '</div><span class="opt-text">' + opt + '</span>'; | |
| if (!S.submitted) { | |
| div.addEventListener('click', () => { S.selected = i; renderQuestion(); }); | |
| } | |
| optWrap.appendChild(div); | |
| }); | |
| // Feedback | |
| const fb = document.getElementById('q-feedback'); | |
| if (S.submitted) { | |
| const isOk = S.selected === q.answer; | |
| fb.className = 'q-feedback ' + (isOk ? 'ok' : 'bad'); | |
| fb.innerHTML = '<strong>' + (isOk ? 'Correct — ' : 'Incorrect — ') + '</strong>' + q.explanation; | |
| if (q.context) { | |
| const ctx = document.createElement('div'); | |
| ctx.className = 'q-context'; | |
| ctx.innerHTML = '<div class="q-context-label">Why this matters in a customer conversation</div>' + q.context; | |
| fb.insertAdjacentElement('afterend', ctx); | |
| } | |
| } else { | |
| fb.className = ''; | |
| fb.innerHTML = ''; | |
| const existing = document.getElementById('q-card').querySelector('.q-context'); | |
| if (existing) existing.remove(); | |
| } | |
| // Action button | |
| const btn = document.getElementById('action-btn'); | |
| if (!S.submitted) { | |
| btn.textContent = 'Check answer'; | |
| btn.disabled = (S.selected === null); | |
| } else { | |
| const isLast = (S.current + 1 >= total); | |
| btn.textContent = isLast ? 'See results' : 'Next question'; | |
| btn.disabled = false; | |
| } | |
| } | |
| function handleAction() { | |
| if (!S.submitted) { | |
| if (S.selected === null) return; | |
| const q = S.questions[S.current]; | |
| const correct = (S.selected === q.answer); | |
| S.submitted = true; | |
| S.answers.push({ qid: q.id, selected: S.selected, correct }); | |
| renderQuestion(); | |
| } else { | |
| if (S.current + 1 >= S.questions.length) { | |
| finishQuiz(); | |
| } else { | |
| S.current++; | |
| S.selected = null; | |
| S.submitted = false; | |
| renderQuestion(); | |
| } | |
| } | |
| } | |
| /* ════════════════════════════════════════════ | |
| FINISH | |
| ════════════════════════════════════════════ */ | |
| function finishQuiz() { | |
| updateMissed(); | |
| recordAttempt(); | |
| renderResults(); | |
| showScreen('results'); | |
| } | |
| function updateMissed() { | |
| const nowMissed = S.answers.filter(a => !a.correct).map(a => a.qid); | |
| if (S.mode === 'full') { | |
| saveMissed(nowMissed); | |
| } else { | |
| const prev = getMissed(); | |
| const fixed = S.answers.filter(a => a.correct).map(a => a.qid); | |
| const remaining = prev.filter(id => !fixed.includes(id)); | |
| saveMissed([...new Set([...remaining, ...nowMissed])]); | |
| } | |
| } | |
| function recordAttempt() { | |
| const total = S.questions.length; | |
| const correct = S.answers.filter(a => a.correct).length; | |
| const pct = Math.round((correct / total) * 100); | |
| const hist = getHistory(); | |
| hist.push({ ts: Date.now(), mode: S.mode, correct, total, pct, name: getName() }); | |
| saveHistory(hist); | |
| } | |
| /* ════════════════════════════════════════════ | |
| RESULTS SCREEN | |
| ════════════════════════════════════════════ */ | |
| function renderResults() { | |
| const total = S.questions.length; | |
| const correct = S.answers.filter(a => a.correct).length; | |
| const pct = Math.round((correct / total) * 100); | |
| const missed = getMissed(); | |
| // Ring | |
| const r = 50, circ = 2 * Math.PI * r; | |
| const dash = (pct / 100) * circ; | |
| const arc = document.getElementById('ring-arc'); | |
| const strokeColor = pct >= 80 ? '#0f7a5a' : pct >= 60 ? '#a06c00' : '#b92b1a'; | |
| arc.setAttribute('stroke', strokeColor); | |
| arc.setAttribute('stroke-dasharray', dash.toFixed(1) + ' ' + circ.toFixed(1)); | |
| document.getElementById('ring-pct').textContent = pct + '%'; | |
| const grade = pct >= 80 ? 'Strong result' : pct >= 60 ? 'Good effort' : 'Keep practicing'; | |
| document.getElementById('result-title').textContent = grade; | |
| document.getElementById('result-sub').textContent = | |
| correct + ' of ' + total + ' correct — ' + (S.mode === 'retake' ? 'retake session' : 'full quiz'); | |
| document.getElementById('stat-correct').textContent = correct; | |
| document.getElementById('stat-missed').textContent = total - correct; | |
| document.getElementById('stat-saved').textContent = missed.length; | |
| // Summary | |
| const sumWrap = document.getElementById('summary-list'); | |
| sumWrap.innerHTML = ''; | |
| S.answers.forEach((a, idx) => { | |
| const q = S.questions.find(q => q.id === a.qid); | |
| const div = document.createElement('div'); | |
| div.className = 'sum-item ' + (a.correct ? 'pass' : 'fail'); | |
| div.innerHTML = | |
| '<div class="sum-dot ' + (a.correct ? 'pass' : 'fail') + '"></div>' + | |
| '<div><div class="sum-q">Q' + (idx + 1) + ': ' + q.question + '</div>' + | |
| (!a.correct ? '<div class="sum-ans">Correct answer: ' + q.options[q.answer] + '</div>' : '') + | |
| '</div>'; | |
| sumWrap.appendChild(div); | |
| }); | |
| // Buttons | |
| const btnRetake = document.getElementById('btn-res-retake'); | |
| btnRetake.style.display = missed.length > 0 ? '' : 'none'; | |
| if (missed.length > 0) btnRetake.textContent = 'Retake missed (' + missed.length + ')'; | |
| document.getElementById('results-note').textContent = | |
| missed.length === 0 | |
| ? 'No missed questions — perfect run!' | |
| : missed.length + ' question' + (missed.length !== 1 ? 's' : '') + ' saved to browser for your next retake'; | |
| } | |
| /* ════════════════════════════════════════════ | |
| CERTIFICATE | |
| ════════════════════════════════════════════ */ | |
| function showCert() { | |
| const history = getHistory(); | |
| if (!history.length) { goHome(); return; } | |
| const name = getName() || 'Participant'; | |
| const best = history.reduce((b, h) => h.pct > b.pct ? h : b, history[0]); | |
| const latest = history[history.length - 1]; | |
| const total = history.length; | |
| document.getElementById('cert-name').textContent = name; | |
| document.getElementById('cert-attempts').textContent = total; | |
| document.getElementById('cert-best-raw').textContent = best.correct + '/' + best.total; | |
| document.getElementById('cert-issued').textContent = 'Issued ' + fmtDateLong(latest.ts); | |
| // Mini ring | |
| const r = 32, circ = 2 * Math.PI * r; | |
| const dash = (best.pct / 100) * circ; | |
| const arc = document.getElementById('cert-ring-arc'); | |
| const col = best.pct >= 80 ? '#0f7a5a' : best.pct >= 60 ? '#a06c00' : '#b92b1a'; | |
| arc.setAttribute('stroke', col); | |
| arc.setAttribute('stroke-dasharray', dash.toFixed(1) + ' ' + circ.toFixed(1)); | |
| document.getElementById('cert-ring-pct').textContent = best.pct + '%'; | |
| // History table | |
| const tbl = document.getElementById('cert-hist-table'); | |
| tbl.innerHTML = ''; | |
| history.forEach((h, i) => { | |
| const cls = h.pct >= 80 ? 'col-pass' : h.pct >= 60 ? 'col-warn' : 'col-fail'; | |
| const tr = document.createElement('tr'); | |
| tr.innerHTML = | |
| '<td class="col-n" style="text-align:left;color:var(--text-dim)">Attempt ' + (i + 1) + '</td>' + | |
| '<td>' + fmtDate(h.ts) + '</td>' + | |
| '<td class="col-pct ' + cls + '">' + h.pct + '%</td>' + | |
| '<td>' + h.correct + '/' + h.total + '</td>' + | |
| '<td class="col-mode" style="color:var(--text-dim)">' + h.mode + '</td>'; | |
| tbl.appendChild(tr); | |
| }); | |
| showScreen('cert'); | |
| } | |
| function clearHistory() { | |
| if (!confirm('Clear all attempt history and missed questions?')) return; | |
| try { localStorage.removeItem(SK_MISSED); localStorage.removeItem(SK_HISTORY); } catch {} | |
| goHome(); | |
| } | |
| /* ════════════════════════════════════════════ | |
| INIT | |
| ════════════════════════════════════════════ */ | |
| initHome(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment