/* Shared Help center + tooltip module for the Work Package Suite. Included by the home page, the suite, and the embedded creator. It injects: - tooltip styles for the .help-tip (ⓘ) component and [data-tip] hovers - a searchable, multi-topic Help center modal opened via window.openHelp() - a floating "?" launcher on any page that doesn't already have a Help button API (unchanged + extended): openHelp() open the help center openHelp('topicId') open and jump to a topic (e.g. openHelp('constraints')) closeHelp() close it Add a Help button anywhere with onclick="openHelp()". */ (function (global) { 'use strict'; // ── styles ──────────────────────────────────────────────────────────────── var css = ` .help-tip{ display:inline-flex; align-items:center; justify-content:center; width:15px; height:15px; margin-left:5px; border-radius:50%; background:#5a6675; color:#fff; font-size:10px; font-weight:700; font-family:ui-sans-serif,system-ui,sans-serif; cursor:help; vertical-align:middle; position:relative; } .help-tip::after{ content:attr(data-tip); position:absolute; bottom:130%; left:50%; transform:translateX(-50%); background:#1a2230; color:#fff; padding:7px 10px; border-radius:6px; font-size:12px; font-weight:400; line-height:1.4; white-space:normal; width:max-content; max-width:260px; text-align:left; z-index:9999; opacity:0; pointer-events:none; transition:opacity .12s; box-shadow:0 4px 14px rgba(20,30,50,.22); } .help-tip::before{ content:''; position:absolute; bottom:130%; left:50%; transform:translate(-50%,95%); border:5px solid transparent; border-top-color:#1a2230; opacity:0; transition:opacity .12s; z-index:9999; } .help-tip:hover::after, .help-tip:hover::before, .help-tip:focus::after, .help-tip:focus::before{ opacity:1; } .ui-help-overlay{ position:fixed; inset:0; background:rgba(20,30,50,.5); display:none; align-items:center; justify-content:center; z-index:10000; padding:4vh 16px; } .ui-help-overlay.open{ display:flex; } .ui-help-modal{ background:#fff; color:#1a2230; max-width:980px; width:100%; height:88vh; max-height:880px; border-radius:10px; box-shadow:0 12px 40px rgba(20,30,50,.3); display:flex; flex-direction:column; overflow:hidden; font-family:ui-sans-serif,system-ui,-apple-system,'Segoe UI',sans-serif; } .ui-help-head{ display:flex; align-items:center; gap:14px; padding:13px 18px; border-bottom:1px solid #e3e6ec; flex:none; } .ui-help-head .ui-help-title{ font-size:15px; font-weight:700; white-space:nowrap; } .ui-help-search{ flex:1; position:relative; max-width:420px; } .ui-help-search input{ width:100%; padding:8px 12px; border:1px solid #d0d5de; border-radius:7px; font-size:13px; outline:none; background:#f7f8fa; } .ui-help-search input:focus{ border-color:#2563d6; background:#fff; box-shadow:0 0 0 2px rgba(37,99,214,.15); } .ui-help-head .ui-help-x{ margin-left:auto; background:none; border:none; font-size:20px; cursor:pointer; color:#5a6675; line-height:1; } .ui-help-wrap{ display:flex; flex:1; min-height:0; } .ui-help-nav{ width:230px; flex:none; border-right:1px solid #e3e6ec; overflow:auto; padding:10px 8px; background:#fafbfc; } .ui-help-nav a{ display:block; padding:7px 10px; border-radius:6px; color:#27313f; text-decoration:none; font-size:13px; cursor:pointer; margin-bottom:1px; } .ui-help-nav a:hover{ background:#eef1f6; } .ui-help-nav a.active{ background:#e7effe; color:#1d4ed8; font-weight:600; } .ui-help-nav a.nohit{ display:none; } .ui-help-content{ flex:1; overflow:auto; padding:22px 28px; scroll-behavior:smooth; } .ui-help-sec{ margin-bottom:30px; } .ui-help-sec.hide{ display:none; } .ui-help-sec h3{ font-size:18px; margin:0 0 10px; color:#16213a; scroll-margin-top:10px; } .ui-help-sec h4{ margin:18px 0 6px; font-size:12px; text-transform:uppercase; letter-spacing:.04em; color:#2563d6; } .ui-help-content p{ font-size:13.5px; line-height:1.62; margin:0 0 9px; color:#27313f; } .ui-help-content ol, .ui-help-content ul{ margin:0 0 10px; padding-left:20px; font-size:13.5px; line-height:1.6; } .ui-help-content li{ margin-bottom:5px; } .ui-help-content code{ background:#eef1f6; padding:1px 5px; border-radius:4px; font-size:12px; } .ui-help-content table{ border-collapse:collapse; width:100%; font-size:12.5px; margin:6px 0 12px; } .ui-help-content th, .ui-help-content td{ border:1px solid #e3e6ec; padding:6px 9px; text-align:left; vertical-align:top; } .ui-help-content th{ background:#f4f6f9; font-weight:600; } .ui-help-pill{ display:inline-block; padding:1px 8px; border-radius:11px; font-size:11px; font-weight:600; } .pill-draft{ background:#eef1f6; color:#5a6675; } .pill-sched{ background:#e7effe; color:#1d4ed8; } .pill-prog{ background:#fef3e0; color:#b45309; } .pill-issued{ background:#e4f6ec; color:#15924f; } .pill-qc{ background:#f3e8ff; color:#7c3aed; } .pill-closed{ background:#e2e8f0; color:#334155; } .pill-hold{ background:#fde8e8; color:#c0392b; } .ui-help-callout{ background:#f4f8ff; border-left:3px solid #2563d6; padding:10px 14px; border-radius:0 6px 6px 0; font-size:13px; line-height:1.55; margin:10px 0; } .ui-help-noresult{ display:none; color:#5a6675; font-size:14px; padding:10px 2px; } .ui-help-content mark{ background:#fff1a8; color:inherit; border-radius:2px; padding:0 1px; } .ui-help-fab{ position:fixed; bottom:12px; left:12px; z-index:9998; width:38px; height:38px; border-radius:50%; border:none; background:#2563d6; color:#fff; font-size:18px; font-weight:700; cursor:pointer; box-shadow:0 2px 10px rgba(20,30,50,.28); } .ui-help-fab:hover{ background:#1d4ed8; } @media (max-width:760px){ .ui-help-modal{ height:92vh; } .ui-help-wrap{ flex-direction:column; } .ui-help-nav{ width:auto; display:flex; flex-wrap:wrap; gap:4px; border-right:none; border-bottom:1px solid #e3e6ec; } .ui-help-nav a{ margin:0; font-size:12px; padding:5px 9px; } .ui-help-head{ flex-wrap:wrap; } }`; var style = document.createElement('style'); style.textContent = css; (document.head || document.documentElement).appendChild(style); // ── content ───────────────────────────────────────────────────────────────── // Each topic: { id, title, body(HTML) }. Order here is the nav order. var TOPICS = [ { id: 'overview', title: 'Getting started', body: `
The Work Package Suite turns a project's standard procedure into release-ready Installation Work Packages (IWPs). You work in three stages, always in the same order:
From the home page, open SOP Configuration, the Work Package Creator, or the Dashboard. Inside the suite, switch any time using the top tabs: ⚙️ SOP Configuration, 📋 Work Package Creation, and 📊 Dashboard. The active project and SOP follow you across all of them.
A project is the top-level container — every SOP and Work Package belongs to one. Create or select projects on the home page.
The active project is the one you're currently working in. All SOP and Work Package data is scoped (namespaced) to it, so switching projects loads that project's own configuration and packages — nothing leaks between jobs. Use the change link next to the active project name to switch.
The SOP is the project baseline. Walk the 10 steps with ← Back / Next →, or jump using the step indicators. The final step is ✓ SOP Complete — saving it unlocks the Work Package Creator and turns the home-page card green.
WP##-[Sector]-[TYPE]), issuance strategy, the project's disciplines, the discipline strategy, and WP sizing (see Sizing and Disciplines).In the Creator, start a package with + New (blank, auto-numbered) or ⧉ Duplicate (copies a saved package and increments the number). The WP Number is built automatically from the SOP number format plus your scope fields, the WP type, and a counter — it's read-only.
Save Draft stores the package; ⚡ Save & View saves and renders the print-ready output. Drafts auto-save to your browser as you type, so nothing is lost if you close the tab.
` }, { id: 'statuses', title: 'Statuses', body: `| Status | Meaning |
|---|---|
| Draft | Work in progress; not yet released. |
| Scheduled | Planned and scheduled; upcoming. |
| Issued | Released to the field. Requires all constraints Cleared or N/A. |
| In Progress | Actively being worked. |
| QC | In quality check / inspection. |
| Closed | Completed. |
| Issue (Hold) | A constraint reopened after release — work is paused until it's resolved. |
On a multi-discipline package, each discipline carries its own status and the overall status rolls up to the least-advanced discipline — so a package is never "Closed" while one trade still lags.
` }, { id: 'constraints', title: 'Constraints & release', body: `Constraints are the readiness checklist that gates a package's release to the field. They follow Advanced Work Packaging (AWP Vol II §2.3.2). The standard set:
Pick which apply (and add custom ones) in SOP Step 9. Each constraint on a package has one of three states:
| State | Effect |
|---|---|
| Open | Not yet cleared — blocks release. |
| Cleared | Requirement met — counts toward release-ready. |
| N/A | Not applicable to this package — counts as cleared. |
Disciplines are trades (Mechanical, Electrical, Tech, …) set in SOP Step 5. The discipline strategy controls how packages handle them:
When a package covers 2+ disciplines, the ⎘ Split by Discipline button breaks it into one numbered instance per discipline — WP01A, WP01B, WP01C (or _MECH/_ELEC suffixes, set in the SOP). The original is kept as a master / roll-up; each instance:
In SOP Step 5 you set a typical WP size band, which sets a split threshold (max labor hours):
| Size band | Split threshold |
|---|---|
| Small — 1–2 days (≈8–24 hrs) | 24 hrs |
| Standard — 3–5 days (≈40–80 hrs) | 80 hrs |
| Large — 1–2 weeks (≈80–160 hrs) | 160 hrs |
| Custom… | you set it |
In the Creator, the Est. Hrs. field is checked live against the threshold. Within range you see the target band; over it you get an amber warning — "⚠ … exceeds the …-hr split threshold — consider breaking this package down" — and a nudge to split by discipline where that applies. It's a guide, not a hard block: you can proceed if it's intentional.
` }, { id: 'dashboard', title: 'Dashboard', body: `The dashboard aggregates every (non-master) package in the active project. Open it from the home page, the suite's 📊 Dashboard tab, or the Creator header.
Shows WP #, subject, type, discipline, status, Gates (clear, n open, or master), due date (red if overdue), and hours. Row actions: issue (when release-ready), view, and edit. Filter with the search box and the status / discipline dropdowns.
⭐ Load Sample is context-aware: on the SOP tab it loads a complete sample SOP; on the WP tab it loads an example Work Package. Great for learning the tool or demoing.
.json (via ⤒ Import SOP) or load the sample SOP.Leave feedback from the home page, per-step comments in the SOP tool (💬 Step Comments), or package comments in the Creator's 💬 Comments drawer. Comments are saved and can be exported/imported as .json so reviewers can share them — and, when the API is reachable, they're collected centrally too.
📊 Usage Logs / ▤ Usage Data shows session and event counts and can export the full log. A dev-mode toggle pauses tracking during demos.
` }, { id: 'shortcuts', title: 'Tips & shortcuts', body: `| Term | Meaning |
|---|---|
| IWP | Installation Work Package — the field-level package this tool produces. |
| AWP | Advanced Work Packaging — the methodology behind the constraint set and release gate. |
| SOP | Standard Operating Procedure — the project baseline every WP inherits. |
| Constraint | A readiness item (Open / Cleared / N/A) that gates release. |
| Release-ready | All constraints Cleared or N/A — the package can be Issued. |
| Issued | Released to the field. |
| Issue (Hold) | A released package paused because a constraint reopened. |
| Discipline | A trade (Mechanical, Electrical, Tech, …). |
| Split / Master / Instance | Breaking a multi-discipline package (master/roll-up) into single-discipline instances (WP01A/B/C). |
| Scope | The sequenced steps the crew performs. |
| Sequence | SOP-defined construction phases; a WP can name a predecessor step. |
| Bagged & tagged | Materials on site, kitted, and labelled — part of the Materials constraint. |
| MIMO | Material In / Material Out — kitting and staging logistics. |
| Asset | A controls.dev record (equipment/system) a package is built around. |
| Hold / Witness point | Hold = work stops until inspection sign-off; Witness = inspection offered but work may proceed. |
| Active project | The currently selected project; all data is scoped to it. |
The SOP for the active project isn't complete yet. Finish SOP Configuration and click ✓ SOP Complete on the last step; the Creator unlocks and the home card turns green.
At least one constraint is still Open. Clear or mark N/A every constraint — the release banner turns green — and the suite will offer to issue it.
Only material rows tagged to a discipline are routed to that instance. Untagged rows stay on the master. Tag them before splitting.
Masters are roll-ups; counting them would double-count their hours and packages. The individual instances are counted instead.
No — drafts auto-save locally per project and reload next time. Use Export (JSON) for a backup or to share with a teammate.
Yes. SOP and Work Packages are scoped to the active project; switching projects loads that project's own set.
Use the feedback / comments features (home page, SOP Step Comments, or the Creator's Comments drawer).
` } ]; // ── build ───────────────────────────────────────────────────────────────── function buildModal() { if (document.getElementById('ui-help-overlay')) return; var overlay = document.createElement('div'); overlay.className = 'ui-help-overlay'; overlay.id = 'ui-help-overlay'; var nav = TOPICS.map(function (t) { return '' + t.title + ''; }).join(''); var sections = TOPICS.map(function (t) { return 'No matches. Try another word.
' + sections + '