<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Amendment Management</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f5f6f7; color: #1a1a1a; line-height: 1.6; padding: 24px 16px 48px; font-size: 16px; } .wrap { max-width: 720px; margin: 0 auto; } /* ── Header ── */ .page-header { background: #ffffff; border-radius: 10px; padding: 28px 32px 24px; margin-bottom: 20px; border-top: 4px solid #087a6a; } .header-eyebrow { font-size: 13px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: #065a4f; margin-bottom: 8px; } .page-header h1 { font-size: 24px; font-weight: 700; color: #111; margin-bottom: 6px; } .header-sub { font-size: 15px; color: #4a4a4a; margin-bottom: 16px; } .header-note { background: #e6f5f2; border-left: 3px solid #087a6a; border-radius: 0 6px 6px 0; padding: 10px 14px; font-size: 15px; color: #1a1a1a; line-height: 1.6; } .header-note strong { color: #111; font-weight: 600; } /* ── Progress bar ── */ .progress-wrap { background: #fff; border-radius: 10px; padding: 16px 24px; margin-bottom: 20px; display: flex; align-items: center; gap: 16px; } .progress-label { font-size: 15px; font-weight: 600; color: #333; white-space: nowrap; flex-shrink: 0; } .progress-track { flex: 1; height: 8px; background: #d0d0d0; border-radius: 4px; overflow: hidden; } .progress-fill { height: 100%; background: #087a6a; border-radius: 4px; transition: width 0.35s ease; width: 0%; } .progress-count { font-size: 15px; font-weight: 700; color: #065a4f; white-space: nowrap; flex-shrink: 0; min-width: 48px; text-align: right; } /* ── Section card ── */ .section-card { background: #fff; border-radius: 10px; margin-bottom: 14px; overflow: hidden; border: 1px solid #d0d0d0; transition: border-color 0.2s; } .section-card.all-done { border-color: #087a6a; } /* Section header is a <button> for full keyboard + screen-reader support */ .section-header { display: flex; align-items: center; gap: 12px; padding: 14px 20px; cursor: pointer; width: 100%; background: transparent; border: none; border-bottom: 1px solid #ebebeb; text-align: left; transition: background 0.15s; font-family: inherit; } .section-header:hover { background: #f5fdf9; } .section-header:focus-visible { outline: 3px solid #087a6a; outline-offset: -3px; border-radius: 9px 9px 0 0; } .section-card.all-done .section-header { background: #e6f5f2; border-bottom-color: #b8e0d8; } .section-num { width: 28px; height: 28px; border-radius: 50%; background: #087a6a; color: #fff; font-size: 13px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: background 0.2s; } .section-card.all-done .section-num { background: #065a4f; } .section-title-wrap { flex: 1; } .section-title { font-size: 15px; font-weight: 700; color: #111; line-height: 1.3; } .section-subtitle { font-size: 14px; color: #555; margin-top: 1px; } .section-badge { font-size: 13px; font-weight: 600; padding: 3px 10px; border-radius: 20px; background: #e8e8e8; color: #444; flex-shrink: 0; transition: all 0.2s; } .section-card.all-done .section-badge { background: #b8e0d8; color: #065a4f; } .section-chevron { font-size: 12px; color: #666; flex-shrink: 0; transition: transform 0.2s; } .section-card.collapsed .section-chevron { transform: rotate(-90deg); } /* ── Section body ── */ .section-body { padding: 4px 0 8px; } .section-card.collapsed .section-body { display: none; } /* ── Role label ── */ .role-label { font-size: 13px; font-style: italic; color: #555; padding: 8px 20px 4px; margin: 0 8px; display: block; } /* ── Sub-section label ── */ .sub-section-label { font-size: 13px; font-weight: 700; color: #065a4f; text-transform: uppercase; letter-spacing: 0.07em; padding: 10px 20px 4px; margin: 0 8px; display: block; } /* ── Checklist items ── */ .check-item { display: flex; align-items: flex-start; gap: 12px; padding: 10px 20px; cursor: pointer; transition: background 0.12s; border-radius: 6px; margin: 0 8px; } .check-item:hover { background: #f0faf8; } .check-item:focus-visible { outline: 3px solid #087a6a; outline-offset: 1px; } .check-item.checked { opacity: 0.75; } .check-box { width: 20px; height: 20px; border: 2px solid #767676; border-radius: 4px; flex-shrink: 0; margin-top: 2px; display: flex; align-items: center; justify-content: center; transition: all 0.15s; background: #fff; } .check-item.checked .check-box { background: #087a6a; border-color: #087a6a; } .check-tick { display: none; color: #fff; font-size: 12px; font-weight: 700; line-height: 1; } .check-item.checked .check-tick { display: block; } .check-text { font-size: 15px; color: #1a1a1a; line-height: 1.6; flex: 1; } .check-item.checked .check-text { text-decoration: line-through; color: #767676; } .check-text strong { font-weight: 600; color: #111; } .check-item.checked .check-text strong { color: #767676; } /* ── Sub-items (indented) ── */ .sub-items { margin: 0 8px 2px 56px; } .sub-item { display: flex; align-items: flex-start; gap: 10px; padding: 6px 12px 6px 0; cursor: pointer; border-radius: 6px; transition: background 0.12s; } .sub-item:hover { background: #f0faf8; } .sub-item:focus-visible { outline: 3px solid #087a6a; outline-offset: 1px; } .sub-item.checked { opacity: 0.75; } .sub-box { width: 18px; height: 18px; border: 2px solid #767676; border-radius: 3px; flex-shrink: 0; margin-top: 3px; display: flex; align-items: center; justify-content: center; transition: all 0.15s; background: #fff; } .sub-item.checked .sub-box { background: #087a6a; border-color: #087a6a; } .sub-tick { display: none; color: #fff; font-size: 10px; font-weight: 700; } .sub-item.checked .sub-tick { display: block; } .sub-text { font-size: 15px; color: #1a1a1a; line-height: 1.5; flex: 1; } .sub-item.checked .sub-text { text-decoration: line-through; color: #767676; } .sub-text strong { font-weight: 600; } /* ── Completion banner ── */ .completion-banner { display: none; background: #065a4f; border-radius: 10px; padding: 20px 24px; margin-bottom: 20px; text-align: center; color: #fff; } .completion-banner.show { display: block; } .completion-banner h2 { font-size: 18px; font-weight: 700; margin-bottom: 6px; } .completion-banner p { font-size: 15px; color: rgba(255,255,255,0.9); margin-bottom: 14px; } .reset-btn { display: inline-block; padding: 8px 20px; border: 2px solid rgba(255,255,255,0.8); border-radius: 6px; color: #fff; font-size: 15px; font-weight: 600; cursor: pointer; background: transparent; transition: background 0.15s; font-family: inherit; } .reset-btn:hover { background: rgba(255,255,255,0.2); } .reset-btn:focus-visible { outline: 3px solid #fff; outline-offset: 3px; } /* ── FAQ ── */ .faq-list-wrap { padding: 4px 0 8px; } .faq-item { padding: 14px 20px; border-bottom: 1px solid #ebebeb; margin: 0 8px; } .faq-item:last-child { border-bottom: none; } .faq-q { font-size: 15px; font-weight: 700; color: #111; margin-bottom: 8px; line-height: 1.5; } .faq-a { font-size: 15px; color: #333; line-height: 1.7; } .faq-a strong { color: #111; font-weight: 600; } .faq-a em { font-style: italic; color: #555; } .faq-list { margin: 10px 0 6px 20px; display: flex; flex-direction: column; gap: 6px; } .faq-list li { font-size: 15px; color: #333; line-height: 1.6; } .faq-list-ordered { list-style: decimal; } /* ── Reduced motion ── */ @media (prefers-reduced-motion: reduce) { .progress-fill, .section-chevron, .check-box, .sub-box { transition: none; } } </style> <main> <div class="wrap"> <!-- Header --> <div class="page-header"> <p class="header-eyebrow" aria-hidden="true">Certified Workflow &middot; Verily Viewpoint Site CTMS</p> <h1>Amendment Management</h1> <p class="header-sub">Enterprise &nbsp;&middot;&nbsp; TrialPath &nbsp;&middot;&nbsp; Finance</p> <div class="header-note" role="note"> <strong>Important:</strong> Complete these steps in chronological order to avoid undesired downstream effects on site finances or study data quality. If your use case requires a different order, reach out to your CEM for guidance. </div> </div> <!-- Progress --> <div class="progress-wrap"> <p class="progress-label" id="progress-label">Overall progress</p> <div class="progress-track" role="progressbar" aria-labelledby="progress-label" aria-valuenow="0" aria-valuemin="0" aria-valuemax="17" aria-valuetext="0 of 17 steps completed" id="progress-bar"> <div class="progress-fill" id="progress-fill"></div> </div> <p class="progress-count" id="progress-count" aria-live="polite" aria-atomic="true">0 / 17</p> </div> <!-- Completion banner --> <div class="completion-banner" id="completion-banner" role="status" aria-live="polite"> <h2>&#10003; Amendment management complete</h2> <p>All steps have been checked off. Confirm participants have been migrated and reconsented as applicable.</p> <button class="reset-btn" onclick="resetAll()">Reset checklist</button> </div> <!-- ── Section 1: Enterprise ── --> <div class="section-card" id="sec-1"> <button class="section-header" onclick="toggleSection('sec-1')" aria-expanded="true" aria-controls="body-sec-1" id="hdr-sec-1"> <span class="section-num" aria-hidden="true">1</span> <span class="section-title-wrap"> <span class="section-title">Enterprise</span> <span class="section-subtitle">Upload the amendment and monitor its status</span> </span> <span class="section-badge" id="badge-sec-1" aria-hidden="true">0 / 2</span> <span class="section-chevron" aria-hidden="true">&#9660;</span> </button> <div class="section-body" id="body-sec-1" role="group" aria-labelledby="hdr-sec-1"> <span class="role-label">Site Role: Clinical Operations</span> <div class="check-item" id="c-1-1" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-1-1')" onkeydown="handleCheckKey(event,'c-1-1')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Add a new protocol request</strong> and upload the protocol as an <strong>amendment to the existing study.</strong> Include a redline or summary of changes (SOC). For more, see the <strong>Add an Amendment to an Existing Study</strong> guide.</span> </div> <div class="check-item" id="c-1-2" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-1-2')" onkeydown="handleCheckKey(event,'c-1-2')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Monitor the amendment's Status</strong> for protocol request updates. Your CEM will notify you when the study is ready for review and sign off. For more, see the <strong>Manage Protocol Requests</strong> guide.</span> </div> </div> </div> <!-- ── Section 2: TrialPath — Approve study ── --> <div class="section-card" id="sec-2"> <button class="section-header" onclick="toggleSection('sec-2')" aria-expanded="true" aria-controls="body-sec-2" id="hdr-sec-2"> <span class="section-num" aria-hidden="true">2</span> <span class="section-title-wrap"> <span class="section-title">TrialPath &mdash; Approve study</span> <span class="section-subtitle">Review, sign off, and place the study on hold</span> </span> <span class="section-badge" id="badge-sec-2" aria-hidden="true">0 / 3</span> <span class="section-chevron" aria-hidden="true">&#9660;</span> </button> <div class="section-body" id="body-sec-2" role="group" aria-labelledby="hdr-sec-2"> <span class="role-label">Site Role: Clinical Operations</span> <div class="check-item" id="c-2-1" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-2-1')" onkeydown="handleCheckKey(event,'c-2-1')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Generate a summary of changes (SOC)</strong> on the Schedule of Events (SOE) tab of the active protocol. Compare the old protocol to the new protocol amendment. For more, see the <strong>Generate a Summary of Changes</strong> guide.</span> </div> <div class="check-item" id="c-2-2" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-2-2')" onkeydown="handleCheckKey(event,'c-2-2')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Sign off</strong> &mdash; use the summary of changes and the <strong>Study Sign Off Checklist</strong> guide to review and approve the amendment. For more, see the <strong>Complete Study Sign Off</strong> guide. Reach out to your CEM with any discrepancies.</span> </div> <div class="check-item" id="c-2-3" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-2-3')" onkeydown="handleCheckKey(event,'c-2-3')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Update the site study status</strong> to <strong>On Hold</strong> until the new budget is completed. For more, see the <strong>Edit Site Study Details</strong> guide.</span> </div> </div> </div> <!-- ── Section 3: Finance — Create new budget ── --> <div class="section-card" id="sec-3"> <button class="section-header" onclick="toggleSection('sec-3')" aria-expanded="true" aria-controls="body-sec-3" id="hdr-sec-3"> <span class="section-num" aria-hidden="true">3</span> <span class="section-title-wrap"> <span class="section-title">Finance &mdash; Create new budget for amendment</span> <span class="section-subtitle">Copy previous settings, review the SOE, and finalise the budget</span> </span> <span class="section-badge" id="badge-sec-3" aria-hidden="true">0 / 5</span> <span class="section-chevron" aria-hidden="true">&#9660;</span> </button> <div class="section-body" id="body-sec-3" role="group" aria-labelledby="hdr-sec-3"> <span class="role-label">Site Role: Finance SME</span> <div class="check-item" id="c-3-1" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-3-1')" onkeydown="handleCheckKey(event,'c-3-1')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Copy protocol settings</strong> from the previous version. For more, see the <strong>Implement a New Protocol Version</strong> guide.</span> </div> <div class="check-item" id="c-3-2" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-3-2')" onkeydown="handleCheckKey(event,'c-3-2')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Create a draft budget</strong> for the new protocol version and copy the previous budget settings. Verily recommends you leave the end date of the previous budget version blank. For more, see the <strong>Create a Budget for the New Protocol</strong> guide.</span> </div> <div class="check-item" id="c-3-3" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-3-3')" onkeydown="handleCheckKey(event,'c-3-3')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Review the new protocol's Schedule of Events (SOE)</strong> and make any needed updates to the new budget.</span> </div> <div class="check-item" id="c-3-4" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-3-4')" onkeydown="handleCheckKey(event,'c-3-4')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Update the budget name</strong> from draft to final.</span> </div> <div class="check-item" id="c-3-5" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-3-5')" onkeydown="handleCheckKey(event,'c-3-5')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text">Under the study, <strong>complete any study-related activities,</strong> such as IRB amendment submission, for the new protocol amendment.</span> </div> </div> </div> <!-- ── Section 4: TrialPath — Update & migrate ── --> <div class="section-card" id="sec-4"> <button class="section-header" onclick="toggleSection('sec-4')" aria-expanded="true" aria-controls="body-sec-4" id="hdr-sec-4"> <span class="section-num" aria-hidden="true">4</span> <span class="section-title-wrap"> <span class="section-title">TrialPath &mdash; Update active enrolling version &amp; migrate participants</span> <span class="section-subtitle">Set new protocol version, update study details, and migrate active participants</span> </span> <span class="section-badge" id="badge-sec-4" aria-hidden="true">0 / 7</span> <span class="section-chevron" aria-hidden="true">&#9660;</span> </button> <div class="section-body" id="body-sec-4" role="group" aria-labelledby="hdr-sec-4"> <span class="role-label">Site Role: Clinical Operations</span> <span class="sub-section-label">Update active enrolling protocol version</span> <div class="check-item" id="c-4-1" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-4-1')" onkeydown="handleCheckKey(event,'c-4-1')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Edit protocol details</strong> &mdash; update the active enrolling version to the new protocol amendment. For more, see the <strong>Set the Active Enrolling Protocol Version</strong> guide.</span> </div> <div class="sub-items" role="group" aria-label="Protocol version sub-steps"> <div class="sub-item" id="c-4-2" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-4-2')" onkeydown="handleCheckKey(event,'c-4-2')"> <span class="sub-box" aria-hidden="true"><span class="sub-tick">&#10003;</span></span> <span class="sub-text">Change the site study status back to the appropriate active status. For more, see the <strong>Edit Site Study Details</strong> guide.</span> </div> <div class="sub-item" id="c-4-3" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-4-3')" onkeydown="handleCheckKey(event,'c-4-3')"> <span class="sub-box" aria-hidden="true"><span class="sub-tick">&#10003;</span></span> <span class="sub-text">Review and edit site study details, such as IRB dates. For more, see the <strong>Edit Site Study Details</strong> guide.</span> </div> </div> <div class="check-item" id="c-4-4" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-4-4')" onkeydown="handleCheckKey(event,'c-4-4')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Add a new consent version.</strong> Be sure to uncheck the old consent version. For more, see the <strong>Consent and Reconsent Study Participants</strong> guide.</span> </div> <span class="sub-section-label">Migrate participants</span> <div class="check-item" id="c-4-5" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-4-5')" onkeydown="handleCheckKey(event,'c-4-5')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text">Ensure <strong>ALL active participants</strong> have <strong>completed ALL prior visits</strong> on the current protocol. For more, see the <strong>Complete Visits</strong> guide.</span> </div> <div class="check-item" id="c-4-6" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-4-6')" onkeydown="handleCheckKey(event,'c-4-6')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Migrate active participants</strong> (Screening, Treatment, Follow Up) to the new protocol version. Do not migrate participants who have screen failed, completed, or are off the study. For more, see the <strong>Migrate Study Participants</strong> guide.</span> </div> <div class="check-item" id="c-4-7" role="checkbox" aria-checked="false" tabindex="0" onclick="toggle('c-4-7')" onkeydown="handleCheckKey(event,'c-4-7')"> <span class="check-box" aria-hidden="true"><span class="check-tick">&#10003;</span></span> <span class="check-text"><strong>Reconsent (if applicable)</strong> &mdash; mark participants who will require reconsent. For more, see the <strong>Reconsents</strong> guide.</span> </div> </div> </div> <!-- ── FAQ Section ── --> <div class="section-card" id="sec-faq"> <button class="section-header" onclick="toggleSection('sec-faq')" aria-expanded="true" aria-controls="body-sec-faq" id="hdr-sec-faq"> <span class="section-num" style="background:#555;" aria-hidden="true">?</span> <span class="section-title-wrap"> <span class="section-title">Frequently asked questions</span> <span class="section-subtitle">Common questions about the amendment management process</span> </span> <span class="section-chevron" aria-hidden="true">&#9660;</span> </button> <div class="section-body faq-list-wrap" id="body-sec-faq" role="region" aria-labelledby="hdr-sec-faq"> <dl> <div class="faq-item"> <dt class="faq-q">How might sites use this checklist to manage the amendment management process in Site CTMS?</dt> <dd class="faq-a">Site teams can use internal routes of communication — internal dashboards, emails, regular meetings — to circulate this checklist and divide upcoming study tasks between finance and clinical operations teams. The goal is to <strong>streamline operational actions around amendments</strong> in Site CTMS, ultimately <strong>increasing financial and clinical efficiencies</strong> at your site.</dd> </div> <div class="faq-item"> <dt class="faq-q">Do I really have to follow the checklist steps in order?</dt> <dd class="faq-a"><strong>To avoid undesired downstream effects on site finances or study data quality, we recommend following the checklist in chronological order.</strong> Examples of downstream effects that could result from completing steps out of order include: <ul class="faq-list"> <li>If you create the new budget in Finance before an amendment is approved in TrialPath, there could be digitization updates needed that could affect budget line items.</li> <li>If you migrate participants to a new amendment before the budget has been completed, not all budget customizations will be available to complete study visits and activities.</li> </ul> <em>Note: If there are use cases where the checklist cannot be followed in chronological order, reach out to your CEM for more information.</em> </dd> </div> <div class="faq-item"> <dt class="faq-q">After you approve the new amendment, why is placing the study on hold so important?</dt> <dd class="faq-a">Once a new amendment has been approved, we recommend you place the study On Hold to <strong>prevent data entry on the new version while a new budget version is being created.</strong> When you create the new budget, be sure to copy the previous budget settings over in Finance BEFORE resuming participant data entry in TrialPath so that budget customizations, such as site-specific visit activities (SSVAs), are properly recorded.</dd> </div> <div class="faq-item"> <dt class="faq-q">Do you migrate participants to the new protocol after the budget is copied/completed?</dt> <dd class="faq-a">Yes. We recommend that you create the new budget first and then migrate participants to the new amendment. <strong>Migrating participants <em>after</em> the budget is complete ensures that all budget/SOE customizations are in place</strong> in Finance before participants begin completing visits and activities in TrialPath. <ol class="faq-list faq-list-ordered"> <li>Create budget for new version</li> <li>Migrate active participants to the new version</li> </ol> </dd> </div> <div class="faq-item"> <dt class="faq-q">Should I add an end date to the previous budget or leave the end date blank?</dt> <dd class="faq-a">We recommend <strong>leaving the end date of the previous budget blank</strong> so that any remaining visits and activities from the previous protocol version can be captured accurately on the corresponding budget.</dd> </div> <div class="faq-item"> <dt class="faq-q">In the real world, budget items could be delayed. Can you copy budget settings over to the new protocol amendment before it is final?</dt> <dd class="faq-a">Yes, you can create a placeholder budget in Step 3: Create a new budget for amendment. We recommend creating a new version of the budget then updating as necessary depending on budget negotiations. Once you update the budget, the charges already in AR/AP will be automatically updated as well.<br><br><em>Note: If there are use cases where the checklist cannot be followed in chronological order, reach out to your CEM for more information.</em></dd> </div> <div class="faq-item"> <dt class="faq-q">Where can I see all amendments that have been approved for a site and whether they have an associated budget created yet?</dt> <dd class="faq-a">In Insights, go to the <strong>Finance &gt; Studies &amp; Budgets report</strong> to quickly see what status each study at your site is in (for example, On Hold, Enrolling by Invitation, etc.) and if a new budget has been associated with the study yet.</dd> </div> </dl> </div> </div> </div> </main> <script> var SECTIONS = { 'sec-1': ['c-1-1','c-1-2'], 'sec-2': ['c-2-1','c-2-2','c-2-3'], 'sec-3': ['c-3-1','c-3-2','c-3-3','c-3-4','c-3-5'], 'sec-4': ['c-4-1','c-4-2','c-4-3','c-4-4','c-4-5','c-4-6','c-4-7'] }; var ALL_IDS = Object.keys(SECTIONS).reduce(function(acc, k) { return acc.concat(SECTIONS[k]); }, []); var TOTAL = ALL_IDS.length; function toggle(id) { var el = document.getElementById(id); var isChecked = el.classList.contains('checked'); el.classList.toggle('checked'); el.setAttribute('aria-checked', isChecked ? 'false' : 'true'); updateProgress(); } function handleCheckKey(e, id) { if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); toggle(id); } } function toggleSection(secId) { var card = document.getElementById(secId); var btn = card.querySelector('.section-header'); var body = document.getElementById('body-' + secId); var isOpen = !card.classList.contains('collapsed'); card.classList.toggle('collapsed', isOpen); btn.setAttribute('aria-expanded', isOpen ? 'false' : 'true'); if (body) body.hidden = isOpen; } function countChecked(ids) { return ids.filter(function(id) { return document.getElementById(id).classList.contains('checked'); }).length; } function updateProgress() { var done = countChecked(ALL_IDS); var pct = TOTAL > 0 ? Math.round((done / TOTAL) * 100) : 0; var fill = document.getElementById('progress-fill'); var bar = document.getElementById('progress-bar'); fill.style.width = pct + '%'; bar.setAttribute('aria-valuenow', done); bar.setAttribute('aria-valuetext', done + ' of ' + TOTAL + ' steps completed'); document.getElementById('progress-count').textContent = done + ' / ' + TOTAL; Object.keys(SECTIONS).forEach(function(secId) { var ids = SECTIONS[secId]; var secDone = countChecked(ids); var secTotal = ids.length; var badge = document.getElementById('badge-' + secId); var card = document.getElementById(secId); if (badge) badge.textContent = secDone + ' / ' + secTotal; if (secDone === secTotal) { card.classList.add('all-done'); } else { card.classList.remove('all-done'); } }); var banner = document.getElementById('completion-banner'); if (done === TOTAL) { banner.classList.add('show'); banner.removeAttribute('hidden'); } else { banner.classList.remove('show'); } } function resetAll() { ALL_IDS.forEach(function(id) { var el = document.getElementById(id); el.classList.remove('checked'); el.setAttribute('aria-checked', 'false'); }); updateProgress(); } updateProgress(); </script>